Finding center of image for rotation in opengl - c++

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 ;)

Related

C++ OpenGL mesh rendering

I know there are a lot of resources about this on the internet but they didn't quite seem to help me.
What I want to achieve:
I am baking a mesh from data which stores the vertices inside a vector<Vector3>.
(Vector3 is a sctruct containg float x, y, z)
It stores triangles in a map<int, vector<int>>
(the key of the map is the submesh and the vector<int> the triangles)
the uv inside a vector<Vector2>
(Vector2 is a struct containing float x, y)
and a color value in vector<Color>
(the color value applies to vertices like the uv does)
Now I want to write a code that can read that data and draw it to the screen with maximum performance
What I got:
static void renderMesh(Mesh mesh, float x, float y, float z) {
if (mesh.triangles.empty()) return;
if (mesh.vertices.empty()) return;
if (mesh.uvs.empty()) return;
glColor3f(1, 1, 1);
typedef std::map<int, std::vector<int>>::iterator it_type;
for (it_type iterator = mesh.triangles.begin(); iterator != mesh.triangles.end(); iterator++) {
int submesh = iterator->first;
if (submesh < mesh.textures.size()) glBindTexture(GL_TEXTURE_2D, mesh.textures[submesh].id);
else glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (int i = 0; i < iterator->second.size(); i += 3) {
int t0 = iterator->second[i + 0];
int t1 = iterator->second[i + 1];
int t2 = iterator->second[i + 2];
Vector3 v0 = mesh.vertices[t0];
Vector3 v1 = mesh.vertices[t1];
Vector3 v2 = mesh.vertices[t2];
Color c0 = mesh.vertexColors[t0];
Color c1 = mesh.vertexColors[t1];
Color c2 = mesh.vertexColors[t2];
Vector2 u0 = mesh.uvs[t0];
Vector2 u1 = mesh.uvs[t1];
Vector2 u2 = mesh.uvs[t2];
glBegin(GL_TRIANGLES);
glColor4f(c0.r / 255.0f, c0.g / 255.0f, c0.b / 255.0f, c0.a / 255.0f); glTexCoord2d(u0.x, u0.y); glVertex3f(v0.x + x, v0.y + y, v0.z + z);
glColor4f(c1.r / 255.0f, c1.g / 255.0f, c1.b / 255.0f, c1.a / 255.0f); glTexCoord2d(u1.x, u1.y); glVertex3f(v1.x + x, v1.y + y, v1.z + z);
glColor4f(c2.r / 255.0f, c2.g / 255.0f, c2.b / 255.0f, c2.a / 255.0f); glTexCoord2d(u2.x, u2.y); glVertex3f(v2.x + x, v2.y + y, v2.z + z);
glEnd();
glColor3f(1, 1, 1);
}
}
}
The problem:
I found out that the way I render is not the best way and that you can achieve higher performance with glDrawArrays (I think it was called).
Could you help me rewriting my code to fit with glDrawArrays, since what I found so far on the internet did not help me too much.
Thanks, and if there is any more information needed just ask.
The use of functions like glBegin and glEnd is deprecated. Functions like glDrawArrays have a better performance, but slightly more complicated to use.
The problem of glBegin render techniques is you have to communicate each vertex one by one each time you want to draw something. Today, graphic cards are able to render thousands of vertices very quickly, but if you give it one by one, the render will become laggy regardless your graphic card performance.
The main advantage of glDrawArrays is you have to initialize your arrays once, and then draw it with one call. So first, you need to fill at the start of your program an array for each attribute. In your case: positions, colors and texture coords. It must be float arrays, something like this:
std::vector<float> vertices;
std::vector<float> colors;
std::vector<float> textureCoords;
for (int i = 0; i < iterator->second.size(); i += 3) {
int t0 = iterator->second[i + 0];
int t1 = iterator->second[i + 1];
int t2 = iterator->second[i + 2];
vertices.push_back(mesh.vertices[t0].x);
vertices.push_back(mesh.vertices[t0].y);
vertices.push_back(mesh.vertices[t0].z);
vertices.push_back(mesh.vertices[t1].x);
vertices.push_back(mesh.vertices[t1].y);
vertices.push_back(mesh.vertices[t1].z);
vertices.push_back(mesh.vertices[t2].x);
vertices.push_back(mesh.vertices[t2].y);
vertices.push_back(mesh.vertices[t2].z);
// [...] Same for colors and texture coords.
}
Then, in another function set only for display, you can use these arrays in order to draw it:
// Enable everything you need
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Set your used arrays
glVertexPointer(3, GL_FLOAT, 0, vertices.data());
glColorPointer(4, GL_FLOAT, 0, colors.data());
glTexCoordPointer(2, GL_FLOAT, 0, textureCoords.data());
// Draw your mesh
glDrawArrays(GL_TRIANGLES, 0, size); // 'size' is the number of your vertices.
// Reset initial state
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Of course, you'll have to enable other attributes you want to use, like texture or blending.
NOTE:
If you wish to learn about performance, there are also other functions using indices in order to reduce the size of data used, like glDrawElements.
There are also other more advanced OpenGL techniques that allows you to increase performance by saving your data directly on the graphic card memory, like Vertex Buffer Objects.

