Scaling in opengl - opengl

My code works as follows :
A triangle is drawn and then when "1" is clicked the triangle is scaled but what happen is that the triangle is both scaled and translated.
Here is my code:
global variables
#include <glut.h>
void Display(void);
void MyKeyboard(unsigned char,int,int);
void MyMouse(int,int,int,int);
int x1 =20 .0f;
int y1 = 30.0f;
int x2 = 40.0f;
int y2 = 50.0f;
int x3 = 60.0f;
int y3 = 10.0f;
the main method
void main(int argc,char** argr)
{
glutInit(&argc,argr);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,600);
glutInitWindowPosition(50,50);
glutCreateWindow("Mouse and Keyboard");
glutDisplayFunc(Display);
glutKeyboardFunc(MyKeyboard);
glutMouseFunc(MyMouse);
glClearColor(0.0f,0.0f,0.0f,0.0f);
gluOrtho2D(0.0,1000.0,0.0,600.0);
glutMainLoop();
}
display method
void Display()
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(x1, 600-y1, 0.0f);
glVertex3f(x2, 600-y2, 0.0f);
glVertex3f(x3, 600-y3, 0.0f);
glEnd( );
glPopMatrix();
glFlush();
}
keyboard event
void MyKeyboard(unsigned char key,int mouseX,int mouseY)
{
if (key == '1')
{
glScaled (0.5f ,0.5f ,1.0f);
glutPostRedisplay();
return;
}

glScaled() will essentially cause all your points to be multiplied by the values you supply to glScaled(). What this essentially means is that all your vertices will move away from the origin (0,0). To overcome your scaling problem, simply define your triangle to be centered at (0,0).
Obviously you won't always want your triangle to be at zero, so you have to make use of the glTranslate() functions.
Ideally you will probably want to change your keyboard function so that it does not call glScale() at all, but stores how much should be scaled in some variable. Then, in your render loop, before drawing the triangle, call the translate and scale functions.
Off-topic: Immediate mode OpenGL is deprecated (that is, glBegin(); glEnd()). Take a look here for a modern OpenGL tutorial..
http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-1:-The-Graphics-Pipeline.html

If you want to proportionally scale the triangle, then use:
glScaled (0.5f ,0.5f ,0.5f);

Related

draw in animated opengl scene

i've a problem with drawing firework effect in animated scene when i clicked on mouse button. Why it don't drawing?
My Code:
#include<GL/glut.h>
struct Point {
GLint x;
GLint y;
};
Point p1, p2;
int ww=600,wh=400;
int xi,yi,xf,yf,y1b,x1b,y2b,x2b;
float px, py, t;
float x=0.,y=0.,x1=5.;
void update()
{
x+=0.01;
x1 -= 0.02;
if (x>6)
{
x -= 6;
x1 = 4;
}
}
There I create a function that draw firework effect on the basis of bezier curves. It will Okey if I draw on the static window.
// Bezier curve firework
void bezier(int xi, int yi, int xf, int yf)
{
// Coordinates for additional points of bezier curve
x1b = xi + rand()%15;
y1b = yi + rand()%5;
x2b = xf + rand()%15;
y2b = xf + rand()%5;
calculate and draw the curves
for (t=0.;t<=1.;t+=0.001)
{
px=(1-t)*(1-t)*(1-t)*xi+3*t*(1-t)*(1-t)*x1b+3*t*t*(1-t)*x2b+t*t*t*xf;
py=(1-t)*(1-t)*(1-t)*yi+3*t*(1-t)*(1-t)*y1b+3*t*t*(1-t)*y2b+t*t*t*yf;
glPointSize(2);
glBegin(GL_POINTS);
//glColor3f(1,0,0);
glVertex2d(px,py);
glEnd();
glFlush();
}
}
void initRendering()
{
glEnable(GL_DEPTH_TEST);
}
void reshaped(int w , int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (double)w/(double)h,1,200);
}
// If pressed ESC -> exit
void keyPressed(unsigned char k, int x, int y)
{
if(k==27)
{
exit(0);
}
}
Then, if I pressed mouse button it should call the function above and draw what I need. But nothing(
// If pressed mouse button -> draw firework effect
void mousePressed(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
xi=x;
yi=wh-y;
xf=x + 5.;
p1.x = xi; p1.y = yi;
p2.x = xf; p2.y = yi;
//drawLine(xi,yi,xf,yi);
bezier(xi, yi,xf, yi);
}
glutPostRedisplay();
}
There I create animated window. Two clouds move in gorizontal waves.
// Display a two moving clouds and the earth
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(x1,y,-5.0);
glBegin(GL_POLYGON);
glColor3f(1.,0.,0.5);
glVertex3f(-1.,1.,-5.);
glVertex3f(0.,2.,-5.);
glVertex3f(-2.,2.,-5.);
glVertex3f(1.,1.,-5.);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef(x,y,-5.);
glBegin(GL_POLYGON);
glColor3f(0.,0.5,0.5);
glVertex3f(1.,0.7,-5.);
glVertex3f(1.5,1.0,-5.0);
glVertex3f(0.7,1.5,-5.0);
glVertex3f(0.0,2.0,-5.0);
glVertex3f(-0.7,1.5,-5.0);
glVertex3f(-1.4,1.6,-5.0);
glVertex3f(-1.7,1.0,-5.0);
glVertex3f(-1.5,0.7,-5.0);
glVertex3f(-1.0,0.5,-5.0);
glEnd();
glPopMatrix();
glBegin(GL_POLYGON);
glColor3f(1.,1.,1.5);
glVertex3f(-2.,-2.,-5.);
glVertex3f(-2.0,-2.0,-5.0);
glVertex3f(-1.0,-1.5,-5.0);
//glVertex3f(0.0,0.0,-5.0);
glVertex3f(2.0,-2.0,-5.0);
glVertex3f(1.2,-1.5,-5.0);
glEnd();
update();
glutSwapBuffers();
glFlush();
}
void myinit()
{
glViewport(0,0,ww,wh);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char **argv)
{
// Initialization
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("Salute | Clouds");
initRendering();
// Registration
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshaped);
// Handler of
myinit();
glutKeyboardFunc(keyPressed);
glutMouseFunc(mousePressed);
// Main Loop
glutMainLoop();
return(0);
}
I think the problem is as follows:
I'm trying to draw my firework in an updated animated window. And every time I clicked on the screen, it is updated. And in the end, nothing is visible.
Actually the question:
How to make so that function glutMoseFunk would draw my salute in updated window?
While your scene is draw in perspective projection, the function bezier works with orthographic projection. This means you have to change the projection matrix befor you call bezier.
Further, do all the rendering in the main loop (display function). The event mousePressed should only be used to change parameters (set xi, yi, ...).
The display function may look like this:
int ww=400, wh=400;
void display()
{
// clear the frame buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// setup perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (double)ww/(double)wh,1,200);
// set model view matrix (identity matrix)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// draw scene
.....
// setup ortihgraphic projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
bezier(xi, yi,xf, yi);
update();
glutSwapBuffers();
glutPostRedisplay();
}
The reshaped function should set the viewport and notice the window size only:
void reshaped(int w , int h)
{
ww = w;
wh = h;
glViewport(0, 0, ww, wh);
}

