bool cOcclusionQueryOGL::FetchResults() { int lAvailable=0; glGetQueryObjectivARB(mlQueryId,GL_QUERY_RESULT_AVAILABLE_ARB,(GLint *)&lAvailable); if(lAvailable==0) return false; glGetQueryObjectivARB(mlQueryId,GL_QUERY_RESULT_ARB,(GLint *)&mlLastSampleCount); return true; }
/* if the query object named by <id> is currently active, then an * INVALID_OPERATION error is generated. */ static bool conformOQ_GetObjResultIn(GLuint id) { int pass = true; GLint param; glBeginQueryARB(GL_SAMPLES_PASSED_ARB, id); glGetQueryObjectivARB(id, GL_QUERY_RESULT_ARB, ¶m); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) pass = false; glGetQueryObjectuivARB(id, GL_QUERY_RESULT_ARB, (GLuint *) & param); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) pass = false; if (pass == false) { printf(" Error: No GL_INVALID_OPERATION generated if " "GetQueryObject[u]iv with GL_QUERY_RESULT_ARB " "in the active progress.\n"); } glEndQueryARB(GL_SAMPLES_PASSED_ARB); return pass; }
/* If multiple queries are issued on the same target and id prior to calling * GetQueryObject[u]iVARB, the result returned will always be from the last * query issued. The results from any queries before the last one will be lost * if the results are not retrieved before starting a new query on the same * target and id. */ static bool conformOQ_GetObjivAval_multi1(GLuint id) { GLint ready; GLuint passed = 0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 25.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTranslatef(0.0, 0.0, -10.0); /* draw the occluder (red) */ glColorMask(1, 1, 1, 1); glDepthMask(GL_TRUE); glColor3f(1, 0, 0); piglit_draw_rect(-0.5, 0.5, 0.5, -0.5); glPushMatrix(); glTranslatef(0.0, 0.0, -5.0); glColorMask(0, 0, 0, 0); glDepthMask(GL_FALSE); /* draw the 1st box (green) which is occluded by the occluder partly */ glBeginQueryARB(GL_SAMPLES_PASSED_ARB, id); glColor3f(0, 1, 0); piglit_draw_rect(-0.51, 0.51, 0.51, -0.51); glEndQueryARB(GL_SAMPLES_PASSED_ARB); /* draw the 2nd box (blue) which is occluded by the occluder throughly */ glBeginQueryARB(GL_SAMPLES_PASSED_ARB, id); glColor3f(0, 0, 1); piglit_draw_rect(-0.4, 0.4, 0.4, -0.4); glEndQueryARB(GL_SAMPLES_PASSED_ARB); glPopMatrix(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); do { glGetQueryObjectivARB(id, GL_QUERY_RESULT_AVAILABLE_ARB, &ready); } while (!ready); glGetQueryObjectuivARB(id, GL_QUERY_RESULT_ARB, &passed); /* 'passed' should be zero */ return passed > 0 ? false : true; }
/* If <id> is not the name of a query object, then an INVALID_OPERATION error * is generated. */ static bool conformOQ_GetObjivAval(GLuint id) { GLuint id_tmp; GLint param; glBeginQueryARB(GL_SAMPLES_PASSED_ARB, id); glEndQueryARB(GL_SAMPLES_PASSED_ARB); id_tmp = find_unused_id(); if (id_tmp == 0) return false; glGetQueryObjectivARB(id_tmp, GL_QUERY_RESULT_AVAILABLE_ARB, ¶m); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return false; return true; }
static void Draw(void) { GLuint passed; GLint ready; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery); glBegin(GL_TRIANGLES); glColor3f(0,0,.7); glVertex3f( 0.9, -0.9, -30.0); glColor3f(.8,0,0); glVertex3f( 0.9, 0.9, -30.0); glColor3f(0,.9,0); glVertex3f(-0.9, 0.0, -30.0); glEnd(); glEndQueryARB(GL_SAMPLES_PASSED_ARB); do { /* do useful work here, if any */ glGetQueryObjectivARB(OccQuery, GL_QUERY_RESULT_AVAILABLE_ARB, &ready); } while (!ready); glGetQueryObjectuivARB(OccQuery, GL_QUERY_RESULT_ARB, &passed); fprintf(stderr, " %d Fragments Visible\n", passed); glFlush(); if (doubleBuffer) { glutSwapBuffers(); } }
real DrawVoronoi(real* xx) { int i,j; real fEnergy = 1e20; GLfloat *buffer_screen = new GLfloat[screenwidth*screenheight*4]; ////////////////////////////////////////////// // First pass - Render the initial sites // ////////////////////////////////////////////// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FB_objects); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, fbo_attachments[0], GL_TEXTURE_RECTANGLE_NV, Processed_Texture[0], 0); CheckFramebufferStatus(); glClearColor(-1, -1, -1, -1); glClear(GL_COLOR_BUFFER_BIT); glDrawBuffer(fbo_attachments[0]); cgGLEnableProfile(VertexProfile); cgGLEnableProfile(FragmentProfile); cgGLBindProgram(VP_DrawSites); cgGLBindProgram(FP_DrawSites); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(1, screenwidth+1, 1, screenheight+1); glViewport(1, 1, screenwidth, screenheight); DrawSites(xx, NULL); // glReadBuffer(fbo_attachments[0]); // imdebugPixelsf(0, 0, screenwidth+2, screenheight+2, GL_RGBA); Current_Buffer = 1; ///////////////////////////////////// // Second pass - Flood the sites // ///////////////////////////////////// cgGLBindProgram(VP_Flood); cgGLBindProgram(FP_Flood); if (VP_Flood_Size != NULL) cgSetParameter2f(VP_Flood_Size, screenwidth, screenheight); bool ExitLoop = false; bool SecondExit; int steplength;; SecondExit = (additional_passes==0); bool PassesBeforeJFA; PassesBeforeJFA = (additional_passes_before>0); if (PassesBeforeJFA) steplength = pow(2.0, (additional_passes_before-1)); else steplength = (screenwidth>screenheight ? screenwidth : screenheight)/2; while (!ExitLoop) { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, fbo_attachments[Current_Buffer], GL_TEXTURE_RECTANGLE_NV, Processed_Texture[Current_Buffer], 0); CheckFramebufferStatus(); glDrawBuffer(fbo_attachments[Current_Buffer]); glClearColor(-1, -1, -1, -1); glClear(GL_COLOR_BUFFER_BIT); //Bind & enable shadow map texture glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Processed_Texture[1-Current_Buffer]); if (VP_Flood_Steplength != NULL) cgSetParameter1d(VP_Flood_Steplength, steplength); glBegin(GL_QUADS); glVertex2f(1.0, 1.0); glVertex2f(1.0, float(screenheight+1)); glVertex2f(float(screenwidth+1), float(screenheight+1)); glVertex2f(float(screenwidth+1), 1.0); glEnd(); glReadBuffer(fbo_attachments[Current_Buffer]); // imdebugPixelsf(0, 0, screenwidth+2, screenheight+2, GL_RGBA); if (steplength==1 && PassesBeforeJFA) { steplength = (screenwidth>screenheight ? screenwidth : screenheight)/2; PassesBeforeJFA = false; } else if (steplength>1) steplength /= 2; else if (SecondExit) ExitLoop = true; else { steplength = pow(2.0, (additional_passes-1)); SecondExit = true; } Current_Buffer = 1-Current_Buffer; } glReadPixels(1,1,screenwidth,screenheight,GL_RGBA,GL_FLOAT,buffer_screen); /////////////////////////////// // Test pass, Compute energy // /////////////////////////////// int Current_Energy_Buffer = 0; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, fbo_attachments[0], GL_TEXTURE_RECTANGLE_NV, Energy_Texture[Current_Energy_Buffer], 0); CheckFramebufferStatus(); glDrawBuffer(fbo_attachments[0]); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); cgGLBindProgram(VP_ComputeEnergyCentroid); cgGLBindProgram(FP_ComputeEnergyCentroid); if (FP_ComputeEnergyCentroid_Size != NULL) cgSetParameter2f(FP_ComputeEnergyCentroid_Size, screenwidth, screenheight); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, Processed_Texture[1-Current_Buffer]); glBegin(GL_QUADS); glVertex2f(1.0, 1.0); glVertex2f(float(screenwidth+1), 1.0); glVertex2f(float(screenwidth+1), float(screenheight+1)); glVertex2f(1.0, float(screenheight+1)); glEnd(); // glReadBuffer(fbo_attachments[0]); // imdebugPixelsf(0, 0, screenwidth+2, screenheight+2, GL_RGBA); Current_Energy_Buffer = 1-Current_Energy_Buffer; ////////////////////// // perform reduction ////////////////////// cgGLBindProgram(VP_Deduction); cgGLBindProgram(FP_Deduction); bool ExitEnergyLoop = false; int quad_size = int((screenwidth>screenheight?screenwidth:screenheight)/2.0+0.5); while (!ExitEnergyLoop) { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, fbo_attachments[0], GL_TEXTURE_RECTANGLE_NV, Energy_Texture[Current_Energy_Buffer], 0); CheckFramebufferStatus(); glDrawBuffer(fbo_attachments[0]); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); //Bind & enable shadow map texture glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, Energy_Texture[1-Current_Energy_Buffer]); glBegin(GL_QUADS); glVertex2f(1.0, 1.0); glVertex2f(float(quad_size+1), 1.0); glVertex2f(float(quad_size+1), float(quad_size+1)); glVertex2f(1.0, float(quad_size+1)); glEnd(); // glReadBuffer(fbo_attachments[0]); // imdebugPixelsf(0, 0, screenwidth+2, screenheight+2, GL_RGBA); if (quad_size>1) { int temp = quad_size/2; quad_size = temp*2==quad_size ? temp : temp+1; } else ExitEnergyLoop = true; Current_Energy_Buffer = 1-Current_Energy_Buffer; } float total_sum[4]; // glReadBuffer(fbo_attachments[0]); // imdebugPixelsf(0, 0, screenwidth+2, screenheight+2, GL_RGBA); glReadPixels(1, 1, 1, 1, GL_RGBA, GL_FLOAT, &total_sum); printf("Energy: %f\n", total_sum[0]); fEnergy = total_sum[0]; ////////////////////////////////////////// // Third pass - Scatter points to sites // ////////////////////////////////////////// cgGLBindProgram(VP_ScatterCentroid); cgGLBindProgram(FP_ScatterCentroid); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, fbo_attachments[0], GL_TEXTURE_RECTANGLE_NV, Site_Texture, 0); CheckFramebufferStatus(); glDrawBuffer(buffers[0]); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); if (VP_ScatterCentroid_Size != NULL) cgSetParameter2f(VP_ScatterCentroid_Size, screenwidth, screenheight); //Bind & enable shadow map texture glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Processed_Texture[1-Current_Buffer]); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glBegin(GL_POINTS); for (i=0; i<screenwidth; i++) for (j=0; j<screenheight; j++) glVertex2f(i+1.5, j+1.5); glEnd(); glDisable(GL_BLEND); Current_Buffer = 1-Current_Buffer; /////////////////////////////////////// // Fourth pass - Test stop condition // /////////////////////////////////////// cgGLBindProgram(VP_DrawSitesOQ); cgGLBindProgram(FP_DrawSitesOQ); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, fbo_attachments[2], GL_RENDERBUFFER_EXT, RB_object); CheckFramebufferStatus(); glDrawBuffer(fbo_attachments[2]); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); if (VP_DrawSitesOQ_Size != NULL) cgSetParameter2f(VP_DrawSitesOQ_Size, screenwidth, screenheight); //Bind & enable shadow map texture glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Site_Texture); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Processed_Texture[Current_Buffer]); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); glBeginQueryARB(GL_SAMPLES_PASSED_ARB, occlusion_query); glBegin(GL_POINTS); for (i=0; i<point_num; i++) { float xx, yy; xx = i%screenwidth+1.5; yy = i/screenheight+1.5; glTexCoord1f(i); glVertex2f(xx, yy); } glEnd(); glEndQueryARB(GL_SAMPLES_PASSED_ARB); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); // glReadBuffer(fbo_attachments[2]); // imdebugPixelsf(0, 0, screenwidth+2, screenheight+2, GL_RGBA); do{ glGetQueryObjectivARB(occlusion_query, GL_QUERY_RESULT_AVAILABLE_ARB, &oq_available); }while(oq_available); glGetQueryObjectuivARB(occlusion_query, GL_QUERY_RESULT_ARB, &sampleCount); printf("sample count: %d\n", sampleCount); cgGLDisableProfile(VertexProfile); cgGLDisableProfile(FragmentProfile); //////////////////// // compute measures //////////////////// bool *bOnBoundary = new bool[point_num]; bool *bIsHexagon = new bool[point_num]; int *nNeighbors = new int[point_num*7]; real *dDiameter = new real[point_num]; real *dNeighborDist = new real[point_num]; float site_pos[2], x, y, dist, neighbor_pos[2]; int id, drow, dcol, nrow, ncol, neighbor_id, k; real dMaxDiameter, chi_id, chi; int nHex, nVC; for (id=0; id<point_num; id++) { bOnBoundary[id] = false; bIsHexagon[id] = true; nNeighbors[id*7] = 0; for (k=1; k<7; k++) nNeighbors[id*7+k] = -1; dDiameter[id] = -1; dNeighborDist[id] = 2*(screenwidth+screenheight); } dMaxDiameter = -1; chi = -1; nHex = nVC = 0; for (i=0; i<screenheight; i++) { for (j=0; j<screenwidth; j++) { site_pos[0] = buffer_screen[i*screenwidth*4+j*4]; site_pos[1] = buffer_screen[i*screenwidth*4+j*4+1]; id = int(buffer_screen[i*screenwidth*4+j*4+2]); x = j+1.5; y = i+1.5; site_pos[0] = (site_pos[0]-1)/screenwidth*2-1; site_pos[1] = (site_pos[1]-1)/screenheight*2-1; x = (x-1)/screenwidth*2-1; y = (y-1)/screenheight*2-1; dist = (x-site_pos[0])*(x-site_pos[0])+(y-site_pos[1])*(y-site_pos[1]); dist = sqrt(dist); dDiameter[id] = dDiameter[id]<dist ? dist : dDiameter[id]; // traverse 9 neighbors for (drow=-1; drow<=1; drow++) { for (dcol=-1; dcol<=1; dcol++) { if (drow==0 && dcol==0) continue; nrow = i+drow; ncol = j+dcol; if (nrow<0 || nrow>=screenheight || ncol<0 || ncol>=screenwidth) { bOnBoundary[id] = true; continue; } neighbor_pos[0] = buffer_screen[nrow*screenwidth*4+ncol*4]; neighbor_pos[1] = buffer_screen[nrow*screenwidth*4+ncol*4+1]; neighbor_id = int(buffer_screen[nrow*screenwidth*4+ncol*4+2]); neighbor_pos[0] = (neighbor_pos[0]-1)/screenwidth*2-1; neighbor_pos[1] = (neighbor_pos[1]-1)/screenheight*2-1; if (neighbor_id==id) continue; dist = (neighbor_pos[0]-site_pos[0])*(neighbor_pos[0]-site_pos[0]) +(neighbor_pos[1]-site_pos[1])*(neighbor_pos[1]-site_pos[1]); dist = sqrt(dist); dNeighborDist[id] = dNeighborDist[id]>dist ? dist : dNeighborDist[id]; for (k=1; k<7; k++) { if (nNeighbors[id*7+k]<0) { nNeighbors[id*7+k] = neighbor_id; nNeighbors[id*7]++; break; } else if (nNeighbors[id*7+k]==neighbor_id) break; } if (k==7) bIsHexagon[id] = false; } } } } for (id=0; id<point_num; id++) { if (nNeighbors[id*7]!=6) bIsHexagon[id] = false; } for (id=0; id<point_num; id++) { dMaxDiameter = dMaxDiameter<dDiameter[id] ? dDiameter[id] : dMaxDiameter; chi_id = 2*dDiameter[id]/dNeighborDist[id]; chi = chi<chi_id ? chi_id : chi; if (!bOnBoundary[id]) { nVC++; } if (bIsHexagon[id]) { nHex++; } } printf("\n==== measures ====\n"); printf("Number of VC in the middle: %d\n", nVC); printf("Number of hexagons: %d\n", nHex); printf("h: %f\n", dMaxDiameter); printf("chi: %f\n", chi); printf("==== measures ====\n\n"); //////////////////// // Fill Octagon & another //////////////////// GLubyte *ColorTexImage = new GLubyte[screenwidth*screenheight*4]; for (i=0; i<screenheight; i++) { for (j=0; j<screenwidth; j++) { int id = i*screenwidth+j; if (id<point_num) { if (bIsHexagon[id]) { ColorTexImage[id*4] = 255; ColorTexImage[id*4+1] = 255; ColorTexImage[id*4+2] = 255; ColorTexImage[id*4+3] = 255; } else { ColorTexImage[id*4] = 192; ColorTexImage[id*4+1] = 192; ColorTexImage[id*4+2] = 192; ColorTexImage[id*4+3] = 255; } } else { ColorTexImage[id*4] = ColorTexImage[id*4+1] = ColorTexImage[id*4+2] = ColorTexImage[id*4+3] = 0.0; } } } glActiveTextureARB(GL_TEXTURE2_ARB); glGenTextures(1, &Color_Texture); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Color_Texture); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, screenwidth, screenheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, ColorTexImage); delete ColorTexImage; delete [] buffer_screen; delete [] bOnBoundary; delete [] bIsHexagon; delete [] nNeighbors; delete [] dDiameter; delete [] dNeighborDist; /////////////////////////////////// // Last pass, Display the result // /////////////////////////////////// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, screenwidth-1, 0, screenheight-1); glViewport(0, 0, screenwidth, screenheight); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Processed_Texture[Current_Buffer]); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_NV, Site_Texture); cgGLEnableProfile(VertexProfile); cgGLEnableProfile(FragmentProfile); cgGLBindProgram(VP_FinalRender); cgGLBindProgram(FP_FinalRender); if (FP_FinalRender_Size != NULL) cgSetParameter2f(FP_FinalRender_Size, screenwidth, screenheight); // Set parameters of fragment program glBegin(GL_QUADS); glVertex2f(0.0, 0.0); glVertex2f(0.0, float(screenheight)); glVertex2f(float(screenwidth), float(screenheight)); glVertex2f(float(screenwidth), 0.0); glEnd(); cgGLDisableProfile(VertexProfile); cgGLDisableProfile(FragmentProfile); DrawSites(xx, NULL); return fEnergy; }
static void Display( void ) { GLuint passed; GLint ready; char s[100]; glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0, 0.0, -15.0 ); /* draw the occluding polygons */ glColor3f(0, 0.6, 0.8); glBegin(GL_QUADS); glVertex2f(-1.6, -1.5); glVertex2f(-0.4, -1.5); glVertex2f(-0.4, 1.5); glVertex2f(-1.6, 1.5); glVertex2f( 0.4, -1.5); glVertex2f( 1.6, -1.5); glVertex2f( 1.6, 1.5); glVertex2f( 0.4, 1.5); glEnd(); /* draw the test polygon with occlusion testing */ glPushMatrix(); glTranslatef(Xpos, 0, -0.5); glScalef(0.3, 0.3, 1.0); glRotatef(-90.0 * Xpos, 0, 0, 1); #if TEST_DISPLAY_LISTS glNewList(10, GL_COMPILE); glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery); glEndList(); glCallList(10); #else glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery); #endif glColorMask(0, 0, 0, 0); glDepthMask(GL_FALSE); glBegin(GL_POLYGON); glVertex3f(-1, -1, 0); glVertex3f( 1, -1, 0); glVertex3f( 1, 1, 0); glVertex3f(-1, 1, 0); glEnd(); #if TEST_DISPLAY_LISTS glNewList(11, GL_COMPILE); glEndQueryARB(GL_SAMPLES_PASSED_ARB); glEndList(); glCallList(11); #else glEndQueryARB(GL_SAMPLES_PASSED_ARB); #endif do { /* do useful work here, if any */ glGetQueryObjectivARB(OccQuery, GL_QUERY_RESULT_AVAILABLE_ARB, &ready); } while (!ready); glGetQueryObjectuivARB(OccQuery, GL_QUERY_RESULT_ARB, &passed); /* turn off occlusion testing */ glColorMask(1, 1, 1, 1); glDepthMask(GL_TRUE); /* draw the orange rect, so we can see what's going on */ glColor3f(0.8, 0.5, 0); glBegin(GL_POLYGON); glVertex3f(-1, -1, 0); glVertex3f( 1, -1, 0); glVertex3f( 1, 1, 0); glVertex3f(-1, 1, 0); glEnd(); glPopMatrix(); /* Print result message */ glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glColor3f(1, 1, 1); sprintf(s, " %4d Fragments Visible", passed); glRasterPos3f(-0.50, -0.7, 0); PrintString(s); if (!passed) { glRasterPos3f(-0.25, -0.8, 0); PrintString("Fully Occluded"); } glutSwapBuffers(); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBOcclusionQuery_nglGetQueryObjectivARB(JNIEnv *env, jclass clazz, jint id, jint pname, jlong params, jlong function_pointer) { GLint *params_address = (GLint *)(intptr_t)params; glGetQueryObjectivARBPROC glGetQueryObjectivARB = (glGetQueryObjectivARBPROC)((intptr_t)function_pointer); glGetQueryObjectivARB(id, pname, params_address); }
enum piglit_result run_subtest(void) { bool exact; uint32_t expected; uint64_t cpu_result; bool have_cpu_result = false; uint32_t default_value[4] = { 0xccccccccu, 0xccccccccu, 0xccccccccu, 0xccccccccu }; bool is_sync = sync_mode == QBO_SYNC || sync_mode == QBO_SYNC_CPU_READ_AFTER_CACHE_TEST; get_query_values(query_desc, &exact, &expected); glGenQueries(1, &query); run_query(query, query_desc); /* Load default value into buffer */ glBindBuffer(GL_QUERY_BUFFER, qbo); glBufferData(GL_QUERY_BUFFER, 16, default_value, GL_DYNAMIC_COPY); if (sync_mode == QBO_ASYNC_CPU_READ_BEFORE) { if (cpu_gather_query(exact, expected, &cpu_result)) return PIGLIT_FAIL; have_cpu_result = true; } glBindBuffer(GL_QUERY_BUFFER, qbo); if (is_sync) { /* Special mode to test against a possible cache invalidation * in case the wait-for-result is handled at a different place * in the memory hierarchy than actually reading and * summarizing the result. */ if (sync_mode == QBO_SYNC_CPU_READ_AFTER_CACHE_TEST) glGetQueryObjectivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0)); if (result_type == GL_INT) glGetQueryObjectivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0)); else if (result_type == GL_UNSIGNED_INT) glGetQueryObjectuivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0)); else glGetQueryObjectui64v(query, GL_QUERY_RESULT, BUFFER_OFFSET(0)); } else { if (result_type == GL_INT) { glGetQueryObjectivARB(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(8)); glGetQueryObjectivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0)); } else if (result_type == GL_UNSIGNED_INT) { glGetQueryObjectuivARB(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(8)); glGetQueryObjectuivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0)); } else { glGetQueryObjectui64v(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(8)); glGetQueryObjectui64v(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0)); } } if (sync_mode == QBO_SYNC_CPU_READ_AFTER_CACHE_TEST || sync_mode == QBO_ASYNC_CPU_READ_AFTER) { if (cpu_gather_query(exact, expected, &cpu_result)) return PIGLIT_FAIL; have_cpu_result = true; } /* Make it available to shader as uniform buffer 0 */ glBindBufferBase(GL_UNIFORM_BUFFER, 0, qbo); glUseProgram(qbo_prog); /* Setup program uniforms */ glUniform1ui(sync_mode_loc, is_sync ? GL_TRUE : GL_FALSE); glUniform1ui(expect_exact_loc, have_cpu_result || exact); glUniform1ui(is_64bit_loc, result_type == GL_UNSIGNED_INT64_ARB); glUniform1ui(expected_loc, have_cpu_result ? cpu_result : expected); glUniform1ui(expected_hi_loc, have_cpu_result ? (cpu_result >> 32) : 0); glDisable(GL_DEPTH_TEST); /* Draw green if query successful */ piglit_draw_rect(-1, -1, 2, 2); glDeleteQueries(1, &query); if (!piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green)) { unsigned *ptr = glMapBuffer(GL_QUERY_BUFFER, GL_READ_ONLY); printf("Expected: %u\n", expected); if (have_cpu_result) printf("CPU result: %lu\n", cpu_result); printf("QBO: %u %u %u %u\n", ptr[0], ptr[1], ptr[2], ptr[3]); glUnmapBuffer(GL_QUERY_BUFFER); return PIGLIT_FAIL; } return PIGLIT_PASS; }
static void Display( void ) { int i; glClearColor(0.25, 0.25, 0.25, 0.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0, 0.0, -15.0 ); /* draw the occluding polygons */ glColor3f(0, 0.4, 0.6); glBegin(GL_QUADS); glVertex2f(-1.6, -2.5); glVertex2f(-0.4, -2.5); glVertex2f(-0.4, 2.5); glVertex2f(-1.6, 2.5); glVertex2f( 0.4, -2.5); glVertex2f( 1.6, -2.5); glVertex2f( 1.6, 2.5); glVertex2f( 0.4, 2.5); glEnd(); glColorMask(0, 0, 0, 0); glDepthMask(GL_FALSE); /* draw the test polygons with occlusion testing */ for (i = 0; i < NUM_OCC; i++) { glPushMatrix(); glTranslatef(Xpos[i], Ypos[i], -0.5); glScalef(0.2, 0.2, 1.0); glRotatef(-90.0 * Xpos[i], 0, 0, 1); glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery[i]); glBegin(GL_POLYGON); glVertex3f(-1, -1, 0); glVertex3f( 1, -1, 0); glVertex3f( 1, 1, 0); glVertex3f(-1, 1, 0); glEnd(); glEndQueryARB(GL_SAMPLES_PASSED_ARB); glPopMatrix(); } glColorMask(1, 1, 1, 1); glDepthMask(GL_TRUE); /* Draw the rectangles now. * Draw orange if result was ready * Draw red if result was not ready. */ for (i = 0; i < NUM_OCC; i++) { GLuint passed; GLint ready; glGetQueryObjectivARB(OccQuery[i], GL_QUERY_RESULT_AVAILABLE_ARB, &ready); glGetQueryObjectuivARB(OccQuery[i], GL_QUERY_RESULT_ARB, &passed); if (!ready) glColor3f(1, 0, 0); else glColor3f(0.8, 0.5, 0); if (!ready || passed) { glPushMatrix(); glTranslatef(Xpos[i], Ypos[i], -0.5); glScalef(0.2, 0.2, 1.0); glRotatef(-90.0 * Xpos[i], 0, 0, 1); glBegin(GL_POLYGON); glVertex3f(-1, -1, 0); glVertex3f( 1, -1, 0); glVertex3f( 1, 1, 0); glVertex3f(-1, 1, 0); glEnd(); glPopMatrix(); } { char s[10]; glRasterPos3f(0.45, Ypos[i], 1.0); sprintf(s, "%4d", passed); PrintString(s); } } glutSwapBuffers(); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBOcclusionQuery_nglGetQueryObjectivARB(JNIEnv *env, jclass clazz, jint id, jint pname, jobject params, jint params_position, jlong function_pointer) { GLint *params_address = ((GLint *)(*env)->GetDirectBufferAddress(env, params)) + params_position; glGetQueryObjectivARBPROC glGetQueryObjectivARB = (glGetQueryObjectivARBPROC)((intptr_t)function_pointer); glGetQueryObjectivARB(id, pname, params_address); }
void CGLMQuery::Complete( uint *result ) { m_ctx->MakeCurrent(); uint resultval = 0; GLint available = 0; bool bogus_available = false; // blocking call if not done Assert(m_started); Assert(m_stopped); switch(m_params.m_type) { case EOcclusion: { if (m_nullQuery) { m_done = true; resultval = 0; // we did say "null queries..." } else { // accept that the query is going to drain pipe in 10.6.4 and prior. // check the error on the spot. glGetQueryObjectivARB(m_name, GL_QUERY_RESULT_AVAILABLE_ARB, &available ); GLenum errorcode = GetQueryError(); if (errorcode) { const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); printf( "\nCGLMQuery::Complete saw %s error (%d) from glGetQueryObjectivARB GL_QUERY_RESULT_AVAILABLE_ARB name=%d", decodedStr, errorcode, m_name ); resultval=0; } else { if (!available) { // this does happen with some very modest frequency. if (!m_ctx->Caps().m_hasPerfPackage1) { glFlush(); // ISTR some deadlock cases on pre-SLGU drivers if you didn't do this to kick the queue along.. } } glGetQueryObjectuivARB( m_name, GL_QUERY_RESULT_ARB, &resultval); errorcode = GetQueryError(); if (errorcode) { const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); printf( "\nCGLMQuery::Complete saw %s error (%d) from glGetQueryObjectivARB GL_QUERY_RESULT_ARB name=%d", decodedStr, errorcode, m_name ); resultval=0; } else { // resultval is legit } } m_done = true; } } break; case EFence: { if(!m_done) { glFinishFenceAPPLE( m_name ); GLenum errorcode = GetQueryError(); if (errorcode) { const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); printf( "\nCGLMQuery::Complete saw %s error (%d) from glFinishFenceAPPLE (EFence) name=%d", decodedStr, errorcode, m_name ); } m_done = true; // for clarity or if they try to Complete twice } } break; } Assert( m_done ); // reset state for re-use - i.e. you have to call Complete if you want to re-use the object m_started = m_stopped = m_done = false; if (result) // caller may pass NULL if not interested in result, for example to clear a fence { *result = resultval; } }
bool CGLMQuery::IsDone( void ) { m_ctx->MakeCurrent(); Assert(m_started); Assert(m_stopped); if(!m_done) // you can ask more than once, but we only check until it comes back as done. { // on occlusion: glGetQueryObjectivARB - large cost on pre SLGU, cheap after // on fence: glTestFenceAPPLE on the fence switch(m_params.m_type) { case EOcclusion: // just test the fence that was set after the query begin { if (m_nullQuery) { // do almost nothing.. but claim work is complete m_done = true; } else { // prepare to pay a big price on drivers prior to 10.6.4+SLGU GLint available = 0; glGetQueryObjectivARB(m_name, GL_QUERY_RESULT_AVAILABLE_ARB, &available ); GLenum errorcode = GetQueryError(); if (errorcode) { const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); printf( "\nCGLMQuery::IsDone saw %s error (%d) from glGetQueryObjectivARB(a2) name=%d", decodedStr, errorcode, m_name ); } m_done = (available != 0); } } break; case EFence: { m_done = glTestFenceAPPLE( m_name ); GLenum errorcode = GetQueryError(); if (errorcode) { const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); printf( "\nCGLMQuery::IsDone saw %s error (%d) from glTestFenceAPPLE(b) name=%d", decodedStr, errorcode, m_name ); } if (m_done) { glFinishFenceAPPLE( m_name ); // no set fence goes un-finished errorcode = GetQueryError(); if (errorcode) { const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); printf( "\nCGLMQuery::IsDone saw %s error (%d) from glFinishFenceAPPLE(b) name=%d", decodedStr, errorcode, m_name ); } } } break; } } return m_done; }