PDA

View Full Version : occlusion query not working



pytell
11-02-2009, 06:01 PM
I wanted to have occlusion query working on 3-D cube set. Therefore I've created cube structure and managed some simple rendering algorithms. The problem is that the occlusion query I've written doesn't work properly. It renders each cube and does not filter obscured ones. Could you help me determing what's wrong with my code?
Regards
Gregory

This is my code:
#include <stdlib.h>
#include "GLee.h"
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <assert.h>

#define BUFSIZE 512
#define CUBES 2
#define CUBES_TOTAL (CUBES * CUBES * CUBES)

struct Cube{
float colour[3];
double x,y,z;
int id;
bool visible;
bool render;
}pointed;

Cube cubes[CUBES_TOTAL];
int pointedCubeIndex=-1;
float cubeSize = 0.7f;
GLsizei width=500,height=500;
GLfloat screenAspect;

//rotation
GLfloat theta[3], axis_values[3];
GLint axis = 2;
/*initial viewer location*/
GLdouble viewer[] = {0.0,0.0,5.0};

float lastPos[3] = {0.0F,0.0F,0.0F};
int curx,cury;
int startX, startY;

bool rotationEnabled = true;
bool trackingMouse = false;
bool redrawContinue = false;
bool trackballMove = false;

void display(void);

void init()
{
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);

int id=0;

for(int i=0;i<CUBES;++i)
for(int j=0;j<CUBES;++j)
for(int k=0;k<CUBES;++k)
{
cubes[id].id = id+1;
cubes[id].colour[0] = (double)rand() / (RAND_MAX + 1);
cubes[id].colour[1] = (double)rand() / (RAND_MAX + 1);
cubes[id].colour[2] = (double)rand() / (RAND_MAX + 1);

cubes[id].visible = true;
cubes[id].render = true;
cubes[id].x = i*cubeSize;
cubes[id].y = j*cubeSize;
cubes[id].z = k*cubeSize;
id++;
}
}


void drawSystem(GLenum mode)
{
GLuint queries[CUBES_TOTAL];
GLuint sampleCount;
GLint available;
GLuint bitsSupported;
int i;

glLoadIdentity();
glTranslatef(-CUBES/2 * cubeSize ,-CUBES/2 * cubeSize,0.0);

glGenQueriesARB(CUBES_TOTAL, queries);

gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);

glRotatef(theta[0],axis_values[0],axis_values[1],axis_values[2]);

glDepthMask(GL_FALSE);


for(i=0;i<CUBES_TOTAL;++i)
{
if(cubes[i].visible)
{
glPushMatrix();
glTranslatef(cubes[i].x,cubes[i].y,cubes[i].z);
glBeginQueryARB(GL_SAMPLES_PASSED_ARB,queries[i]);
glutWireCube(cubeSize);
glEndQuery(GL_SAMPLES_PASSED_ARB);
glPopMatrix();
}
}
glDepthMask(GL_TRUE);

glFlush();

i = CUBES_TOTAL * 3/4;
do{
glGetQueryObjectivARB(queries[i],GL_QUERY_RESULT_AVAILABLE_ARB,&amp;available);
}while(!available);
glFlush();

//hack me: do poprawienia occlusion test
GLint rendered = 0;
for(int i=0;i<CUBES_TOTAL;++i)
{
glGetQueryObjectuivARB(queries[i],GL_QUERY_RESULT_AVAILABLE_ARB,&amp;sampleCount);
if(sampleCount>0 &amp;&amp; cubes[i].visible &amp;&amp; glIsQuery(queries[i]))
{
glPushMatrix();
glTranslatef(cubes[i].x,cubes[i].y,cubes[i].z);
glColor3fv(cubes[i].colour);
glLoadName(cubes[i].id);
glutSolidCube(cubeSize);
glPopMatrix();
rendered++;
}
}
printf("I've rendered: %d\n",rendered);
}

void redefineProjection()
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0,screenAspect,1.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}

void processHits(GLuint hits, GLuint buffer[])
{
assert(hits!=-1);
unsigned int i,j;
GLuint names, * ptr;
printf("hits = %d\n",hits);
ptr = (GLuint *) buffer;
if(hits==0)
{
pointedCubeIndex = -1;
return;
}

for(i=0;i<hits;++i)
{
names = *ptr;
#if _DEBUG
printf(" number of names for hit = %d\n",names);
#endif
ptr++;
#if _DEBUG
printf(" z1 is %g;", (float)*ptr/0x7fffffff);
#endif
ptr++;
#if _DEBUG
printf(" z2 is %g\n",(float)*ptr/0x7fffffff);
#endif
ptr++;
#if _DEBUG
printf(" the name is");
#endif
for(j=0;j<names;++j)
{
#if _DEBUG
printf(" %d", *ptr);
#endif
if(*ptr>0)
{
pointedCubeIndex = *ptr;
pointedCubeIndex--;
}
ptr++;
}
#if _DEBUG
printf("\n");
#endif
}

#if _DEBUG
printf("\nFINALL!!\nthe name is: %d\n",*(ptr+3));
#endif
memcpy(&amp;pointed,&amp;cubes[pointedCubeIndex],sizeof(struct Cube));
cubes[pointedCubeIndex].visible = !cubes[pointedCubeIndex].visible;
}


