Related
I would like to render a cube map layout (orthographic projection) - something like this. Let's focus on the +X face (right on the picture). The code which renders +X face looks this way:
glBegin(GL_QUADS);
glTexCoord3f(1, 1, -1);
glVertex2i(0,0);
glTexCoord3f(1, 1, 1);
glVertex2i(256,0);
glTexCoord3f(1, -1, 1);
glVertex2i(256, 256);
glTexCoord3f(1, -1, -1);
glVertex2i(0, 256);
glEnd();
It looks like that glTexCoord3f uses ndc values, but I don't understand why y value is positive for the first two vertices and negative for the next, from my understanding it should be opposite ( I imagine that I observe cube faces from the cube center).
No glTexCoord3D does not use NDC !!! its a direction vector instead.
I was struggling in the past with the same ... GL_TEXTURE_CUBE_MAP are hard to start with ...
To make things easier here is mine render in old API (C++ member from mine engine) for those:
void OpenGL_TXR::cube_draw_CW(double size,int unit)
{
int i,j;
double a=size;
double pnt[8][3]=
{
+a,-a,+a,
+a,+a,+a,
-a,+a,+a,
-a,-a,+a,
+a,-a,-a,
+a,+a,-a,
-a,+a,-a,
-a,-a,-a
};
int tab[24]=
{
0,1,2,3,
7,6,5,4,
4,5,1,0,
5,6,2,1,
6,7,3,2,
7,4,0,3
};
glColor3f(1,1,1);
glBegin(GL_QUADS);
for (i=23;i>=0;i--)
{
j=tab[i];
glMultiTexCoord3dv(GL_TEXTURE0+unit,pnt[j]);
glVertex3dv(pnt[j]);
}
glEnd();
}
size is the cube half size and unit is texture unit where is your cube map binded.
But it renders a textured cube. If you want to render your layout then just use different vertexes but the same texture coords. Something like this:
void cube_draw2D_CW(double size,int unit)
{
int i,j;
// U
// W N E S
// D
const double a=size,a0=-3.0*a,a1=a0+a+a,a2=a1+a+a,a3=a2+a+a;
const double b=1.7320508075688772935274463415059; // sqrt(3.0)
double pnttxr[8][3]=
{
+b,-b,+b,
+b,+b,+b,
-b,+b,+b,
-b,-b,+b,
+b,-b,-b,
+b,+b,-b,
-b,+b,-b,
-b,-b,-b
};
double pntver[24][3]=
{
a1+a,a0+a-a,+0.0,
a1+a,a0+a+a,+0.0,
a1-a,a0+a+a,+0.0,
a1-a,a0+a-a,+0.0,
a1+a,a2+a-a,+0.0,
a1+a,a2+a+a,+0.0,
a1-a,a2+a+a,+0.0,
a1-a,a2+a-a,+0.0,
a0+a,a1+a-a,+0.0,
a0+a,a1+a+a,+0.0,
a0-a,a1+a+a,+0.0,
a0-a,a1+a-a,+0.0,
a1+a,a1+a-a,+0.0,
a1+a,a1+a+a,+0.0,
a1-a,a1+a+a,+0.0,
a1-a,a1+a-a,+0.0,
a2+a,a1+a-a,+0.0,
a2+a,a1+a+a,+0.0,
a2-a,a1+a+a,+0.0,
a2-a,a1+a-a,+0.0,
a3+a,a1+a-a,+0.0,
a3+a,a1+a+a,+0.0,
a3-a,a1+a+a,+0.0,
a3-a,a1+a-a,+0.0,
};
int tabtxr[24]=
{
4,0,3,7, // D
1,5,6,2, // U
3,2,6,7, // W
0,1,2,3, // N
4,5,1,0, // E
7,6,5,4, // S
};
int tabver[24]=
{
0,1,2,3,
4,5,6,7,
8,9,10,11,
12,13,14,15,
16,17,18,19,
20,21,22,23,
};
glColor3f(1,1,1);
glBegin(GL_QUADS);
for (i=23;i>=0;i--)
{
j=tabtxr[i];
glMultiTexCoord3dv(GL_TEXTURE0+unit,pnttxr[j]);
j=tabver[i];
glVertex3dv(pntver[j]);
}
glEnd();
}
Here preview:
I created Lines and when I'm rotate the line. Line will be stretch. How can I stop stretch at rotation time. When I change height in Ortho it will be not displaying properly. When Line is going left or right it will be start strtching but when it will be reach in main point it will come in real position.
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<glut.h>
using namespace std;
float yr = 0;
void introscreen();
void screen();
void screen1();
void PitchLadder();
int width = 1268;
int height = 720;
float translate = 0.0f;
GLfloat angle = 0.0f;
void display(void) {
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-300, 300, -10, 25, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
static int center_x = 0;
static int center_y = 0;
}
void specialKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_UP:
translate += 1.0f;
break;
case GLUT_KEY_DOWN:
translate -= 1.0f;
break;
case GLUT_KEY_LEFT:
angle += 1.0f;
break;
case GLUT_KEY_RIGHT:
angle -= 1.0f;
break;
}
glutPostRedisplay();
}
void Rolling(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 1, 0);
glPushMatrix();
glRotatef(-angle, 0, 0, 1);
glTranslatef(-10, translate,0);
PitchLadder();
glPopMatrix();
glFlush();
}
void PitchLadder() {
GLfloat y;
GLfloat y2;
GLfloat fSize[5];
GLfloat fCurrSize;
fCurrSize = fSize[2];
for (y2 = -90.0f ; y2 <= 90.0f ; y2 += 10.0f) {
glLineWidth(fCurrSize);
glBegin(GL_LINES);
glVertex3f(-50.0f , y2 , 0);
glVertex3f(50.0f , y2 , 0);
glEnd();
fCurrSize += 1.0f;
screen();
screen1();
}
}
void renderbitmap1(float x3, float y3, void *font1, char *string1) {
char *c1;
glRasterPos2f(x3, y3);
for (c1=string1; *c1 != '\0'; c1++) {
glutBitmapCharacter(font1, *c1);
}
}
void screen(void) {
glColor3f(0, 1, 0);
char buf1[20] = { '\0' };
for (int row1 = -90.0f; row1 <= 90 + yr; row1 +=10.0f) {
sprintf_s(buf1,"%i", row1);
renderbitmap1(70 , (yr+row1), GLUT_BITMAP_TIMES_ROMAN_24, buf1);
}
}
void renderbitmap2(float x4, float y4, void *font2, char *string2) {
char *c1;
glRasterPos2f(x4, y4);
for (c1=string2; *c1 != '\0'; c1++) {
glutBitmapCharacter(font2, *c1);
}
}
void screen1(void) {
glColor3f(0, 1, 0);
char buf1[20] = { '\0' };
for (int row1 = -90.0f; row1 <= 90 + yr; row1 +=10.0f) {
sprintf_s(buf1,"%i", row1);
renderbitmap2(-70 , (yr+row1), GLUT_BITMAP_TIMES_ROMAN_24, buf1);
}
}
int main(int arg, char** argv) {
glutInit(&arg, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(width, height);
glutInitWindowPosition(50, 100);
glutCreateWindow("HUD Lines");
display();
glutDisplayFunc(Rolling);
glutSpecialFunc(specialKey);
glutMainLoop();
return 0;
}
At Orthographic Projection, the view space coordinates are linearly mapped to the clip space coordinates respectively normalized device coordinates. The normlaized device space is a cube with a minimum of (-1, -1, -1) and a maximum of (1, 1, 1).
Finally the coordinates in normalized device space are mapped to the rectangular viewport.
If the viewport is rectangular then the aspect ratio has to be considered, when the view space coordinates are transformed to clip space.
The mapping of the normalized device coordinates to the viewport distorted the geometry by the reciprocal aspect ration of the viewport. This distortion has to be compensated by the orthographic projection.
When the orthographic projection is set by glOrtho(left, right, bottom, top, near, far), then the cuboid volume is defined, which maps (left, bottom, near) to (-1, -1, -1) and (right, top, far) to (1, 1, 1).
It is not necessary that the x and y range of the orthographic projection is equal the view port rectangle, bit the ration (left-right)/(top-bottom)hast to be equal the ration of the viewport rectangle else the geometry will be distored.
double size = 200.0f;
double aspect = (double)width / (double)height;
glOrtho(-aspect*size/2.0, aspect*size/2.0, -size/2.0, size/2.0, -1.0, 1.0);
Your window size and orthographic "view" do not have the same aspect ratio:
// This creates a window that's 1268 x 720 (a wide rectangle)
int width = 1268;
int height = 720;
glutInitWindowSize(width, height);
// This creates a "view" that's 300 x 300 (a square)
glOrtho(-300, 300, -10, 25, 0, 1);
The "view" will be stretched to fill the viewport (window). You are seeing a 300 x 300 image being stretched to 1268x720, which definitely makes horizontal lines appear longer than vertical lines even though they're the same length in the code.
You should call glOrtho using the width and height variables of your window:
glOrtho(0, width, 0, height, 0, 1);
Notice that I have changed the arguments to (left = 0, right = width, bottom = 0, top = height, ...). This allows you to work with a screen coordinate space that is similar to 2D rendering but the bottom-left corner is (0,0) and the top-right is (width,height).
So I have this piece of code, which pretty much draws various 2D textures on the screen, though there are multiple sprites that have to be 'dissected' from the texture (spritesheet). The problem is that rotation is not working properly; while it rotates, it does not rotate on the center of the texture, which is what I am trying to do. I have narrowed it down to the translation being incorrect:
glTranslatef(x + sr->x/2 - sr->w/2,
y + sr->y/2 - sr->h/2,0);
glRotatef(ang,0,0,1.f);
glTranslatef(-x + -sr->x/2 - -sr->w/2,
-y + -sr->y/2 - -sr->h/2,0);
X and Y is the position that it's being drawn to, the sheet rect struct contains the position X and Y of the sprite being drawn from the texture, along with w and h, which are the width and heights of the 'sprite' from the texture. I've tried various other formulas, such as:
glTranslatef(x, y, 0);
The below three switching the negative sign to positive (x - y to x + y)
glTranslatef(sr->x/2 - sr->w/2, sr->y/2 - sr->h/2 0 );
glTranslatef(sr->x - sr->w/2, sr->y - sr->h/2, 0 );
glTranslatef(sr->x - sr->w, sr->y - sr->w, 0 );
glTranslatef(.5,.5,0);
It might also be helpful to say that:
glOrtho(0,screen_width,screen_height,0,-2,10);
is in use.
I've tried reading various tutorials, going through various forums, asking various people, but there doesn't seem to be a solution that works, nor can I find any useful resources that explain to me how I find the center of the image in order to translate it to '(0,0)'. I'm pretty new to OpenGL so a lot of this stuff takes awhile for me to digest.
Here's the entire function:
void Apply_Surface( float x, float y, Sheet_Container* source, Sheet_Rect* sr , float ang = 0, bool flipx = 0, bool flipy = 0, int e_x = -1, int e_y = -1 ) {
float imgwi,imghi;
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,source->rt());
// rotation
imghi = source->rh();
imgwi = source->rw();
Sheet_Rect t_shtrct(0,0,imgwi,imghi);
if ( sr == NULL ) // in case a sheet rect is not provided, assume it's width
//and height of texture with 0/0 x/y
sr = &t_shtrct;
glPushMatrix();
//
int wid, hei;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&wid);
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&hei);
glTranslatef(-sr->x + -sr->w,
-sr->y + -sr->h,0);
glRotatef(ang,0,0,1.f);
glTranslatef(sr->x + sr->w,
sr->y + sr->h,0);
// Yeah, out-dated way of drawing to the screen but it works for now.
GLfloat tex[] = {
(sr->x+sr->w * flipx) /imgwi, 1 - (sr->y+sr->h *!flipy )/imghi,
(sr->x+sr->w * flipx) /imgwi, 1 - (sr->y+sr->h * flipy)/imghi,
(sr->x+sr->w * !flipx) /imgwi, 1 - (sr->y+sr->h * flipy)/imghi,
(sr->x+sr->w * !flipx) /imgwi, 1 - (sr->y+sr->h *!flipy)/imghi
};
GLfloat vertices[] = { // vertices to put on screen
x, (y + sr->h),
x, y,
(x +sr->w), y,
(x +sr->w),(y +sr->h)
};
// index array
GLubyte index[6] = { 0,1,2, 2,3,0 };
float fx = (x/(float)screen_width)-(float)sr->w/2/(float)imgwi;
float fy = (y/(float)screen_height)-(float)sr->h/2/(float)imghi;
// activate arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// pass verteices and texture information
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, tex);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, index);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
Sheet container class:
class Sheet_Container {
GLuint texture;
int width, height;
public:
Sheet_Container();
Sheet_Container(GLuint, int = -1,int = -1);
void Load(GLuint,int = -1,int = -1);
float rw();
float rh();
GLuint rt();
};
Sheet rect class:
struct Sheet_Rect {
float x, y, w, h;
Sheet_Rect();
Sheet_Rect(int xx,int yy,int ww,int hh);
};
Image loading function:
Sheet_Container Game_Info::Load_Image(const char* fil) {
ILuint t_id;
ilGenImages(1, &t_id);
ilBindImage(t_id);
ilLoadImage(const_cast<char*>(fil));
int width = ilGetInteger(IL_IMAGE_WIDTH), height = ilGetInteger(IL_IMAGE_HEIGHT);
return Sheet_Container(ilutGLLoadImage(const_cast<char*>(fil)),width,height);
}
Your quad (two triangles) is centered at:
( x + sr->w / 2, y + sr->h / 2 )
You need to move that point to the origin, rotate, and then move it back:
glTranslatef ( (x + sr->w / 2.0f), (y + sr->h / 2.0f), 0.0f); // 3rd
glRotatef (0,0,0,1.f); // 2nd
glTranslatef (-(x + sr->w / 2.0f), -(y + sr->h / 2.0f), 0.0f); // 1st
Here is where I think you are getting tripped up. People naturally assume that OpenGL applies transformations in the order they appear (top-to-bottom), that is not the case. OpenGL effectively swaps the operands everytime it multiplies two matrices:
M1 x M2 x M3
~~~~~~~
(1)
~~~~~~~~~~
(2)
(1) M2 * M1
(2) M3 * (M2 * M1) --> M3 * M2 * M1 (row-major / textbook math notation)
The technical term for this is post-multiplication, it all has to do with the way matrices are implemented in OpenGL (column-major). Suffice it to say, you should generally read glTranslatef, glRotatef, glScalef, etc. calls from bottom-to-top.
With that out of the way, your current rotation does not make any sense.
You are telling GL to rotate 0 degrees around an axis: <0,0,1> (the z-axis in other words). The axis is correct, but a 0 degree rotation is not going to do anything ;)
I am using Qt + OpenGl for 2D rendering.
I am a beginner at OpenGL and for the life of me i am not able to figure out this aspect ratio issue. Everytime i think i have understood glOrtho and gViewPort, but very next time i am into another issue with them. While if coordinates are symmetric like between -1 and 1, my code works else it doesn't. I really want to get through these for once and all. All the suggestions i have searched and applied have gone fruitless for me.
My Problem Statement:
I am rendering a square and a triangle and i switch between them with keystroke "R". I am also zooming in and out. While square is maintaining aspect ratio, triangle is not. Coordinates for shapes are:
Square: (-10, -250), (500, -250), (500, -260), (-10, -260);
Triangle: (250, 0), (310, 0), (280, 30)
Basically I am not able to render above triangle. Here is code for same:
My Code
#include <QtGui/QMouseEvent>
#include <qdebug.h>
#include "GLWidget.h"
#include "stdio.h"
#include "qgl.h"
#include "qimage.h"
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
{
setMouseTracking(true);
}
void GLWidget::initializeGL()
{
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glEnable(GL_POLYGON_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(1, 1, 1, 0);
glEnable( GL_POINT_SMOOTH ); // For Circular Points
}
void GLWidget::resizeGL(int w, int h)
{
canvas_width = (double)w;
canvas_height = (double)h;
aspect_ratio = canvas_width/canvas_height;
left_plane = 250;
right_plane = 310;
bottom_plane = 0;
top_plane = 60;
z_near_plane = 1;
z_far_plane = -1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if( canvas_width > canvas_height ){
glOrtho(left_plane*aspect_ratio, right_plane*aspect_ratio, bottom_plane, top_plane, z_near_plane, z_far_plane);
}else{
glOrtho(left_plane, right_plane, bottom_plane/aspect_ratio, top_plane/aspect_ratio, z_near_plane, z_far_plane);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,0,0); // red
glBegin(GL_POLYGON);
//glVertex2f(-30,0);
//glVertex2f(30,0);
//glVertex2f(0,60);
glVertex2f(250,0);
glVertex2f(310,0);
glVertex2f(280,60);
glEnd();
}
I do not see any traingle because left_plane*aspect_ratio clips my drawing (250 is minimum X, 250*1.4 > 310, 310 is maximum X).
I hope i have made myself clear.
I will try to place images as well (i guess i will have to upload images to some other site and link them here?).
Your problem is that the bounding box (the values assigned to left/right/top/bottom_plane) doesn't have the same aspect ratio as the viewport. If you have the bounding box for the object, you need to find viewport coordinates with the correct aspect ratio (w/h). The viewport needs to be both centered on the bounding box center, and be big enough to fit the bounding box. But the aspect ratio of the viewport has nothing to do with the size of the bounding box.
In general you have a 3D bounding box (8 corner points). You would project each corner onto the screen, then use min/max to get a rectangle that needs to be centered on screen. You then check the aspect ratio ar = wr/hr of that rectangle against the aspect ratio of the viewport a=w/r. If a < ar, you need to fit wr to w, otherwise fit hr to h.
void GLWidget::resizeGL(int w, int h)
{
// First set up the projection.
double canvas_width = (double)w;
double canvas_height = (double)h;
double a = canvas_width / canvas_height;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-a, +a, -1, +1, -1, +1);
// Now set up the view matrix.
double leftBoundingRectangle = 250;
double rightBoundingRectangle = 310;
double bottomBoundingRectangle = 0;
double topBoundingRectangle = 60;
double widthBoundingRectangle = rightBoundingRectangle - leftBoundingRectangle;
double heightBoundingRectangle = topBoundingRectangle - bottomBoundingRectangle;
double ar = widthBoundingRectangle / heightBoundingRectangle;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Center on bounding rectangle center.
double tx = (leftBoundingRectangle + rightBoundingRectangle)/2.0, ty = (topBoundingRectangle + bottomBoundingRectangle)/2.0;
glTranslated(tx, ty, 0.0); // or is it -tx, -ty?
// Scale to fit bounding box.
double s;
if (ar > a)
{
s = ... // sorry, but you have to figure this one out for yourself. :)
}
else
{
s = ...
}
glScaled(s,s,s);
}
I am trying to write a own rotation function for a camera in OpenGL, but I can't get it to run. My camera is mainly from flipcode, with some minor changes:
Camera code:
Camera::Camera(float x, float y, float z) {
memset(Transform, 0, 16*sizeof(float));
Transform[0] = 1.0f;
Transform[5] = 1.0f;
Transform[10] = 1.0f;
Transform[15] = 1.0f;
Transform[12] = x; Transform[13] = y; Transform[14] = z;
Left=&Transform[0];
Up=&Transform[4];
Forward=&Transform[8];
Position=&Transform[12];
old_x = 0;
old_y = 0;
}
The view is set before every rendered frame:
void Camera::setView() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float viewmatrix[16]={//Remove the three - for non-inverted z-axis
Transform[0], Transform[4], -Transform[8], 0,
Transform[1], Transform[5], -Transform[9], 0,
Transform[2], Transform[6], -Transform[10], 0,
-(Transform[0]*Transform[12] +
Transform[1]*Transform[13] +
Transform[2]*Transform[14]),
-(Transform[4]*Transform[12] +
Transform[5]*Transform[13] +
Transform[6]*Transform[14]),
//add a - like above for non-inverted z-axis
(Transform[8]*Transform[12] +
Transform[9]*Transform[13] +
Transform[10]*Transform[14]), 1};
glLoadMatrixf(viewmatrix);
}
Now to my problem, the rotation. Consider for example rotation around the y-axis. This is the rotation matrix stack:
// deg is the angle it is not working in degree or radiant
void Camera::rotateLocal_y(float deg){
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(Transform);
rotateMatrixf_y(Transform, deg);
glGetFloatv(GL_MODELVIEW_MATRIX, Transform);
glPopMatrix();
}
So next I am going to show the rotation function:
//rotate a matrix around y axis
void rotateMatrixf_y(float *aMatrix, float angle){
// x y z t
float rotMatrix[] = {cos(angle),0,-1*sin(angle),0, 0, 1, 0, 0, sin(angle), 0, cos(angle), 0, 0, 0, 0, 1};
multMatrixMatrix(rotMatrix,aMatrix);
}
And finally the matrix multiplication function:
void multMatrixMatrix(float* m_a, float* m_b){
float m_c[16] = {m_a[0]*m_b[0]+m_a[4]*m_b[1]+m_a[8]*m_b[2]+m_a[12]*m_b[3],
m_a[0]*m_b[4]+m_a[4]*m_b[5]+m_a[8]*m_b[6]+m_a[12]*m_b[7],
m_a[0]*m_b[8]+m_a[4]*m_b[9]+m_a[8]*m_b[10]+m_a[12]*m_b[11],
m_a[0]*m_b[12]+m_a[4]*m_b[13]+m_a[8]*m_b[14]+m_a[12]*m_b[15],
m_a[1]*m_b[0]+m_a[5]*m_b[1]+m_a[9]*m_b[2]+m_a[13]*m_b[3],
m_a[1]*m_b[4]+m_a[5]*m_b[5]+m_a[9]*m_b[6]+m_a[13]*m_b[7],
m_a[1]*m_b[8]+m_a[5]*m_b[9]+m_a[9]*m_b[10]+m_a[13]*m_b[11],
m_a[1]*m_b[12]+m_a[5]*m_b[13]+m_a[9]*m_b[14]+m_a[13]*m_b[15],
m_a[2]*m_b[0]+m_a[6]*m_b[1]+m_a[10]*m_b[2]+m_a[14]*m_b[3],
m_a[2]*m_b[4]+m_a[6]*m_b[5]+m_a[10]*m_b[6]+m_a[14]*m_b[7],
m_a[2]*m_b[8]+m_a[6]*m_b[9]+m_a[10]*m_b[10]+m_a[14]*m_b[11],
m_a[2]*m_b[12]+m_a[6]*m_b[13]+m_a[10]*m_b[14]+m_a[14]*m_b[15],
m_a[3]*m_b[0]+m_a[7]*m_b[1]+m_a[11]*m_b[2]+m_a[15]*m_b[3],
m_a[3]*m_b[4]+m_a[7]*m_b[5]+m_a[11]*m_b[6]+m_a[15]*m_b[7],
m_a[3]*m_b[8]+m_a[7]*m_b[9]+m_a[11]*m_b[10]+m_a[15]*m_b[11],
m_a[3]*m_b[12]+m_a[7]*m_b[13]+m_a[11]*m_b[14]+m_a[15]*m_b[15]
};
m_b = m_c;
}
I though this must be it, but it seems as if something is fundamentaly wrong. It is not moving at all. the camera is properly set. The method order is: cam.rotate then cam.setView.
Flipcodes originial rotate function:
void Camera::rotateLoc(float deg, float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(Transform);
glRotatef(deg, x,y,z);
glGetFloatv(GL_MODELVIEW_MATRIX, Transform);
glPopMatrix();
}
Your code is pretty messy and incomplete.
I think your problem is here :
glPushMatrix();
glLoadMatrixf(Transform); // give the Transform matrix to GL (why?)
rotateMatrixf_y(Transform, deg); // modify the Transform matrix
glGetFloatv(GL_MODELVIEW_MATRIX, Transform); // (3) retrieve the original Tranform matrix
glPopMatrix();
(3) just undoes whatever changes you've been doing in 'Transform' by calling 'rotateMatrixf_y'.
The flipcode code you added is using OpenGL to update the Tranform matrix, by calling glRotatef' and reading back the result, which is fine. In your method code, you should just remove every reference to OpenGL and just keep the call to rotateMatrixf_y, which does all the work in its own.
Do you really understand what's the use of the GL matrix stack ? You should perhaps go back to the basics by either using only GL functions or using your own, but get to know why it works in either way before mixing the uses.