I'm creating a 2D tile based tactical rpg using OpenGL using C++ and I'm having difficulties with layering my tiles/quads. I want to to able to put say a tree textured quad, the image is of the tree with a surrounding transparent alpha layer, on top of an opaque grass textured quad. I need to have the tree appear on top of the grass with the grass showing through the alpha layer of the tree image.
So far I've been messing with glDisable(GL_DEPTH_TEST), glEnable(GL_BLEND), andglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) but with no luck so far. I end up with a tree on a black background, instead of the grass tile. Could someone point me in the right direction?
Below is my render function and initialize function which are probably most relevant.
void View::initialize() {
updateProjection(window);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
camera = new Camera(Vector3(-1, -3, 25), Vector3(-1, -3, 0), Vector3(0, 1, 0));
loadImages();
initShaders();
//needed for transparency?
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void View::render(World* worldTemp)
{
Matrix4 mvpMatrix, viewMatrix, modelMatrix;
Matrix4 XAxisRotationMatrix, YAxisRotationMatrix, ZAxisRotationMatrix;
input->handleInput(camera, worldTemp->getPlayer());
worldTemp->timerTick();
worldTemp->clearFog();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
XAxisRotationMatrix = Matrix4::IDENTITY;
YAxisRotationMatrix = Matrix4::IDENTITY;
ZAxisRotationMatrix = Matrix4::IDENTITY;
XAxisRotationMatrix.rotate(Vector3(1.0, 0.0, 0.0), XAxisRotationAngle);
YAxisRotationMatrix.rotate(Vector3(0.0, 1.0, 0.0), YAxisRotationAngle);
ZAxisRotationMatrix.rotate(Vector3(0.0, 0.0, 1.0), ZAxisRotationAngle);
viewMatrix = camera->getViewMatrix();
modelMatrix = translationMatrix(Vector3(-4, 2, 0));
mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;
//Spit out the map
for (int i = 0; i < 100; i++){
for (int j = 0; j < 100; j++){
for (int t = 0; t < 5; t++){
if (worldTemp->getTile(i, j)->isOccupied() == true) {
if (worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getFog()){
worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix, true);
}
else{
worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix);
}
}
}
}
}
//Place the player
worldTemp->getPlayer()->getEntityQuad()->render_self(mvpMatrix);
renderEnemies();
glutSwapBuffers(); //works with GL_DOUBLE. use glFlush(); instead, if using GL_SINGLE
}
Basically, in 2d games layering done via ordering of render calls. If you want layer A on top of layer B, you should render layer B first and then layer A.
blend function that you're using should depend on texture format of images. There are two common formats for alpha:
Pre-multiplied alpha
Straight alpha
More info about this: https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre
opengl es2 premultiplied vs straight alpha + blending
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); is for premultiplied alpha, and it should work well if you use colors as is. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); is for straight alpha.
Related
I want to draw tow circles with the same radii but exclude the overlapped area when drawing.
I want to draw or set dots on gray area.
I implement the mathematical aspect behind it and here is my code:
void draw_venn(){
float radian_to_degree_theta=2 * 3.14 / 360,
r = 0.5,
distance=0.3,
theta=0.0,
theta2=0.0,
xR=0.0,
yR=0.0,
xG=0.0,
yG=0.0,
sum_radii=0,
dis=0.0;
sum_radii=r+r;
for (r = 0.5; r >=0; r-=0.001)
{
for (float degree = 0; degree < 361; degree+=0.1)
{
theta =degree*radian_to_degree_theta;
xR=r*cos(theta)+distance;
yR=r*sin(theta);
xG=r*cos(theta)-distance;
yG=r*sin(theta);
dis=sqrt(pow(xR-xG,2) + pow(yR-yG,2));
if (dis <= sum_radii)
{
set_point(xR,yR,0.1,1,0,0);
set_point(xG,yG,0.1,0,1,0);
}
}
}
}
void set_point(float x,float y,float size,float R,float G,float B){
glPointSize(size);
glBegin (GL_POINTS);
glColor3f (R, G, B);
glVertex2f(x, y);
glEnd ();
}
void draw(void)
{
glClearColor (1, 1, 1, 0);
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix();
draw_ven();
glPopMatrix ();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(1400, 1400);
glutInitWindowPosition(700, 500);
glutCreateWindow("GL Sample");
glutDisplayFunc(draw);
glutMainLoop();
return 0;
}
and here is the result:
How can I find if a point is inside the overlapping area?
I reviewed and tested out your code. Trigonometry can get a bit tricky. Following is the "draw_venn" function with some refinements to produce an overlap effect.
void draw_venn()
{
float radian_to_degree_theta=2 * 3.141 / 360,
r = 0.5,
distance=0.3,
theta=0.0,
theta2 = 0.0,
xR=0.0,
yR=0.0,
xG=0.0,
yG=0.0,
dis=0.0;
glPointSize(1);
glColor3f(1,0,0);
glBegin(GL_POINTS);
for (r = 0.5; r >=0; r-=0.001)
{
for (float degree = 0; degree < 361; degree+=0.1)
{
theta =degree*radian_to_degree_theta;
theta2 = (180.0 - degree) * radian_to_degree_theta;
xR=r*cos(theta2)+distance;
yR=r*sin(theta2);
xG=r*cos(theta)-distance;
yG=r*sin(theta);
dis = sqrt(pow((distance - xG), 2) + pow(yG, 2));
if (dis < 0.5)
{
set_point(xR,yR,0.1,0,0,1); /* Color the overlap blue */
set_point(xG,yG,0.1,0,0,1); /* This works due to symmetry */
}
else
{
set_point(xR,yR,0.1,1,0,0); /* Set the symmetrical circle colors */
set_point(xG,yG,0.1,0,1,0);
}
}
}
glEnd();
}
Pointing out the two significant revisions, first I derive a mirror image value for "theta" and place that into variable "theta2". That is used to draw the red circle. This assures that the circle images are being built in equal but opposite directions so that the coordinates are symmetrical. Second, I revised the formula for checking if the green image coordinates fall within the red circle's outermost radius. Using the Pythagorean theorem calculation for the hypotenuse, the formula determines if the hypotenuse value is smaller than the outermost radius length (0.5). If it is smaller make that point for the green circle blue, and since the circle points are being built and colored symmetrically, also make the corresponding point for the red circle blue.
The result of those revisions is a Venn Diagram showing an overlap.
I hope that helps and gives you a springboard to proceed.
Regards.
Add 8bit Stencil Buffer to your context
I do it by setting up pixelformat like this:
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof( pfd ) ); // set the pixel format for the DC
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
Enable and Clear Stencil with 0 and setup it for incrementation
Disable color and depth output
Render circles
Enable color and depth output
Set up Stencil test to not equal 2
You can also use equal to 1 in case you overlap more than just 2 objects
Render circles
Disable Stencil test
I see it like this:
//---------------------------------------------------------------------------
void glCircle(float x,float y,float r)
{
int e;
float a,da=2.0*M_PI/72.0;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x,y);
for (e=1,a=0.0;e;a+=da)
{
if (a>=2.0*M_PI) { e=0; a=0.0; }
glVertex2f(x+(r*sin(a)),y+(r*cos(a)));
}
glEnd();
}
//---------------------------------------------------------------------------
void gl_draw()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
float aspect=float(xs)/float(ys); //xs,ys is screen resolution
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0,aspect,1.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// turn off color,depth
glStencilMask(0xFF);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
// clear stencil and setup it for increment
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS,1,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
// render stencil
glCircle(-0.3,0.0,0.6);
glCircle(+0.3,0.0,0.6);
// turn on color,depth
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
// render screen (where Stencil is not 2)
glStencilFunc(GL_NOTEQUAL,2,0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glColor3f(1.0,0.0,0.0); glCircle(-0.3,0.0,0.6);
glColor3f(0.0,1.0,0.0); glCircle(+0.3,0.0,0.6);
glDisable(GL_STENCIL_TEST);
glFlush();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
And output:
In case you also want to know if pixel is inside both circles you can use:
GLint a;
glReadPixels(X,ys-1-Y,1,1,GL_STENCIL_INDEX,GL_INT,&a);
if (a==2); // X,Y is inside both circles
else; // X,Y is not inside both circles
In case You insist on rendering the stuff pixel by pixel then do it at least properly As your current approach is horibly slow for many reasons... For example you can do this like this:
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glTranslatef(-1.0,-1.0,0.0);
glScalef(2.0/xs,2.0/ys,1.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
int x0=(4*xs)/10,y0=ys/2,r0=xs/4; // circle0
int x1=(6*xs)/10,y1=ys/2,r1=xs/4; // circle1
int x,y,xx0,xx1,yy0,yy1,rr0=r0*r0,rr1=r1*r1;
glBegin(GL_POINTS);
glColor3f(1.0,0.0,0.0);
for (x=-r0;x<=r0;x++){ xx0=x; xx0*=xx0; xx1=x+x0-x1; xx1*=xx1;
for (y=-r0;y<=r0;y++){ yy0=y; yy0*=yy0; yy1=y+y0-y1; yy1*=yy1;
if (xx0+yy0<=rr0)
if (xx1+yy1>=rr1)
glVertex2i(x0+x,y0+y); }}
glColor3f(0.0,1.0,0.0);
for (x=-r1;x<=r1;x++){ xx1=x; xx1*=xx1; xx0=x+x1-x0; xx0*=xx0;
for (y=-r1;y<=r1;y++){ yy1=y; yy1*=yy1; yy0=y+y1-y0; yy0*=yy0;
if (xx1+yy1<=rr1)
if (xx0+yy0>=rr0)
glVertex2i(x1+x,y1+y); }}
glEnd();
glFlush();
SwapBuffers(hdc);
Where xs,ys is GL screen resolution.
See related:
I have an OpenGL Tessellated Sphere and I want to cut a cylindrical hole in it
OpenGL 3D-raypicking with high poly meshes
Is there a more efficient way of texturing a circle?
Need to get global absolute scale of object to display it with OpenGL.
When I just multiply scale vectors of parents and children, I get absolute scale for world axes space. When I rotate object, it scales along global axes, not local.
I decided that I need to rotate scale vector too. But:
When I am trying to rotate it with direction vector - it values sometimes are going to 0, and scale too.
{ scale.x * forward.x , scale.y * forward.y , scale.z * forward.z }
When I am trying to rotate it with glm::rotate, it makes unexpected results, like infinite rotating/scaling, wrench and other effects on meshes.
auto globalScale = glm::vec3(scale.x, scale.y, scale.z);
globalScale = glm::rotate(globalScale, rotation.x, {1,0,0});
globalScale = glm::rotate(globalScale, rotation.y, {0,1,0});
globalScale = glm::rotate(globalScale, rotation.z, {0,0,1});
My rendering code:
void Render(Material *mat, Transform* tr){
glEnable(GL_COLOR_MATERIAL);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
// Get object transformations
Vector3 pos = tr->globalPosition();
Vector3 rot = tr->globalRotation();
Vector3 scale = (tr->globalScale());
auto globalScale = glm::vec3(scale.x, scale.y, scale.z);
// First, scaling, then rotating, then translating in world space
// ( Initially all objects rendering starts at (0,0,0) )
glScaled(globalScale.x, globalScale.y, globalScale.z);
glRotatef(rot.x, 1.0, 0.0, 0.0);
glRotatef(rot.y, 0.0, 1.0, 0.0);
glRotatef(rot.z, 0.0, 0.0, 1.0);
glTranslated(pos.x, pos.y, pos.z);
// Rendering
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3,GL_FLOAT,0,vertexArray);
glNormalPointer(GL_FLOAT,0,normalArray);
glClientActiveTexture(GL_TEXTURE0_ARB);
glTexCoordPointer(2,GL_FLOAT,0,uvArray);
glDrawArrays(GL_TRIANGLES,0,numVerts);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// Rolling transformations back
glTranslated(-pos.x, -pos.y, -pos.z);
glRotated(-rot.z, 0.0, 0.0, 1.0);
glRotated(-rot.y, 0.0, 1.0, 0.0);
glRotated(-rot.x, 1.0, 0.0, 0.0);
glScaled(1/globalScale.x, 1/globalScale.y, 1/globalScale.z);
}
Rendering call:
void RenderObject(GameObject* go){
for(auto goc : go->children)
goc->Update<MeshRenderer>();//RenderObject(goc);
}
void RenderScene(){
auto scene = EditorInstance::GetSingleton()->currentScene;
for(auto go : scene->hierarchy){
RenderObject(go);
if(auto mr = (go->GetComponent<Camera>())){
mr->Update();
}
}
}
... render->setOnRender(RenderScene); ...
Main rendering method:
int render()
{
#ifdef EDITOR
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
DrawGrid(100);
#else
if(NukeOGL::getSingleton() != this){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
}
#endif
//glClearColor(0, 0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
gluLookAt(transform->position.x,
transform->position.y,
transform->position.z,
transform->position.x + transform->direction().x,
transform->position.y + transform->direction().y,
transform->position.z + transform->direction().z,
0.0,
1.0,
0.0);
if(_onRender.size() > 0)
for(auto _rn : _onRender){
_rn();
}
#ifdef EDITOR
glPopAttrib(); // Restore our glEnable and glViewport states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture
#else
if(NukeOGL::getSingleton() != this){
glPopAttrib(); // Restore our glEnable and glViewport states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture
}
#endif
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(_onGUI.size() > 0)
for(auto _rn : _onGUI){
_rn();
}
glutSwapBuffers();
//glutPostRedisplay();
return 0;
}
What I am doing wrong? What I should do to make it right scale from local to world space?
Scale and rotation are linear transformations, their effects are relative to distance to origin of coordinates system. You must apply them in a proper order and with a proper origin each.
I explain in 2D so it's easier to understand.
Say you have a rectangle of size axb, whose center is at {cx,cy} and you want to scale and rotate (in this order). Then you first translate to {0,0} then scale, then rotate, then translate it back to {cx,cy}. Since each transformation is defined by a matrix, and usually OpenGL matrices are defined in column-mayor order, the composed matrix for this object may be:
MObj_i = MObj_i_trans(cx,cy) * MObj_i_rot(cangle, caxis) * MObj_i_sca(cfactor) * MObj_i_trans(-cx,-cy)
After you do those transformations for each object (with its own center/scale/rotation each) you want a "global" scale and rotation. Again you need a center of scale/rotation:
MGlobal = MGlo_trans(gx,gy) * MGlo_rot(gangle, gaxis) * MGlo_sca(gfactor) * MGlo_trans(-gx,-gy)
Usually the world center is `{0,0}' so you can avoid translations:
MGlobal = MGlo_rot(gangle, gaxis) * MGlo_sca(gfactor)
The good news is that the transformations can be combined into an only matrix. So, for each object, you apply the matrix:
MObjec_i = MGlobal * MObj_i
If you use glm for these maths, don't forget to inializate an Identity matrix:
glm::mat4 objScale(1.0);
objScale(objScale, vec3(fx, fy, fz));
glm::mat4 objRotate(1.0);
objRotate(objRotate, angle, vec3(axis.x, axis.y, axis.z));
etc.
I am writing an application that displays .jpg files that are stored as Texture2D (RGB) in OpenGL. I want to smoothly change from one texture2D to the next by fading to black, then fading into the next texture.
After looking for some explanation I wrote something like this.
void renderTexture()
{
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mTexture);
gluSphere(mQuad, 1.0f, 50, 50);
glBindTexture(GL_TEXTURE_2D, 0);
}
void fadeToBlack()
{
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
for (GLfloat alpha = 1.0; alpha > 0.0; alpha -= 0.05)
{
glColor4f(0.0, 0.0, 0.0, alpha);
renderTexture();
glFlush();
glutSwapBuffers();
}
glDisable(GL_BLEND);
}
Unfortunately, this does not fade to black but instead switches to black immediately. I must have some misunderstanding on how GL_BLEND is working here. Can somebody please point out what I am doing wrong?
** EDIT: This did the trick. Thanks a lot j-p and Benjamin for the pointers **
void fadeToBlack()
{
for (GLfloat alpha = 1.0; alpha > 0.0; alpha -= 0.001)
{
renderTexture();
glColor4f(alpha, alpha, alpha, alpha);
glFlush();
glutSwapBuffers();
}
glColor4f(1.0, 1.0, 1.0, 1.0);
}
The for loop will be executing so quickly that the texture changes will appear to happen instantly.
I'm using FLTK 1.3 as base for OpenGL window context creation (Fl_Gl_Window), etc. on Mac OS X 10.9.
The goal is to create some grid with simple primitives on it. I've done some easy stuff with OpenGL in 2D before, but now i'm lost. All rendered as good, as it need to, except edges. They are all so, uhmmm... Edgy, you know.
It's obvious that this objects need some anti-aliasing in any form. Will it be simple vendor-implementation-specific smooth AA or full Multisampling. Problem is i can't turn it on in FLTK. Can't for triangles, but can for lines.
So far, i tried glEnable(GL_POLYGON_SMOOTH), multisampling on window (seems not working), different blending funcs, changing shader models.
Maybe it is because of triangle fan structure of objects? Please help me and thanks to you!
Code used for object:
float object_width = 100;
float object_height = 50;
float object_x = 250;
float object_y = 100;
glColor3f(0, 0, 1);
glBegin(GL_TRIANGLE_FAN);
for(int i = 0; i < 30; i++)
glVertex2f(object_x + (object_width / 2) * cosf(i * 12 * DEG2RAD), object_y + (object_height / 2) * sinf(i * 12 * DEG2RAD));
glEnd();
Code on window creation (just mode setting):
mode(FL_RGB | FL_ALPHA | FL_DOUBLE);
Code used on init:
glClearColor(0.9, 0.9, 0.9, 1);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Colored output, but not smooth
//glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE_MINUS_SRC_ALPHA); // All drawn black, no smooth
//glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); // All drawn black, no smooth either
glEnable(GL_BLEND);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH); // not working???
On different blending modes than GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA getting this picture:
I am attempting to make a simple drawing using openGL. However, the depth buffer doesn't appear to be working.
Other people with a similar problem are typically doing one of two things wrong:
Not including glEnable(GL_DEPTH_TEST)
Bad clipping values
However, my code does not have either of these problems.
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluPerspective(25.0,1.0,10.0,200.0);
// Set the camera location
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(20.0, 10.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Cull backfacing polygons
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE)
drawCoordinateAxis();
drawBox(5.0,2.0,5.0,0.8,0.0,0.0);
glTranslated(1.0,-1.0,1.0); //The box is 5x2x5, it is shifted 1 unit down and 1 in the x and z directions
drawBox(5.0,2.0,5.0,0.0,1.0,1.0);
...
When I execute my code, this is drawn. http://imgur.com/G9y41O1
Note that the blue box and the red box collide, so the red box should be covering part of the blue box.
The functions drawCoordinateAxis() and drawBox() just draw a few primitives, nothing fancy inside.
I am running this on Debian squeeze.
void reshape(GLint width, GLint height)
{
g_Width = width;
g_Height = height;
glViewport(0, 0, g_Width, g_Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
glMatrixMode(GL_MODELVIEW);
}
So set Matrix Mode to GL_PROJECTION first, then gluPerspective.... and then back to MODELVIEW mode.