Draw a rectangle with mouse in GLUT

I am fairly new to using GLUT, and I have been attempting to compile a program (which I found here, first response) that uses the mouse to draw a rectangle by recording the starting and ending points of a click-and-drag.
As a clean copy/paste, it will compile but not draw anything. It just displays a white screen, even after changing the background color to black (in the setup() function). I've read several sources to verify that this program doesn't miss anything in its draw and reshape functions, and it's all there.
I create a window, set the viewport to the window dimensions, and then use the gluOrtho2D function to set the mapping (since the window and viewport are the same dimensions, I set the mapping to the window dimensions). The mouse callback records where I left-click, and where I release left-click, then calls the glutPostRedisplay() function to redraw the window with the new coordinates. After a bit of debugging, I discovered the coordinates are recorded and saved appropriately, and are measured in pixels (x and y are integers between 0 and window dimension), so I should be able to draw a rectangle from one vertex to the other vertex using the coordinates. But, like I said, it only displays a white screen.
So, is there something wrong with the way I am drawing the rectangle? Am I mapping the window incorrectly? I am seriously lost, and any feedback would be greatly appreciated.
EDIT2: I changed the glutInitDisplayMode from GLUT_SINGLE to GLUT_DOUBLE, and that fixed the whole non-interactive white screen thing. Now it will draw a rectangle with the mouse with a flipped y-coordinate (which I fixed), and it works great now. Thank you very much for the suggestion.
Here is my program (EDIT1: added comments):
#include <cstdlib>
#include <GL/glut.h>
using namespace std;
GLsizei width, height;
struct Position
{
Position() : x(0), y(0) {}
float x;
float y;
};
Position start; // Records left-click location
Position finish; // Records left-click release location
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // clear window
glColor3ub(rand()%256, rand()%256, rand()%256); // generates random color
glBegin(GL_QUADS);
glVertex2f(start.x,start.y);
glVertex2f(finish.x,start.y);
glVertex2f(finish.x,finish.y);
glVertex2f(start.x,finish.y);
glEnd();
glutSwapBuffers(); // display newly drawn image in window
}
void reshape( int w, int h )
{
glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); // set to size of window
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, (float)w, 0.0, (float)h );
width = w; // records width globally
height = h; // records height globally
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(state==GLUT_DOWN)
{
start.x = x; //x1
start.y = y; //y1
}
if(state==GLUT_UP)
{
finish.x = x; //x2
finish.y = y; //y2
}
break;
glutPostRedisplay();
}
}
void motion( int x, int y )
{
finish.x = x;
finish.y = y;
glutPostRedisplay();
}
void setup()
{
glClearColor(0.0, 0.0, 0.0, 1.0); // *should* display black background
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,100);
glutCreateWindow("");
setup();
// initializing callbacks
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}
As my comment suggested:
change:
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
to:
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

