clan::Image App::get_stencil(clan::Canvas &canvas, clan::Rect rect) { canvas.flush(); // For an unknown reason, stencil reads should be a multiple of 32 rect.left = 32 * ((rect.left + 31) / 32); rect.top = 32 * ((rect.top + 31) / 32); rect.right = 32 * ((rect.right + 31) / 32); rect.bottom = 32 * ((rect.bottom + 31) / 32); int rect_width = rect.get_width(); int rect_height = rect.get_height(); std::vector<unsigned char> buffer; buffer.resize(rect_width * rect_height); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, rect_width); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadBuffer(GL_BACK); if (glClampColor) { #ifdef GL_CLAMP_READ_COLOR glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); #else glClampColor(clan::GL_CLAMP_READ_COLOR, GL_FALSE); #endif } glReadPixels(rect.left, canvas.get_height()- rect.bottom, rect_width, rect_height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &buffer[0]); clan::PixelBuffer pbuf(rect_width, rect_height, clan::tf_rgba8); unsigned int *pdata = (unsigned int *) pbuf.get_data(); unsigned char *rdata = &buffer[0]; for (int ycnt=0; ycnt < rect_height; ycnt++) { for (int xcnt=0; xcnt < rect_width; xcnt++) { int value = *(rdata++); if (value == 0) { *(pdata++) = 0xFF005500; } else { value = value * 16; value = 0xFF000000 | value | (value << 8) | (value << 16); *(pdata++) = value; } } } pbuf.flip_vertical(); return clan::Image(canvas, pbuf, pbuf.get_size()); }
PixelBuffer GL3GraphicContextProvider::get_pixeldata(const Rect& rect, TextureFormat texture_format, bool clamp) const { TextureFormat_GL tf = OpenGL::get_textureformat(texture_format); if (!tf.valid) throw Exception("Unsupported texture format passed to GraphicContext::get_pixeldata"); PixelBuffer pbuf(rect.get_width(), rect.get_height(), texture_format); OpenGL::set_active(this); if (!framebuffer_bound) { render_window->is_double_buffered() ? glReadBuffer(GL_BACK) : glReadBuffer(GL_FRONT); } if (glClampColor) glClampColor(GL_CLAMP_READ_COLOR, clamp ? GL_TRUE : GL_FALSE); Size display_size = get_display_window_size(); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pbuf.get_pitch() / pbuf.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels(rect.left, display_size.height - rect.bottom, rect.get_width(), rect.get_height(), tf.pixel_format, tf.pixel_datatype, pbuf.get_data()); pbuf.flip_vertical(); return pbuf; }
int main(int, char **) { int argc = 2; const char* argv[] = { "main", "-glDebug" }; glutInit(&argc, const_cast<char**>(&argv[0])); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(g_winWidth, g_winHeight); glutInitWindowPosition(0, 0); g_win = glutCreateWindow(argv[0]); #ifndef __APPLE__ glewInit(); if (!glewIsSupported("GL_VERSION_2_0")) { std::cout << "OpenGL 2.0 not supported" << std::endl; exit(1); } #endif // Step 1: Initilize the OpenGL engine glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment #ifndef __APPLE__ glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); // glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); // avoid any kind of clamping glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); // #endif glEnable(GL_TEXTURE_2D); glClearColor(0, 0, 0, 0); // background color glClearStencil(0); // clear stencil buffer // Step 2: Allocate the needed textures AllocateImageTexture(); AllocateDefaultLut3D(); // Step 3: Create the frame buffer and render buffer GLuint fboId; // create a framebuffer object, you need to delete them when program exits. glGenFramebuffers(1, &fboId); glBindFramebuffer(GL_FRAMEBUFFER, fboId); GLuint rboId; // create a renderbuffer object to store depth info glGenRenderbuffers(1, &rboId); glBindRenderbuffer(GL_RENDERBUFFER, rboId); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F_ARB, g_winWidth, g_winHeight); glBindRenderbuffer(GL_RENDERBUFFER, 0); // attach a texture to FBO color attachement point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, g_imageTexID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_3D, g_lut3dTexID, 0); // attach a renderbuffer to depth attachment point glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Step 4: Execute all the unit tests unsigned failures = 0; const UnitTests & tests = GetUnitTests(); const size_t numTests = tests.size(); for(size_t idx=0; idx<numTests; ++idx) { OCIOGPUTest* test = tests[idx]; test->setup(); const unsigned curr_failures = failures; // Set the rendering destination to FBO glBindFramebuffer(GL_FRAMEBUFFER, fboId); // Clear buffer glClearColor(0.1f, 0.1f, 0.1f, 0.1f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); std::cerr << "Test [" << test->group() << "] [" << test->name() << "] - "; try { // Update the image texture UpdateImageTexture(); // Update the GPU shader program UpdateOCIOGLState(test->getProcessor()); // Enable the shader program, and its textures glUseProgram(g_program); glUniform1i(glGetUniformLocation(g_program, "tex1"), 1); glUniform1i(glGetUniformLocation(g_program, "tex2"), 2); // Process the image texture into the rendering buffer Reshape(); Redisplay(); // Validate the processed image using the rendering buffer ValidateImageTexture(test->getProcessor(), test->getErrorThreshold()); } catch(OCIO::Exception & ex) { ++failures; std::cerr << "FAILED - " << ex.what() << std::endl; } catch(...) { ++failures; std::cerr << "FAILED - Unexpected error" << std::endl; } if(curr_failures==failures) { std::cerr << "PASSED" << std::endl; } glUseProgram(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } std::cerr << std::endl << failures << " tests failed" << std::endl << std::endl; }
List<BoundingBox> SWTHelperGPU::StrokeWidthTransform(const cv::Mat &input) { glFinish(); auto startTime = now(); DisableIrrelvantState(); glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); int width = input.size().width; int height = input.size().height; // Create a Texture from the input Ptr<Texture> texture = textureFromImage<cv::Vec3f>(input); List< Ptr<Texture> > textures; /*for(int i = 0; i < 14; ++i) textures.push_back( New<Texture>(width, height, GL_RGBA, GL_FLOAT) ); for(int i = 0; i < 14; ++i) textures[i].reset(); */ // Create the framebuffer attachments auto colorf = New<Texture>(GL_RGBA, width, height, GL_RGBA, GL_FLOAT); auto depthStencil = New<Texture>(GL_DEPTH_STENCIL, width, height, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); //Ptr<RenderBuffer> depthStencil = New<RenderBuffer>(width, height, RenderBufferType::DepthStencil); // Create and setup framebuffer FrameBuffer frameBuffer(colorf); //frameBuffer.SetDepthStencil(depthStencil); // Create a full-screen rect DrawableRect rect(-1, -1, 1, 1); GraphicsDevice::SetDefaultBuffers(rect.VertexBuffer, rect.IndexBuffer); GraphicsDevice::UseDefaultBuffers(); frameBuffer.Bind(); auto textRegionsFilter = New<TextRegionsFilter>(texture); textRegionsFilter->DoLoadShaderPrograms(); glFinish(); auto setupTime = now() - startTime; ApplyPass(textRegionsFilter); //FrameBuffer::GetCurrentlyBound()->Print(RenderBufferType::Stencil); glFinish(); auto totalTime = now() - startTime; auto misc = totalTime - renderTime - setupTime; printf("\n"); printf("Total time: %.1fms\n", GetTimeMsec(totalTime)); printf("Setup time: %.1fms (%.1f%%)\n", GetTimeMsec(setupTime), setupTime * 100.0f / totalTime); printf("Render time: %.1fms (%.1f%%)\n", GetTimeMsec(renderTime), renderTime * 100.0f / totalTime); printf("Misc time: %.1fms (%.1f%%)\n", GetTimeMsec(misc), misc * 100.0f / totalTime); printf("Textures: Active %i Peak %i\n", Texture::ActiveTextureCount, Texture::PeakTextureCount); return textRegionsFilter->ExtractedBoundingBoxes; }
enum piglit_result piglit_display(void) { GLuint vao = 0; GLuint fbo = 0; GLuint *fboTextures = NULL; GLenum *colorBuffers = NULL; GLuint attribLoc; GLfloat result[4]; int i = 0; /* * Reserve memory for the FBO texture objects. */ fboTextures = calloc(g_maxColorAttachments, sizeof(GLuint)); if (NULL == fboTextures) { fprintf(stderr, "Failed to create FBO texture object container.\n"); goto fail; } /* * Build the color attachments */ colorBuffers = calloc(g_maxColorAttachments, sizeof(GLenum)); if (NULL == colorBuffers) { fprintf(stderr, "Failed to create draw buffers descriptor.\n"); goto fail; } /* * Generate an FBO container to hold the color attachment hierarchy. */ glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (i = 0; i < g_maxColorAttachments; i++) { setup_fbo_2d(i, GL_RGBA32F, GL_RGBA, GL_FLOAT, BUFFER_WIDTH, BUFFER_HEIGHT, fbo, &fboTextures[i]); colorBuffers[i] = GL_COLOR_ATTACHMENT0 + i; } /* * Build the textures sampled by the shaders */ for (i = 0; i < g_maxCombinedTextureImageUnits; i++) { GLuint tex; GLuint uniformLoc; char strTemp[16]; glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (((i+1) * MAX_COMPONENTS) > sizeof(g_primes)) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, &g_primes[i * MAX_COMPONENTS]); } if (!piglit_check_gl_error(GL_NO_ERROR)) { fprintf(stderr, "Failed to create texture %u.\n", i); goto fail; } snprintf(strTemp, sizeof(strTemp), "Texture[%u]", i); uniformLoc = glGetUniformLocation(g_program, strTemp); glUniform1i(uniformLoc, i); if (!piglit_check_gl_error(GL_NO_ERROR)) { fprintf(stderr, "Unable to assign texture %u uniform.\n", i); goto fail; } } /* * Setup the vertex and element buffers for drawing our points. */ if (g_drawMode != DRAW_IMMEDIATE) { glGenVertexArrays(1, &vao); glBindVertexArray(vao); if (!piglit_check_gl_error(GL_NO_ERROR)) { fprintf(stderr, "Unable to create VAO.\n"); goto fail; } setup_vertex_element_buffers(); } /* * Setup the raster state. */ glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawBuffers(g_maxColorAttachments, colorBuffers); if (!piglit_check_gl_error(GL_NO_ERROR)) { fprintf(stderr, "Unable to assign draw buffers.\n"); goto fail; } glClearColor(0.0, 1.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* * Bind the vertex array and enable each attribute. */ if (g_drawMode != DRAW_IMMEDIATE) { glBindVertexArray(vao); attribLoc = glGetAttribLocation(g_program, "InPosition"); glEnableVertexAttribArray(attribLoc); if (!piglit_check_gl_error(GL_NO_ERROR)) { fprintf(stderr, "Unable to enable vertex array attribute %u.\n", attribLoc); goto fail; } /* * Enable the rest of the attributes. */ for (i = 0; i < g_maxVertexAttribs - 1; i++) { char strTemp[16]; snprintf(strTemp, sizeof(strTemp), "InValue%u", i); attribLoc = glGetAttribLocation(g_program, strTemp); glEnableVertexAttribArray(attribLoc); if (!piglit_check_gl_error(GL_NO_ERROR)) { fprintf(stderr, "Unable to enable vertex array attribute %u.\n", attribLoc); goto fail; } } if (g_drawMode == DRAW_ARRAYS_VBO) { if (g_debugMask & DEBUG_DRAW) { fprintf(stderr, "Draw mode DRAW_ARRAYS_VBO\n"); } glDrawArrays(GL_TRIANGLES, 0, NUM_VERTICES); } if (g_drawMode == DRAW_ELEMENTS_VBO) { if (g_debugMask & DEBUG_DRAW) { fprintf(stderr, "Draw mode DRAW_ELEMENTS_VBO\n"); } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_elementVBO); glDrawElements(GL_TRIANGLES, NUM_VERTICES, GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } /* * Blindly reset all the attributes. */ for (i = 0; i < g_maxVertexAttribs; i++) { glDisableVertexAttribArray(i); } } else { glBegin(GL_TRIANGLES); glVertex3f(-1.0, -1.0, 0.0); glVertex3f(-1.0, 1.0, 0.0); glVertex3f(1.0, 1.0, 0.0); glEnd(); } if (!piglit_check_gl_error(GL_NO_ERROR)) goto fail; /* * Read back the FBO contents. */ /* * Disable color clamping so we don't encounter result * collisions attempting to use a normalized color space. * * Requires OpenGL 3.0 */ glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); for (i = 0; i < g_maxColorAttachments; i++) { if (g_debugMask & DEBUG_READBACK) { printf("GL_READ_FRAMEBUFFER <- fbo=%u\n", fbo); } glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); if (!piglit_check_gl_error(GL_NO_ERROR)) goto fail; glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTextures[i], 0); if (!piglit_check_gl_error(GL_NO_ERROR)) goto fail; glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadBuffer(GL_COLOR_ATTACHMENT0); if (!piglit_check_gl_error(GL_NO_ERROR)) goto fail; glReadPixels(0, BUFFER_HEIGHT - 1, 1, 1, GL_RGBA, GL_FLOAT, result); if ((g_expected[(i * MAX_COMPONENTS) + 0] != result[0]) || (g_expected[(i * MAX_COMPONENTS) + 1] != result[1]) || (g_expected[(i * MAX_COMPONENTS) + 2] != result[2]) || (g_expected[(i * MAX_COMPONENTS) + 3] != result[3])) { fprintf(stderr, "GL_COLOR_ATTACHMENT%u: expected " "(%f, %f, %f, %f) != (%f, %f, %f, %f)\n", i, g_expected[(i * MAX_COMPONENTS) + 0], g_expected[(i * MAX_COMPONENTS) + 1], g_expected[(i * MAX_COMPONENTS) + 2], g_expected[(i * MAX_COMPONENTS) + 3], result[0], result[1], result[2], result[3]); goto fail; } } piglit_present_results(); /* * Cleanup the allocations. */ free(colorBuffers); free(fboTextures); piglit_report_result(PIGLIT_PASS); return PIGLIT_PASS; fail: if (colorBuffers) free(colorBuffers); if (fboTextures) free(fboTextures); piglit_report_result(PIGLIT_FAIL); return PIGLIT_FAIL; }