Hi,
The problem I’m having is not with drawing into the back buffer–it’s with setting the viewing position. Do I have to reverse the transformations that I perform on the model and the view?
In the code below, the sphere is translated one unit in the positive y direction. Do I need to undo this transformation when drawing into the back buffer?
In the code below, the hit test doesn’t work properly for the left-hand subwindow. If I reverse the translation that takes place in the drawScene funtion then it works properly.
I’ve included the full code below.
Cheers,
Chris
#include <GL/openglut.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>
//********************************************************************\\
#define WINDOW_WIDTH 1000
#define WINDOW_HEIGHT 500
#define BORDER 5
//********************************************************************\\
void init(void);
void renderMain(void);
void renderIdle(void);
void renderSW01(void);
void renderSW02(void);
void drawScene(int window);
void reshape(int w, int h);
void resetProjMat(int w1, int h1);
void mouseSW01(int button, int state, int x, int y);
void mouseSW02(int button, int state, int x, int y);
int main(int argc, char** argv);
//********************************************************************\\
GLint gMainWindow;
GLint gSubWindow01;
GLint gSubWindow02;
static GLfloat gRotate = 0.0;
GLint w;
GLint h;
GLint gHit = FALSE;
//********************************************************************\\
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glEnable(GL_COLOR_MATERIAL );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
//********************************************************************\\
void renderMain(void)
{
glutSetWindow(gMainWindow);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSwapBuffers();
}
//********************************************************************\\
void renderIdle(void)
{
renderSW01();
renderSW02();
}
//********************************************************************\\
void renderSW01(void)
{
glutSetWindow(gSubWindow01);
glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
drawScene(gSubWindow01);
}
//********************************************************************\\
void renderSW02(void)
{
glutSetWindow(gSubWindow02);
glLoadIdentity();
gluLookAt(0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
drawScene(gSubWindow02);
}
//********************************************************************\\
void drawScene(int window)
{
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(gHit == TRUE)
glColor3f(1.0, 0.0, 0.0);
else
glColor3f(0.5, 1.0, 1.0);
glPushMatrix();
glTranslatef(0.0, 1.0, 0.0);
glRotatef(gRotate, 0.0f, 1.0f, 0.0f);
glutWireSphere(1.0, 32, 32);
glPopMatrix();
glColor3f(0.5, 0.5, 0.5);
glBegin(GL_QUADS);
glVertex3i(-10, 0, 10);
glVertex3i(10, 0, 10);
glVertex3i(10, 0, -10);
glVertex3i(-10, 0, -10);
glEnd();
glColor3f(0.7f, 0.7f, 0.7f);
glBegin(GL_LINES);
for(i = -10; i < 11; i+=2)
{
glVertex3f((GLfloat)i, 0.01f, -10.0);
glVertex3f((GLfloat)i, 0.01f, 10.0);
glVertex3f(-10.0, 0.01f, (GLfloat)i);
glVertex3f(10.0, 0.01f, (GLfloat)i);
}
glEnd();
glutSwapBuffers();
gRotate += 1.0;
}
//********************************************************************\\
void reshape(int w1, int h1)
{
if(h1 == 0)
h1 = 1;
w = w1;
h = h1;
glutSetWindow(gSubWindow01);
glutPositionWindow(BORDER, BORDER);
glutReshapeWindow((w - (3 * BORDER)) / 2, h - (2 * BORDER));
resetProjMat((w - (3 * BORDER)) / 2, h - (2 * BORDER));
glutSetWindow(gSubWindow02);
glutPositionWindow((2 * BORDER) + ((w - (3 * BORDER)) / 2), BORDER);
glutReshapeWindow((w - (3 * BORDER)) / 2, h - (2 * BORDER));
resetProjMat((w - (3 * BORDER)) / 2, h - (2 * BORDER));
}
//********************************************************************\\
void resetProjMat(int w1, int h1)
{
GLfloat ratio;
ratio = 1.0f * w1 / h1;
// Reset the coordinate system before modifying.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window.
glViewport(0, 0, w1, h1);
// Set the clipping volume.
gluPerspective(45, ratio, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
}
//********************************************************************\\
void mouseSW01(int button, int state, int x, int y)
{
GLfloat pixel[4]; // An RGBA pixel.
GLint value;
if(state == GLUT_DOWN)
{
printf("In subwindow 01
");
glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawBuffer(GL_BACK);
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glTranslatef(0.0, 1.0, 0.0);
glRotatef(gRotate, 0.0f, 1.0f, 0.0f);
glutSolidSphere(1.0, 32, 32);
glPopMatrix();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_QUADS);
glVertex3i(-10, 0, 10);
glVertex3i(10, 0, 10);
glVertex3i(10, 0, -10);
glVertex3i(-10, 0, -10);
glEnd();
glReadBuffer(GL_BACK);
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, pixel);
printf("R: %f G: %f B: %f
", pixel[0], pixel[1], pixel[2]);
value = (GLint)pixel[0];
if(value == 1)
{
printf("Hit!
");
gHit = TRUE;
}
else
{
printf("Miss!
");
gHit = FALSE;
}
}
}
//********************************************************************\\
void mouseSW02(int button, int state, int x, int y)
{
GLfloat pixel[4]; // An RGBA pixel.
GLint value;
if(state == GLUT_DOWN)
{
printf("In subwindow 02
");
glLoadIdentity();
gluLookAt(0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawBuffer(GL_BACK);
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glTranslatef(0.0, 1.0, 0.0);
glRotatef(gRotate, 0.0f, 1.0f, 0.0f);
glutSolidSphere(1.0, 32, 32);
glPopMatrix();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_QUADS);
glVertex3i(-10, 0, 10);
glVertex3i(10, 0, 10);
glVertex3i(10, 0, -10);
glVertex3i(-10, 0, -10);
glEnd();
glReadBuffer(GL_BACK);
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, pixel);
printf("R: %f G: %f B: %f
", pixel[0], pixel[1], pixel[2]);
value = (GLint)pixel[0];
if(value == 1)
{
printf("Hit!
");
gHit = TRUE;
}
else
{
printf("Miss!
");
gHit = FALSE;
}
}
}
//********************************************************************\\
int main(int argc, char** argv)
{
int subWindowWidth = (WINDOW_WIDTH - (3 * BORDER)) / 2;
int subWindowHeight = WINDOW_HEIGHT - (2 * BORDER);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitWindowPosition(100, 100);
gMainWindow = glutCreateWindow("Test");
init();
glutDisplayFunc(renderMain);
glutIdleFunc(renderIdle);
glutReshapeFunc(reshape);
gSubWindow01 = glutCreateSubWindow(gMainWindow, BORDER, BORDER, subWindowWidth, subWindowHeight);
init();
glutDisplayFunc(renderSW01);
glutMouseFunc(mouseSW01);
gSubWindow02 = glutCreateSubWindow(gMainWindow, (2 * BORDER) + subWindowWidth, BORDER, subWindowWidth, subWindowHeight);
init();
glutDisplayFunc(renderSW02);
glutMouseFunc(mouseSW02);
glutMainLoop();
return 0;
}
//********************************************************************\\