How do you rotate an object in OpenGL a certain number of degrees? Is there a built-in command or do I have to use a formula?

How do you rotate an object in OpenGL a certain number of degrees? Is there a built-in command or do I have to use a formula? I've been stuck on this issue for days. Its a program that draws a shape under my mouse as it moves.
Say I have a drawing function:
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glColor3f ( 1, 1, 1 );
glBegin (toggle_type );
//Where cur_x and cur_y is the current mouse location that gets auto-updated
//ratiox is 0.7 and ratioy is 0.6
if (toggle_type==GL_QUADS) //rectangle from (-length, -length) to (length,length)
{
glVertex2f ( cur_x- length*ratiox, cur_y + length*ratioy );
glVertex2f ( cur_x+ length*ratiox, cur_y + length*ratioy );
glVertex2f ( cur_x+ length*ratiox, cur_y- length*ratioy );
glVertex2f ( cur_x- length*ratiox, cur_y- length*ratioy );
}
else if (toggle_type==GL_TRIANGLES)//triangle with vertices (-length, -length), (length, -length), (0, length).
{
glVertex2f ( cur_x- length, cur_y - length );
glVertex2f ( cur_x+length, cur_y - length );
glVertex2f ( cur_x, cur_y + length );
}
else if (toggle_type==GL_LINES) //line brush with vertices (0,-length), (0,length)
{
glVertex2f ( cur_x, cur_y - length );
glVertex2f ( cur_x, cur_y + length );
}
I can't just use glRotatef() before I use glBegin can I? I want to rotate the way it's drawn around my mouse a certain number of degrees. Is there not a built in function? What formula should I look into using if not?
You need to learn how to use OpenGL transforms: glTranslate, glRotate, and glScale.
Translate means "move stuff." Scale means "make stuff bigger or smaller." Rotate means what it sounds like it means.
With OpenGL transforms, it helps to think in terms of changing the coordinate system every time you issue a transform.
So to do this, let's saying you're drawing a box around the cursor. First translate to the position of the mouse cursor. That's where you want to do your drawing. Then rotate the coordinate system around the cursor, so you can draw a box easily without having to do funny stuff with sines and cosines and angles. Then, scale the object to whatever size you want it to be -- this shrinks or expands the coordinate system. Finally, just draw a one-unit-across box around the origin (0,0), and it will appear on screen in the location, rotation, and size you want.
If you try to rotate before you translate, you'll get incorrect results. The technical reason for this is that OpenGL post-multiplies transform matrices by vertex vectors.
And, yes, you should do all transforms outside of your begin/end block. Your begin/end block is just for specifying vertices, normals, etc.
I was just playing with freeglut to see if multi windows can work (seem it does!), and i was using rotations to see some change in display:
#include <cstdio>
#include <cassert>
#include <GL/freeglut.h>
#define DEGREES_X_SEC 10.0
int w_dc, w_ds;
float yRotationAngle;
void DrawSphere()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(yRotationAngle, .3f, .3f, .3f);
glutWireSphere(.3, 20, 20);
glFlush();
glutSwapBuffers();
}
void DrawCube()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(yRotationAngle, .2f, .2f, .2f);
glutWireCube(.5);
glFlush();
glutSwapBuffers();
}
void Idle()
{
static int previousTime = 0;
int currentTime = glutGet(GLUT_ELAPSED_TIME);
if (currentTime - previousTime > 10)
{
float x_frame = (DEGREES_X_SEC / 1000.0) * (currentTime - previousTime);
yRotationAngle += x_frame;
glutPostWindowRedisplay(w_dc);
glutPostWindowRedisplay(w_ds);
previousTime = currentTime;
}
}
// other code here....
int main(int argc, char *argv[])
{
// let glut eat any command line args that it owns
glutInit(&argc, argv);
// full color, double buffered
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(800, 600);
w_dc = make_window("cube", DrawCube);
glutPositionWindow(100, 100);
w_ds = make_window("sphere", DrawSphere);
glutPositionWindow(200, 200);
// not bound to any window
glutIdleFunc(Idle);
glutMainLoop();
return 0;
}
HTH, of course requires freeglut...
you need to focus an allegraic material like c 5 and m2, this is automatic rotation and will be instantly rewarded by the government because it shows abnormal behaviour, let me know if this helps.
Rog.

