Ok, I'm trying to recreate an old classic rocket command using OpenGL in C ++. This is my first foray into OpenGL, although I feel pretty comfortable with C ++ at this point.
I decided that my first task was to figure out how to move 2d objects around the screen, it seemed that it would be quite simple. I created two quick method calls to make triangles or squares:
void makeTriangle(color3f theColor, vertex2f &p1, vertex2f &p2, vertex2f &p3, int &xOffset, int &yOffset) {
color3f and vertex2f are simple classes:
class vertex2f { public: float x, y; vertex2f(float a, float b){x=a; y=b;} }; class color3f { public: float red, green, blue; color3f(float a, float b, float c){red=a; green=b; blue=c;} };
And here is my main file:
#include <iostream> #include "Shapes.hpp" using namespace std; int xOffset = 0, yOffset = 0; bool done = false; void keyboard(unsigned char key, int x, int y) { if( key == 'q' || key == 'Q') { exit(0); done = true; } if( key == 'a' ) xOffset = -10; if( key == 'd' ) xOffset = 10; if( key == 's' ) yOffset = -10; if( key == 'w' ) yOffset = 10; } void init(void) { //Set color of display window to white glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Set parameters for world-coordiante clipping window glMatrixMode(GL_PROJECTION); gluOrtho2D(-400.0,400.0,-300.0,300.0); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); color3f aGreen(0.0, 1.0, 0.0); vertex2f pa(-400,-200); vertex2f pb(-400,-300); vertex2f pc(400,-300); vertex2f pd(400,-200); makeQuad(aGreen,pa,pb,pc,pd,xOffset,yOffset); color3f aRed(1.0, 0.0, 0.0); vertex2f p1(-50.0,-25.0); vertex2f p2(50.0,-25.0); vertex2f p3(0.0,50.0); makeTriangle(aRed,p1,p2,p3,xOffset,yOffset); glFlush(); } int main(int argc, char** argv) { // Create Window. glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutCreateWindow("test"); // Some initialization. init(); while(!done) { //display functions glutDisplayFunc(display); glutKeyboardFunc(keyboard); // Start event loop. glutMainLoop(); } return 0; }
The square is defined as the “background” at the moment and consists only of a green rectangle along the bottom of the screen. The red triangle is the “object” I want to move. When you press the key, the offset is saved in the specified direction.
I tried using glTranslatef(xOffset,yOffset,0); , but the problem is that it moves both elements on the screen, not just the red triangle. I tried putting the whole call to draw a triangle between the push and pop matrix operation:
PushMatrix(); glTranslatef(xOffset,yOffset,0); glBegin(GL_POLYGON); glColor3f(theColor.red, theColor.green, theColor.blue); glVertex2f(p1.x, p1.y); glVertex2f(p2.x, p2.y); glVertex2f(p3.x, p3.y); glEnd(); PopMatrix();
As far as I can tell, this destroys any changes that the translation made in advance. I also tried just changing the x and y coordinates before calling a draw, but this just causes a brief flicker before leaving the triangle in its original position:
p1.x += xOffset; p2.x += xOffset; p3.x += xOffset; p1.y += yOffset; p2.y += yOffset; p3.y += yOffset;
There must be a good easy way to do this, and I'm just reviewing it. Can anyone suggest a suggestion?
EDIT:
My actual problem was that I never updated the screen after the initial draw. I needed to specify a simple function inside my main loop:
glutIdleFunc(IdleFunc);
If the actual IdleFunc looks like this:
GLvoid IdleFunc(GLvoid) { glutPostRedisplay(); }
Instead of using glFlush() inside my drawing function, I had to use glutSwapBuffers() . In doing so, the code I first came up with:
p1.x += xOffset; p2.x += xOffset; p3.x += xOffset; p1.y += yOffset; p2.y += yOffset; p3.y += yOffset;
Works great for my purposes. I didn’t need to translate the matrix, I just needed to draw an element in another place from one scene to another.