Rotating Vertex Array Object not working

I am using vertex arrays to store circle vertices and colors.
Here is the setup function:
void setup1(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
// Enable two vertex arrays: co-ordinates and color.
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Specify locations for the co-ordinates and color arrays.
glVertexPointer(3, GL_FLOAT, 0, Vertices1);
glColorPointer(3, GL_FLOAT, 0, Colors1);
}
The global declaration of the arrays is here:
static float Vertices1[500] = { 0 };
static float Colors1[500] = { 0 };
The arrays are all set up here (R is the radius, X and Y are the (X,Y) center, and t is the angle parameter of the circle)
void doGlobals1()
{
for (int i = 0; i < numVertices1 * 3; i += 3)
{
Vertices1[i] = X + R * cos(t);
Vertices1[i + 1] = Y + R * sin(t);
Vertices1[i + 2] = 0.0;
t += 2 * PI / numVertices1;
}
for (int j = 0; j < numVertices1 * 3; j += 3)
{
Colors1[j] = (float)rand() / (float)RAND_MAX;
Colors1[j + 1] = (float)rand() / (float)RAND_MAX;
Colors1[j + 2] = (float)rand() / (float)RAND_MAX;
}
}
Finally, this is where the shape is drawn.
// Window 1 drawing routine.
void drawScene1(void)
{
glutSetWindow(win1);
glLoadIdentity();
doGlobals1();
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(15, 1, 0, 0);
glDrawArrays(GL_TRIANGLE_FAN, 0, numVertices1);
glFlush();
}
Without the Rotation, the circle draws just fine. The circle also draws fine with any Scale/Translate function. I suspect there is some special protocol necessary to rotate an object drawn with vertex arrays.
Can anyone tell me where I have gone wrong, what I will need to do in order to rotate the object, or offer any advice?
glRotatef(15, 1, 0, 0);
^ why the X axis?
The default ortho projection matrix has pretty tight near/far clipping planes: -1 to 1.
Rotating your circle of X/Y coordinates outside of the X/Y plane will tend to make those points get clipped.
Rotate around the Z axis instead:
glRotatef(15, 0, 0, 1);

How to efficiently draw 3D lines using gluCylinder?

I have this code that draws a 3D line between two points:
void glLine(Point3D (&i)[2], double const width, int const slices = 360)
{
double const d[3] = { i[1].X - i[0].X, i[1].Y - i[0].Y, i[1].Z - i[0].Z };
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
GLUquadric *const quadric = gluNewQuadric()
double z[3] = { 0, 0, 1 };
double const angle = acos(dot(z, d) / sqrt(dot(d, d) * dot(z, z)));
cross(z, d);
glTranslated(i[0].X, i[0].Y, i[0].Z);
glRotated(angle * 180 / M_PI, z[0], z[1], z[2]);
gluCylinder(quadric, width / 2, width / 2, sqrt(dot(d, d)), slices, 1);
glPopMatrix();
gluDeleteQuadric(quadric);
}
The trouble is, it's extremely slow because of the math that computes the rotation from the unit z vector to the given direction.
How can I make OpenGL (hopefully, the GPU) perform the arithmetic instead of the CPU?
Do not render lines using cylinders. Rather render quads using geometry shaders, facing the user with correct screen space scaling.
Have a look here: Wide lines in geometry shader behaves oddly

Draw a curved line from an arc edge

