If I understand your question correctly, how do you already perform the calculations using your own class HTransform
instead of using classic Opengl functions gltranslatef()
, glRotatef()
, glScalef()
and etc.
So basically, in order for you to move, resize, and rotate an object using your matrix, you must first load it into Opengl. For this you use:
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(matrix);
Where matrix
is a pointer to a type matrix GLfloat
4x4, containing the values already calculated.
Example for Classic Opengl
Using glfw, to create the Opengl context, and glm, to perform the matrix calculations (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 matrices 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:
White balls being added later to indicate the local axis of the object.
To learn how the functions of translate
, scale
, rotate
have been implemented you can see the source code of the glm
, is pure mathematics. But, I strongly recommend that you consider using a specialized library for matrix calculations (or at least see the source code) because they are generally well optimized, tested and most use optimizations of type SSE, SSE2, SSE3 (etc) in matrix calculations.
If it is also possible instead of using Opengl 1.3, you might consider using Opengl 3.3+, as Opengl 3 has rendered several classic Opengl functions obsolete.
Which version of Opengl?
– Lucas Lima
It has to be for Opengl 1.3
– Walberti Evaristo
I strongly recommend the library
glm
: http://glm.g-truc.net/0.9.5/index.html– Lucas Lima
For 1.3, I think the
glm
shouldn’t be much use.– Lucas Lima
So, until a while ago, I tried to use the glm. But I had difficulty rotating the objects with glm. I found it a little complicated.
– Walberti Evaristo
But anyway, I’d like to learn how to do this using my own matrices. I’ve done a lot of research but I can’t find an answer.
– Walberti Evaristo
But you how to do with GLM?
– Walberti Evaristo