   Basic OpenGL Translation Question
  Lately I've been messing around trying to learn a bit of OpenGL.  What I'm trying to is draw a grid of tiles and then draw different shapes (in this case a pyramid) on top of those tiles.  Each tile is a square.  I know the vertex coordinates of each corner of each square, and I calculate the normals of each square by determining the vector between two vertices, finding the cross product of those two vectors, normalizing them and then adding it to the vector describing the center of the tile.So:  When I'm drawing my Pyramids, I do it by just drawing three triangles.  The base vertices of each triangle are the vertices of each tile, and the third vertex (in this case the top of the pyramid) is simply the vector representing the normal vector of the tile.As far as I can tell, this method works for simply drawing a pyramid, my issue comes when I attempt to translate it.  I'm not sure why, but it appears only the bases of the triangles are moving.  The tip of the pyramid (the third vertex of each triangle) does not get translated, and I am unsure why that is.  I'll post the code I *think* is relevant, but if you need to see something else please feel free to ask..Code to draw a Tile:void Tile::draw(){  if(_sq){    /* Set static variables of everything that needs to be translated. */    Square::s_xtrans = Tile::s_xtrans;    Square::s_ytrans = Tile::s_ytrans;    Square::s_ztrans = Tile::s_ztrans;   Triangle::s_xtrans = Tile::s_xtrans;    Triangle::s_ytrans = Tile::s_ytrans;    Triangle::s_ztrans = Tile::s_ztrans;   _sq->draw();    drawTerrain();    drawUnit();  }  else    std::cout<<"This Tile is not yet drawable.\n";}Where _sq is a private variable representing the tile's square.drawTerrain() calls Pyramids draw function.Code to draw a square (in square class):void Square::draw(){  float vertx, verty, vertz;  glLoadIdentity();  glTranslatef(s_xtrans, s_ytrans, s_ztrans);  glBegin(GL_LINE_LOOP);  glColor3f((0x33/255), (0xFF/255), (0x00/255));  for(int i = 0; i < 4; i++)    { vertx = _verts->x; verty = _verts->y; vertz = _verts->z; glVertex3f(vertx, verty, vertz);    }  glEnd();}Code to draw a Triangle (in triangle class):void Triangle::draw(){  float vertx, verty, vertz;  glLoadIdentity();  glTranslatef(s_xtrans, s_ytrans, s_ztrans);  glBegin(GL_LINE_LOOP);  glColor3f(1.0f, 1.0f, 1.0f);  for(int i = 0; i < 3; i++)    { vertx = _verts->x; verty = _verts->y; vertz = _verts->z; glVertex3f(vertx, verty, vertz);    }  glEnd();}In both Square and Triangle _verts is an array containing each vertex of the shape.And finally, Code to draw a Pyramid (in pyramid class) (real simple):void Pyramid::draw(){  for(int i = 0; i < 4; i++) _sides->draw();}Where _sides is an array of triangles, which are created by the code:void Pyramid::initSides(){  MyVector** verts = _base->getVerts();  MyVector* triVert1, * triVert2, * triVert3;  float vertx, verty, vertz;  for(int i = 0; i < 4; i++)    { triVert1 = verts; if(i == 3)triVert2 = verts[0]; elsetriVert2 = verts[i+1]; triVert3 = _base->getNormal(); _sides = new Triangle(triVert1, triVert2, triVert3);    }}Where _base is the tile (square) that this pyramid is being drawn on.This is my translation code, in a Grid object that is simply a 2d array of tiles.void Grid::translate(bool up, bool down, bool left, bool right){  if(!(up && down))    { if(up){  ytrans -= XY_TRANS_AMT;  ztrans += Z_TRANS_AMT;} if(down){  ytrans += XY_TRANS_AMT;  ztrans -= Z_TRANS_AMT;}    }  if(!(left && right))    { if(left)  xtrans += XY_TRANS_AMT; if(right)  xtrans -= XY_TRANS_AMT;    }    Tile::s_xtrans = xtrans;  Tile::s_ytrans = ytrans;  Tile::s_ztrans = ztrans;}I'm guessing that my problem is in how I'm translating, though it works fine with tiles and I thought it was a decent idea initially to use static variables being that the nature of this program means everything will *always* move the same amount as everything else.Anyways sorry if that was incredibly long winded - I just haven't really been able to figure this out - And I'm not entirely sure what code you guys might need to see.  Anyways - Thanks for any assistance.   
  Do you think you could post a screenshot?  The only thing I can think of right now is that maybe the vector returned by _base->getNormal(); in Pyramid::initSides() isn't quite right.  Could you post the code behind the getNormal() function?  It looks like your translations are all the same, and it looks like you're always doing glLoadIdentity() before translating, so those parts don't jump out to me as problems.   ;  Definitely:This is the grid initially without moving:http://img38.imageshack.us/img38/5853/pic1c.jpgAnd this is the grid upon translating it a bit to the left:http://img39.imageshack.us/img39/9412/pic2wuh.jpgAnd here is the code for getting the normal vector:MyVector* MyVector::calcNormal(MyVector* v, MyVector* w){  return v->cross(w);}MyVector* MyVector::cross(MyVector* v){  float newx, newy, newz;  newx = (y * v->z) - (z * v->y);  newy = (z * v->x) - (x * v->z);  newz = (x * v->y) - (y * v->x);  return new MyVector(newx, newy, newz);}Whoops I left this out:The code to calculate the normal for a square:void Square::calcNormal(){  /* These two MyVectors will hold the vectors connecting three points on   * the square (and thus two vectors on the plane) that will be used   * to calculate the normal. */  MyVector* v0v1, * v1v2;   /* Vectors connecting the vert0 to vert1 and vert1 to vert2. */    v0v1 = _verts[0]->vectorBetweenTwoPoints(_verts[1]);  v1v2 = _verts[1]->vectorBetweenTwoPoints(_verts[2]);    _normal = _normal->calcNormal(v0v1, v1v2);  _normal->add(_centerVector);/* Add the normal vector to the center coords  * of the square.  The normal vector is calculated  * as being through the origin so doing this  * will put it directly through the center  * of the square. */  _normal->normalize();}Thanks for the help!Edit: just gave you links to the images so the whole post isn't for some reason weird.[Edited by - Aztral on May 26, 2009 11:48:07 PM];  Hmmm...  Here's something to try that might help narrow down the problem, cause so far I can't see one.  If you were to remove all the glLoadIdentity() and glTranslate() function calls and change Tile::draw() to the followingvoid Tile::draw(){  if(_sq){    /* Set static variables of everything that needs to be translated. */   Square::s_xtrans = Tile::s_xtrans;    Square::s_ytrans = Tile::s_ytrans;    Square::s_ztrans = Tile::s_ztrans;   Triangle::s_xtrans = Tile::s_xtrans;    Triangle::s_ytrans = Tile::s_ytrans;    Triangle::s_ztrans = Tile::s_ztrans;   // Rather than have each square/triangle do its own translation,    // just do one translation at the beginning and let it persist    // while you draw the square/triangles for this tile    glLoadIdentity();    glTranslatef(Tile::s_xtrans, Tile::s_ytrans, Tile::s_ztrans);   _sq->draw();    drawTerrain();    drawUnit();  }  else    std::cout<<"This Tile is not yet drawable.\n";}Does the problem persist?  If the problem goes away, then it is very likely that the problem is being caused by how you're translating.  If the problem is still there, then it is very likely that the problem is not being caused by how you're translating and probably has to do with some other part of your program.   ;  Hmmm.  Doing that doesn't change the error =(.Im at a loss for where to look.  It seems strange to me that it would translate the base of each triangle but not the 'tip' of it (the vert forming the tip of the pyramid).   ;  I've been looking at your code for a while, and I don't see anything in the stuff that you posted that seems like it would cause something like that to happen. The only thing I can think of to even try would be to do glPushMatrix() before the translate, and glPopMatrix() after the glEnd().This is unnecessarily complex for what you're trying to do, though. openGL has triangles and quads (squares) built in as primitives, so you really don't need to have classes for them (the primitives are specifically GL_TRIANGLES and GL_QUADS).Instead of thinking of objects as a series of lines, try to think of them as a collection of vertices. A pyramid is 5 vertices, which form 4 tris and 1 quad (the base).   ;  Thanks.  I'll definitely try that when I can (I'm not at home at the moment.)As far as me making things complex - I don't doubt it at all.  Would it still make sense to have a Square (for example) class even if it is nothing more than a container for the XYZ coordinates of it's center and it's normal vector?  Since the normal is relevant to the calculation of the pyramids (and I'm sure a lot more)?  Or is there a better way to do that?   ;Quote:Original post by AztralThanks.  I'll definitely try that when I can (I'm not at home at the moment.)As far as me making things complex - I don't doubt it at all.  Would it still make sense to have a Square (for example) class even if it is nothing more than a container for the XYZ coordinates of it's center and it's normal vector?  Since the normal is relevant to the calculation of the pyramids (and I'm sure a lot more)?  Or is there a better way to do that?Oh, I didn't realize you were representing each square that way.I would definitely just use 4 vertices to represent each square instead of doing that. I wrote a program representing boxes in similarly, and it ended up being a LOT more complicated than just storing all the vertices.You can make a container class to store the data if you want to, but again, it seems like that needlessly complicates things. Vertices are usually stored in an array of 3 floats, so you can call glVertex3fv on the array, instead of having to put 3 variable names into each vertex call.   