Related
I need to draw a cube to indicate coordinate in OpenGL 3.3 core profile.It works fine without glutInitContextVersion (3, 3); but it becomes totally black when glutInitContextVersion (3, 3); applied.
Here is the drawing code.
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
Here is the code in main function:
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); // Enable double buffered mode
glutInitContextVersion (3, 3);
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
initGL(); // Our own OpenGL initialization
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}
How to draw a cube in OpenGL 3.3 core profile?
glBegin and friends are deprecated and removed from the newer versions (3.2 onward).
Instead you need to upload the vertex data to Vertex Buffer Objects. Then use glVertexAttribPointer to tell openGL how the data is laid out.
Besides that you need to write shaders.
Fixed function pipeline (glVertex, glBegin etc.) does not exist in Core Profile.
So I'm pretty new to openGL programming and am just going over the basics for now. I know I should be using VBOs and stuff but wanted to get a little foundation first. I wont present you with all the code just the stuff that draws and sets the scene.
Heres a little code for setting up my camera:
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, width / height, 1, 1000);
glEnable(GL_DEPTH_TEST);
// Move the camera back to view the scene
glTranslatef(0.0f, 0.0f, -5.0f);
I tried to create it around the origin like so (also I never draw the bottom face) :
void drawtetrahedron(GLfloat angle)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); //FRONT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //RIGHT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //LEFT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(0.0f, -1.0f, -1.0f);
glEnd();
}
When my window first comes up the red triangle looks fine, but as I rotate it the shape looks a little distorted. If I rotate all the way around (where I cant see the red face at all) it looks normal... What am I missing here?
Heres where it starts to look weird
Also any pointers on openGL stuff I'm doing incorrectly (or in general) are greatly appreciated! :D
I don't know if this is what you consider a wierd looking shape, but your shape doesn't seem to be a regular Tetrahedron:
The 3 Corners of the base don't have the same distance to the top corner (the two front corners have a distance of sqrt(6) to the top corner, while the back corner has a distance of sqrt(5)).
the distance on the base is off too: the front corners have a distance of sqrt(2) while the distance between any front corner and the back corner is sqrt(3).
An example for a regular tetrahedron would be:
(Please note that these coordinates don't have a base parallel to the xz plane)
(1,1,1)(1,-1,-1)(-1,1,-1)(-1,-1,1)
Your code itself looks to be ok. (Except for the translating the projection matrix) I, myself prefer to create code blocks after push/popmatrix and glbegin/end (these things { ... }), but that's just to keep my code easy to read.
Also, as a general rule of thumb, in opengl you don't move the camera: you move everything else. (That's why translating negative z moves objects away from you, translating positive x makes them move right and so on...)
I'm a complete beginner with OpenGL, just trying to learn (starting with freeglut for the moment). So far I have the following code that should draw some basic 3D objects. The problem is that whatever I put in the render function (although it does execute), it only displays a blank window.
#include "stdafx.h"
#include <iostream>
#include "dependente\glew\glew.h"
#include "dependente\freeglut\glut.h"
void render()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glTranslatef(-1.5f, 1.0f, -6.0f); // Translate back and to the left
glPushMatrix(); // Push the current modelview matrix on the matrix // Rotate on all 3 axis
glBegin(GL_TRIANGLES); // Draw a pyramid
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top of front face
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f); // Left of front face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f); // Right of front face
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top of right face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f); // Left of right face
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f); // Right of right face
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top of back face
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f); // Left of back face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f); // Right of back face
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f); // Top of left face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f); // Left of left face
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f); // Right of left face
glEnd();
// Render a quad for the bottom of our pyramid
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f); // Left/right of front/left face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f); // Right/left of front/right face
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f); // Right/left of right/back face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f); // Left/right of right/back face
glEnd();
glPopMatrix();
glTranslatef(3.0f, 0.0f, 0.0f); // Translate right
glPushMatrix(); // Push the current modelview matrix on the matrix stack // Rotate the primitive on all 3 axis
glBegin(GL_QUADS);
// Top face
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, 1.0f, -1.0f); // Top-right of top face
glVertex3f(-1.0f, 1.0f, -1.0f); // Top-left of top face
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom-left of top face
glVertex3f(1.0f, 1.0f, 1.0f); // Bottom-right of top face
// Bottom face
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f(1.0f, -1.0f, -1.0f); // Top-right of bottom face
glVertex3f(-1.0f, -1.0f, -1.0f); // Top-left of bottom face
glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom-left of bottom face
glVertex3f(1.0f, -1.0f, 1.0f); // Bottom-right of bottom face
// Front face
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(1.0f, 1.0f, 1.0f); // Top-Right of front face
glVertex3f(-1.0f, 1.0f, 1.0f); // Top-left of front face
glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom-left of front face
glVertex3f(1.0f, -1.0f, 1.0f); // Bottom-right of front face
// Back face
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f(1.0f, -1.0f, -1.0f); // Bottom-Left of back face
glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom-Right of back face
glVertex3f(-1.0f, 1.0f, -1.0f); // Top-Right of back face
glVertex3f(1.0f, 1.0f, -1.0f); // Top-Left of back face
// Left face
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f); // Top-Right of left face
glVertex3f(-1.0f, 1.0f, -1.0f); // Top-Left of left face
glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom-Left of left face
glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom-Right of left face
// Right face
glColor3f(1.0f, 0.0f, 1.0f); // Violet
glVertex3f(1.0f, 1.0f, 1.0f); // Top-Right of left face
glVertex3f(1.0f, 1.0f, -1.0f); // Top-Left of left face
glVertex3f(1.0f, -1.0f, -1.0f); // Bottom-Left of left face
glVertex3f(1.0f, -1.0f, 1.0f); // Bottom-Right of left face
glEnd();
glPopMatrix();
glTranslatef(-1.5f, -3.0f, 0.0f); // Back to center and lower screen
glPushMatrix();
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glutSolidSphere(1.0f, 16, 16); // Use GLUT to draw a solid sphere
glScalef(1.01f, 1.01f, 1.01f);
glColor3f(1.0f, 0.0f, 0.0f); // Red
glutWireSphere(1.0f, 16, 16); // Use GLUT to draw a wireframe sphere
glPopMatrix();
}
void initGlut(int argc, char* argv[]) {
std::cout << "Initialise OpenGL..." << std::endl;
glutInit(&argc, argv);
int iScreenWidth = glutGet(GLUT_SCREEN_WIDTH);
int iScreenHeight = glutGet(GLUT_SCREEN_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(120, 120);
glutInitWindowSize(600, 600);
glutCreateWindow("OpenGL");
// Register GLUT callbacks
glutDisplayFunc(render);
// Setup initial GL State
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClearDepth(1.0f);
glShadeModel(GL_SMOOTH);
glutMainLoop();
std::cout << "Initialise OpenGL: Success!" << std::endl;
}
int _tmain(int argc, char* argv[])
{
initGlut(argc, argv);
return 0;
}
Hopefully someone with more experience will let me know what obvious thing I'm missing.
Here's how I go about debugging the problem "OpenGL isn't drawing anything":
Add this code to the start of my render() function: glClearColor (1, 1, 0, 1); glClear (GL_COLOR_BUFFER_BIT); If the output turns yellow, it's calling your render() function and clearing the output properly. You can then remove that code or comment it out. If the output doesn't turn yellow, then either your render() function isn't getting called or it is, but your OpenGL state is set up not to draw to the screen. (Perhaps the wrong context is current at the time, or the color attachment for the current FBO isn't what you think it is.)
Attempt to draw a single white triangle, with no textures or shaders, centered at the origin. If it shows up, then the other geometry you're trying to draw could be wrong. If it doesn't show up, the problem could be your matrix calculations (projection or modelview matrix). (Are you pointing the "camera" where you think you are? Are your objects being drawn where you think?) It could also be lighting, blending, or depth testing. I turn all of those off for this sort of test just to be sure. (See glEnable()/glDisable() for how to turn them on and off.)
If that stuff works, I start turning on the things that I turned off above: texturing, shaders, lighting, blending, depth testing. I turn them on one at a time until something goes wrong.
If nothing goes wrong, then probably the geometry for my objects is wrong.
Aha! It seems my problem was that my zNear value given to gluPerspective had to be greater than 0, and I had to enable the depth buffer to get it working. Ive updated the code below to be working.
I've tried to do this a lot, and always thought I was defining my quad vertices in the wrong order, but now, I know its something else.
I've tried enabling Culling, changing frontFace to clockwise, disabling Blending, adding normals, but I always get a cube that looks like this;
Hopefully, you won't even have to look at my code to know what the problem is, as it wasn't too hard to get it like this.
If you don't immediately know what the problem is, here's the code used to set up and draw the cube.
// FIXED CODE.
// reshape, called on init, and window resize
void reshape(int w, int h) {
scrw=w;
scrh=h;
glClearColor(0.8,0.8,0.8,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(cfov,(float) scrw/ (float) scrh,1,1000); // this is also a part of the fix.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST); // this is a part of the fix
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glViewport(0,0,scrw,scrh);
}
// drawQuadCube(), called every frame.
void drawQuadCube() {
glPushMatrix();
glTranslated(0.5,0.5,0.5);
glRotated(xangle,0,1,0);
glRotated(yangle,1,0,0);
glRotated(zangle,0,0,1);
glTranslated(-0.5,-0.5,-0.5);
glBegin(GL_QUADS);
// bottom
glColor4ub(30,30,255,255);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
// top
glColor4ub(40,40,255,255);
glVertex3f(0.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// left
glColor4ub(60,60,255,255);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 1.0f);
// right
glColor4ub(60,60,200,255);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
// near
glColor4ub(70,70,100,255);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// far
glColor4ub(20,20,90,255);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 1.0f, 1.0f);
glNormal3f(0,0,0);
glNormal3f(0,0,1);
glNormal3f(0,1,0);
glNormal3f(1,0,0);
glNormal3f(1,0,1);
glNormal3f(1,1,0);
glNormal3f(1,1,1);
glNormal3f(0,1,1);
glEnd();
glPopMatrix();
}
// if that isn't enough, this is the function used to set up the view.
void setView(void) {
glLoadIdentity();
gluLookAt(0.5,0.5,-5,0.5,0.5,0.5,0,1,0);
}
Your winding mode is incorrect.
glFrontFace defaults to GL_CCW, but your "front-facing quad", in this example the "near" one, is wound clockwise (from the frame of reference of your camera position; note that it's at negative Z, and looking along positive Z). glCullFace defaults to GL_BACK, so it's getting culled. Set it correctly with:
glFrontFace(GL_CW);
See also http://www.opengl.org/sdk/docs/man/xhtml/glFrontFace.xml
Once you've got that setup, then you'll want to enable depth-buffering, so your quads overpaint correctly without relying on paint ordering. See: http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm
Try:
glCullFace(GL_FRONT);
See http://www.opengl.org/sdk/docs/man/xhtml/glCullFace.xml
or:
glEnable(GL_CULL_FACE);
See http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml
You didn't specify what windowing mechanism you were using but incase you are using glut, don't forget to set the GLUT_DEPTH flag while creating the window. Thats a simple common error frequently overlooked.
I want to be able to render something into a texture, on OpenGL, so I can further use it whenever I want, without rendering everything over again. This website here gave me the guidelines to do it, without using the FrameBuffer. I don't want to do it with the FrameBuffer Object due to compatibility issues, since this old machine is not supporting it. I have done some code, which creates my texture, renders my scene, and I then create a Quad to render the texture on it. The only problem is that the texture is being rendered like an "Alpha Mask", it means, looks like it's only taking into account the Alpha Value, maintaining my rectangle always with the same color, but just changing the transparency on pixels. Here is some code I've done so far:
void CreateTexture ()
{
xSize = 512;
ySize = 512; //size of texture
//new array
char* colorBits = new char[ xSize * ySize * 3 ];
//texture creation..
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0 ,3 , xSize,
ySize, 0 , GL_RGB,
GL_UNSIGNED_BYTE, colorBits);
//you can set other texture parameters if you want
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//clean up
delete[] colorBits;
}
Then:
int viewport[4];
glGetIntegerv(GL_VIEWPORT,(int*)viewport);
glViewport(0,0,xSize,ySize);
DrawScene(hDC);
//save data to texture using glCopyTexImage2D
glBindTexture(GL_TEXTURE_2D,texture);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
0,0, xSize, ySize, 0);
glClearColor(.0f, 0.5f, 0.5f, 1.0f); // Set The Clear Color To Medium Blue
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
// glBindTexture(GL_TEXTURE_2D,texture);
And Finally:
glEnable(GL_TEXTURE_2D); // Enable 2D Texture Mapping
glBlendFunc(GL_DST_COLOR,GL_ONE); // Set Blending Mode
glEnable(GL_BLEND);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D,texture);
glRotatef(theta, 0.0f, 0.0f, 0.01f);
glBegin(GL_QUADS);
//Front Face
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.5, -0.5f, 0.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glEnd();
SwapBuffers(hDC);
The DrawScene() function simply renders a rectangle with a triangle on top of it, with each vertice having different colors.. nothing special.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT );//| GL_DEPTH_BUFFER_BIT);
glPushMatrix();
// glRotatef(theta, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(0.87f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(-0.87f, -0.5f);
glEnd();
glPopMatrix();
I've found something on nVidia website which looks useful, for someone who cannot also do offscreen rendering with FBO:
http://developer.download.nvidia.com/SDK/9.5/Samples/samples.html
This website contains one project called "Simple P-Buffer", which basically contains an implementation of a P-buffer. The idea of the sample is that you make context switching to the pBuffer, while you want to draw pixels on offscreen mode, let's say. After drawing your scene with the normal rendering functions, we use glReadPixels to read the data from the pBuffer into an array of unsigned bytes (GLubyte). After that, we do context-switching once again, setting it back to the screen context, so that you can use glReadPixels to read the content from our array.
The method before FBOs were available was to use an alternate render buffer (see glDrawBuffer(GL_AUX0), then copy pixels from that buffer (see glReadBuffer) to the texture (see glCopyTexImage2D. Rendering directly into a texture requires FBOs.