opengl regular polygon

i have the following code which draws nothing.
If i use glBegin(GL_POINTS) it draws a circle but with polygon mode it doesn't.
int WXSIZE=500,WYSIZE=500;
//Coordinate system
float Xmin=-8, Xmax=8, Ymin=-8, Ymax=8;
void setupmywindow()
{
glClearColor(0,0,0,0);
gluOrtho2D(Xmin, Xmax, Ymin, Ymax);
}
void mypolygon(float radius) //test object
{
glColor3f(1,0,0);
int numPoints=20;
float x,y;
float centerx,centery=0;
for (int i = 0; i < numPoints; i++)
{
x = centerx + radius * sin(2.0*PI*i/numPoints);
y = centery + radius * cos(2.0*PI*i/numPoints);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_POLYGON);
glVertex2f(x, y);
glEnd();
}
}
void myDisplay()
//single object
{
glClear(GL_COLOR_BUFFER_BIT);
mypolygon(2.0);
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(WXSIZE,WYSIZE);
glutCreateWindow("My graphic window");
setupmywindow();
glutDisplayFunc(myDisplay);
glutMainLoop();
}
Any suggestions?
EDIT----------------------
glBegin(GL_POLYGON);
for (int i = 0; i < numPoints; i++)
{
x = centerx + radius * sin(2.0*PI*i/numPoints);
y = centery + radius * cos(2.0*PI*i/numPoints);
glVertex2f(x, y);
}
glEnd();
I messed it with the loop.
In every loop you are drawing a polygon, that consists of a single vertex, so nothing. Just put the glBegin/glEnd (and the glPolygonMode) outside of the for loop and only draw glVertex in the loop. Of course it works with points, as a n times a single point is the same as n points. But n polygon consisting of one point each is not the same as one polygon consisting of n points.
Your polygon seems to be on the wrong side. By default, OpenGL only shows front faces, which need to be specified counterclockwise. You can:
Invert the order of your primitives (for (int i = numPoints-1; i >= 0 ; i--))
Invert the front face (glFrontFace(GL_CW))
Disable back face culling (glDisable(GL_CULL_FACE)).
When you call glBegin with GL_POLYGON, it is expecting I believe a minimum of three vertices. Standard drawing protocol is to draw using triangles, witch vertices in sets of three, since you need three vertices for each triangle face. You are only feeding it a single vertex, so you're not going to see anything. Try changing it to this:
glBegin(GL_TRIANGLES);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glEnd();