void trackball_ptov(int x,int y, int width,int height,float v[3])
{
float d,a;
/* project onto a hemisphere centered within width and height */
v[0] = (2.0F*x - width)/width;
v[1]= (height - 2.0F*y)/height;
d= (float) sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = (float) cos((3.1459/2.0F)*((d<1.0F)?d:1.0F));
a= 1.0F / (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *=a;
v[1] *=a;
v[2] *=a;
}

void prepareHits(int x,int y,GLuint selectBuf[BUFSIZE])
{
GLint viewport[4];

glGetIntegerv(GL_VIEWPORT,viewport);

glSelectBuffer(BUFSIZE,selectBuf);
(void)glRenderMode(GL_SELECT);

glInitNames();
glPushName(0);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble)x,(GLdouble)(viewport[3] - y),5.0,5.0,viewport);

gluPerspective(40.0,screenAspect,1.0,20.0);
glMatrixMode(GL_MODELVIEW);

drawSystem(GL_SELECT);

glPopMatrix();
glFlush();

}

//computes world coordinates mouse rotation values
void computeMousePosValues(float curPos[3])
{
float dx,dy,dz;
dx = curPos[0] - lastPos[0];
dy = curPos[1] - lastPos[1];
dz = curPos[2] - lastPos[2];

if(dx || dy || dz)
{
GLfloat angle = 90.0F * sqrt(dx*dx + dy*dy + dz*dz);
theta[0] = theta[1] = theta[2] = angle;

axis_values[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
axis_values[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
axis_values[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];

lastPos[0] = curPos[0];
lastPos[1] = curPos[1];
lastPos[2] = curPos[2];
}
}


void processMouseClick(int x, int y)
{
GLuint selectBuf[BUFSIZE];
GLint hits;
prepareHits(x,y,selectBuf);
hits = glRenderMode(GL_RENDER);
processHits(hits,selectBuf);
}

void mouseMotion(int x,int y)
{
if(rotationEnabled)
{
float curPos[3];
trackball_ptov(x,y,width,height,curPos);

if(trackingMouse)
{
//printf("rotating\n");
computeMousePosValues(curPos);
}
}
else
{
processMouseClick(x,y);
}
redefineProjection();
}

void startMotion(int x,int y)
{
trackingMouse = true;
redrawContinue = false;
startX = x;
startY = y;
curx = x;
cury = y;
trackball_ptov(x,y,width,height,lastPos);
trackballMove = true;
}

void stopMotion(int x, int y)
{
trackingMouse = false;

if(startX != x || startY !=y)
{
redrawContinue = true;
}
else
{
theta[0] = theta[1] = theta[2] = 0.0F;
redrawContinue = false;
trackballMove = false;
}
}

void pickCube(int button,int state,int x,int y)
{
if(button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_DOWN &amp;&amp; rotationEnabled)
{
y = height - y;
startMotion(x,y);
axis = 0;
return;
}
else if(button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_UP &amp;&amp; rotationEnabled)
{
stopMotion(x,y);
return;
}
processMouseClick(x,y);
redefineProjection();
glutPostRedisplay();
}

void keys(unsigned char key, int x, int y)
{
switch(key)
{
case 'x':
viewer[0] -=1.0;
break;
case 'X':
viewer[0] +=1.0;
break;
case 'y':
viewer[1] -= 1.0;
break;
case 'Y':
viewer[1] += 1.0;
break;
case 'z':
viewer[2] -= 1.0;
break;
case 'Z':
viewer[2] += 1.0;
break;
case 'r':
rotationEnabled = !rotationEnabled;
break;
case 'm':
if(pointedCubeIndex!=-1)
cubes[pointedCubeIndex].visible = !cubes[pointedCubeIndex].visible;
pointedCubeIndex = -1;
}
glutPostRedisplay();
}

void display(void)
{
glEnable(GL_DEPTH_TEST);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

drawSystem(GL_RENDER);

glutSwapBuffers();
}

void reshape(int w,int h)
{
width = (GLsizei) w;
height = (GLsizei) h;
screenAspect = (GLfloat)w/(GLfloat)h;
redefineProjection();
}

int main(int argc,char * argv[])
{
srand(time(NULL));
glutInit(&amp;argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPT H);
glutInitWindowSize(width,height);
glutInitWindowPosition(400,200);
glutCreateWindow("Volume GL");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(pickCube);
glutMotionFunc(mouseMotion);
glutKeyboardFunc(keys);
glutMainLoop();
return 0;
}