Here's the screenshot of what I am doing. Currently, I'm stuck from drawing a curved borders into this rectangle.
My first solution was: draw a quartered circle behind the rectangle, but if I adjust the opacity of the shape, as you can see, the quartered circle gets shown.
I know this is pretty basic for you guys but I'm not really good at math.
I did try to reuse the computed edges of the arc and add the size of border but I got this as a result.
I also think of bezier curves as a replacement but I think it is more efficient to just reuse the computed vertices and add all the missing ones. Also, I don't know how to compute for the curved points of bezier curves and finding the right amount of t would be very computationally expensive so I don't implement it.
Here's the code how I draw the inner quartered circle and I think I can just reuse it.
void drawArc(int x, int y,
int startAngle, int endAngle,
uint32_t radiusX, uint32_t radiusY,
int border_x, int border_y,
const rgb color,
const rgb bcX, const rgb bcY,
uint8_t opacity)
{
if (radiusX <= 0 || radiusY <= 0) return;
static constexpr float DTR = 3.14159 / 180;
float cx, cy;
int step;
static std::vector<float> verts;
static std::vector<uint8_t> colors;
if (startAngle < endAngle)
{
step = +1;
++ endAngle;
} else
{
step = -1;
-- endAngle;
}
verts.clear();
colors.clear();
verts.push_back(x);
verts.push_back(y);
colors.push_back(color[R]);
colors.push_back(color[G]);
colors.push_back(color[B]);
colors.push_back(opacity);
while (startAngle != endAngle)
{
cx = cos(DTR * startAngle) * radiusX;
cy = sin(DTR * startAngle) * radiusY;
verts.push_back(x + cx);
verts.push_back(y - cy);
colors.push_back(color[R]);
colors.push_back(color[G]);
colors.push_back(color[B]);
colors.push_back(opacity);
startAngle += step;
}
drawElements(GL_POLYGON, sizeof(arcIndices) / sizeof(arcIndices[0]), GL_FLOAT,
&verts[0], &colors[0], &arcIndices[0]);
if (border_x != 0 || border_y != 0)
{
//remove (x, y)
verts.erase(verts.begin(), verts.begin() + 2);
// float px, py;
//
// px = *(verts.begin() + 0);
// py = *(verts.begin() + 1);
//
// glPointSize(5);
//
// glBegin(GL_POINTS);
//
// glColor3ub(0,0,255);
// glVertex2i(px, py);
//
// px = *(verts.end() - 2);
// py = *(verts.end() - 1);
//
// glColor3ub(255,0,0);
// glVertex2i(px , py);
// glEnd();
//attempting to reuse the edges
//I think the last vertices are opposed
//that's why I got a crossed out lines??
for (int i = 0;i <= 90; ++i)
{
verts.push_back(verts[i + 0] + border_x);
verts.push_back(verts[i + 1] + border_y);
colors.push_back(bcX[R]);
colors.push_back(bcX[G]);
colors.push_back(bcX[B]);
colors.push_back(opacity);
}
//91 = steps from 0-90 degree revolution
//182 = 91 * 2
unsigned int index[182 + 91 * 2];
for (int i = 0;i < 182 + 91 * 2; ++i)
index[i] = i;
drawElements(GL_LINE_LOOP, verts.size() / 2, GL_FLOAT,
&verts[0], &colors[0], &index[0]);
}
}
Edit:
Can't I just reuse the pre-calculated (x,y) before?
Sorry for too much use of pictures
The red dots are pre-calculated (x, y) I'm referring to and just append the next arc base on this.
I'm gonna render many of this kind so I need as efficient as possible(w/o too much use to trigo functions).
Update:
And here is the result I got from using stencil buffer as what Andon M. Coleman suggested:
Btw, as you can see, I am trying to emulate my own UI using OpenGL :D
You expressed an interest in seeing how this could be solved using the stencil buffer yesterday, so I am following up with some basic pseudo-code.
glClearStencil (0x0);
glClear (GL_STENCIL_BUFFER_BIT);
glEnable (GL_STENCIL_TEST);
glStencilFunc (GL_ALWAYS, 0x0, 0x0);
// Add 1 to stencil buffer at every location the object to be bordered is visible
glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);
// Draw your grey object
// Only draw the red border where the grey object was never drawn (stencil = 0x0)
glStencilFunc (GL_EQUAL, 0x0, 0xff);
// Draw your red quarter circles
glDisable (GL_STENCIL_TEST);
Clearing the stencil buffer everytime you draw your outlined object is probably overkill. If you opt to clear the stencil buffer once per-frame instead, you can do some pretty interesting things. For instance, if you drew the outlines as a separate pass after all non-outlined shapes are drawn you could use this stencil buffer setup to outline the union (instead of including the intersection of objects as part of the drawn outline) of any overlapping objects.. this would allow you to construct more complicated shapes from your simple rounded rectangles.
Of course for this to work, your pixel format must have a stencil buffer. I will have to leave that part up to you, because the process of setting that up is implementation specific.
GL_POLYGON is only for convex polygons.
Link together the vertices on your inner and outer radii to form quads/triangles:
#include <GL/glut.h>
#include <cmath>
void Torus2d
(
float angle, // starting angle in radians
float length, // length of arc in radians, >0
float radius, // inner radius, >0
float width, // width of torus, >0
unsigned int samples // number of circle samples, >=3
)
{
if( samples < 3 ) samples = 3;
const float outer = radius + width;
glBegin( GL_QUAD_STRIP );
for( unsigned int i = 0; i <= samples; ++i )
{
float a = angle + ( i / (float)samples ) * length;
glVertex2f( radius * cos( a ), radius * sin( a ) );
glVertex2f( outer * cos( a ), outer * sin( a ) );
}
glEnd();
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glOrtho( -4 * ar, 4 * ar, -4, 4, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 0, 0 );
Torus2d( 0, 1.57079633, 2, 1, 20 );
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}

Camera rotation in OpenGL not using glRotate glLookAt

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.