If I have correctly understood your question, how do you do the calculations using your own HTransform
class instead of using the classical classic OpenGL functions gltranslatef()
, glRotatef()
, glScalef()
, and so on.
So, basically, so you can move, resize and rotate an object using your array, before you must load it into OpenGL. For this you use:
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(matrix);
Where matrix
is a pointer to an array of type GLfloat
4x4, containing already calculated values.
Example for Classic OpenGL
Using glfw , to create the OpenGL context, and glm , to perform the calculations of the matrices (which in your case is HTransform
).
Considering the class Quad
that simply serves to draw a square (or the object in question):
#ifndef QUAD_DEFINED_HPP
#define QUAD_DEFINED_HPP
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
// Classe do Objeto
class Quad
{
public:
// Construtor
Quad(float w = 30.0f, float h = 30.0f) : m_width(w), m_height(h)
{
// carrega com matriz identidade.
m_model = glm::mat4(1);
// Define a cor padrão para vermelho.
m_cores[0] = 1.0f; // [1] e [2] são zero.
}
// Move o objeto para x e y
void moverPara(float x, float y)
{
m_model = glm::translate(m_model, glm::vec3(x, y, 0.0f));
}
// translada em relação ao eixo local
void transladar(float x, float y)
{
m_model += glm::translate(m_model, glm::vec3(x, y, 0.0f));
}
// modifica a escala
void setEscala(float x, float y)
{
m_model = glm::scale(m_model, glm::vec3(x, y, 1.0f));
}
// rotaciona
void rotacionar(float angulo)
{
m_model = m_model * glm::rotate(angulo, glm::vec3(0.0f, 0.0f, 1.0f));
}
// modifica a cor do quadrado
void setCor(int r, int g, int b)
{
m_cores[0] = static_cast<float>(r) / 255.0f;
m_cores[1] = static_cast<float>(g) / 255.0f;
m_cores[2] = static_cast<float>(b) / 255.0f;
}
void desenhar(void)
{
glPushMatrix();
// define a cor do quadrado
glColor3fv(m_cores);
glMatrixMode(GL_MODELVIEW);
const GLfloat* matrix = reinterpret_cast<const GLfloat*>(&m_model);
glLoadMatrixf(matrix);
// Desenha os vértices do quadrado
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, m_height, 0.0f);
glVertex3f(m_width, 0.0f, 0.0f);
glVertex3f(m_width, m_height, 0.0f);
glVertex3f(m_width, 0.0f, 0.0f);
glVertex3f(0.0f, m_height, 0.0f);
glEnd();
glPopMatrix();
}
private:
// largura
float m_width;
// altura
float m_height;
// matriz
glm::mat4 m_model;
float m_cores[3];
};
#endif
And to create the window and etc:
#include <GLFW/glfw3.h>
#include "quad.hpp"
// Ajusta a tela para desenhar de forma ortogonal (2D).
void telaOrtogonal();
// Ponteiro para a janela atual.
GLFWwindow* window;
int main(void)
{
// Inicializa a glfw.
if (!glfwInit())
{
// falhou
return -1;
}
// Cria uma janela com um contexto de opengl
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
// falhou ao criar a janela
glfwTerminate();
return -1;
}
// Define a janela criada como o contexto atual.
// Isso é usado para casos em que há vários
// contextos opengl em um mesmo programa.
glfwMakeContextCurrent(window);
// O objeto que será desenhado.
Quad quad1;
quad1.moverPara(20, 20);
quad1.setEscala(2.0f, 2.0f);
Quad quad2;
quad2.setCor(0, 0, 255);
quad2.moverPara(100, 80);
quad2.transladar(0, 20);
quad2.rotacionar(45);
// Loop principal, rodado até que o usuário feche a janale.
while (!glfwWindowShouldClose(window))
{
// Ajusta para tela ortogonal (2D).
telaOrtogonal();
// Desenha os quadrados
quad2.desenhar();
quad1.desenhar();
// Atualiza os buffers
glfwSwapBuffers(window);
// Processa os eventos (mouse, teclado, sistema e etc).
glfwPollEvents();
}
// Finaliza a glfw.
glfwTerminate();
return 0;
}
void telaOrtogonal()
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
}
Note that arrays are only updated in calls:
Quad quad1;
quad1.moverPara(20, 20);
quad1.setEscala(2.0f, 2.0f);
Quad quad2;
quad2.setCor(0, 0, 255);
quad2.moverPara(100, 80);
quad2.transladar(0, 20);
quad2.rotacionar(45);
The result is this:
Being the white balls you add later to indicate the local axis of the object.
To know how the translate
, scale
, rotate
functions have been implemented you can see the glm
source code, it's pure math. But I strongly recommend that you consider using a specialized library for array calculations (or at least see the source code) because they are generally well optimized, tested, and most use SSE, SSE2, SSE3 (etc) type optimizations in calculations of the matrices.
If it is also possible instead of using OpenGL 1.3, you might consider using OpenGL 3.3+, as OpenGL 3 made several classic OpenGL functions obsolete.