OpenGL: How can I move a 2d object without displacing the whole scene?

Alright, I'm trying to recreate the old classic, Missile Command, using OpenGL in C++. This is my first foray into OpenGL, although I feel fairly comfortable with C++ at this point.
I figured my first task was to figure out how to move 2d objects around the screen, seemed like it would be fairly simple. I created two quick method calls to make either triangles or quads:
void makeTriangle(color3f theColor, vertex2f &p1, vertex2f &p2, vertex2f &p3,
int &xOffset, int &yOffset)
{
//a triangle
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();
}
void makeQuad(color3f theColor, vertex2f &p1, vertex2f &p2, vertex2f &p3,
vertex2f &p4, int &xOffset, int &yOffset)
{
//a rectangle
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);
glVertex2f(p4.x, p4.y);
glEnd();
}
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;
}
A quad is defined as the "background" for the time being and consists of just a green rectangle along the bottom of the screen. The red triangle is the "object" that I wish to move. On a keypress, an offset is saved in the direction indicated.
I've tried using glTranslatef(xOffset,yOffset,0); but the problem with that is that it moves both elements on the screen and not just the red triangle. I attempted to put the whole call to draw the triangle between a 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, that destroys any changes that the translation was doing beforehand.
I've also tried just changing the values of the x and y coordinates before calling the draw, but that 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 has to be a nice simple way of doing this, and I'm just overlooking it. Could someone offer a suggestion please?
EDIT:
My actual problem was that I was never refreshing the screen after an initial draw. What I needed was to specify an idle function inside my main loop:
glutIdleFunc(IdleFunc);
Where the actual IdleFunc looks like:
GLvoid IdleFunc(GLvoid)
{
glutPostRedisplay();
}
Instead of using glFlush() inside my draw function, I should have been using glutSwapBuffers(). By doing that, the code I had first come up with:
p1.x += xOffset;
p2.x += xOffset;
p3.x += xOffset;
p1.y += yOffset;
p2.y += yOffset;
p3.y += yOffset;
Works fine for my purposes. I didn't have a need to translate the matrix, I just needed to draw the element in a different position from one scene to the next.
GL_MODELVIEW is what you need.
From the OpenGL FAQ, 2.1: http://www.opengl.org/resources/faq/technical/gettingstarted.htm
program_entrypoint
{
// Determine which depth or pixel format should be used.
// Create a window with the desired format.
// Create a rendering context and make it current with the window.
// Set up initial OpenGL state.
// Set up callback routines for window resize and window refresh.
}
handle_resize
{
glViewport(...);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set projection transform with glOrtho, glFrustum, gluOrtho2D, gluPerspective, etc.
}
handle_refresh
{
glClear(...);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set view transform with gluLookAt or equivalent
// For each object (i) in the scene that needs to be rendered:
// Push relevant stacks, e.g., glPushMatrix, glPushAttrib.
// Set OpenGL state specific to object (i).
// Set model transform for object (i) using glTranslatef, glScalef, glRotatef, and/or equivalent.
// Issue rendering commands for object (i).
// Pop relevant stacks, (e.g., glPopMatrix, glPopAttrib.)
// End for loop.
// Swap buffers.
}
You answer your own question, that is the solution:
glPushMatrix();
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();
glPopMatrix();
That will change the modelview matrix while the rectangle is drawn, then it will revert the modelview matrix back to what it were before. Did you actualy tried that? What whent wrong?
If I'm reading your code right, you want to only rotate one element right? If so, do this:
Call glPushMatrix();
then do your rotation
Store how much you've rotated
then draw your rotated item
then call glPopMatrix();
That will only rotate the one object.
EDIT:
I see that doing that "destroys" the previous rotation. Could you elaborate? That is the correct way to translate/rotate one object.
I also notice that you aren't initializing the Modelview Matrix. You should initialize the Modelview Matrix after you setup your PROJECTION matrix. You also need to make sure that you are initializing both matrices to the identity. And finally, make sure that you are initializing both matrices EVERY time the screen refreshes. To test this, set a breakpoint on your matrix initialization and see if it gets hit only once or every frame.