/** * @brief * Sets a color render target */ void SurfaceTextureBuffer::SetColorRenderTarget(uint8 nColorIndex, PLRenderer::TextureBuffer *pTextureBuffer) { // Check color index if (nColorIndex < m_nMaxColorTargets) { // Set color render target while (!m_lstTextureBufferHandler[nColorIndex]) { PLRenderer::ResourceHandler *pTextureBufferHandler = new PLRenderer::ResourceHandler(); m_lstTextureBufferHandler.Add(pTextureBufferHandler); } PLRenderer::ResourceHandler *pTextureBufferHandler = m_lstTextureBufferHandler[nColorIndex]; pTextureBufferHandler->SetResource(pTextureBuffer); // Check FBO if (m_pFrameBufferObject && pTextureBuffer) { m_pFrameBufferObject->Bind(); m_pFrameBufferObject->SwitchTarget(*pTextureBuffer, nColorIndex); // Get extensions instance const Extensions &cExtensions = static_cast<Renderer&>(GetRenderer()).GetContext().GetExtensions(); // Set draw buffers static const GLuint db[16] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT, GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT, GL_COLOR_ATTACHMENT8_EXT, GL_COLOR_ATTACHMENT9_EXT, GL_COLOR_ATTACHMENT10_EXT, GL_COLOR_ATTACHMENT11_EXT, GL_COLOR_ATTACHMENT12_EXT, GL_COLOR_ATTACHMENT13_EXT, GL_COLOR_ATTACHMENT14_EXT, GL_COLOR_ATTACHMENT15_EXT}; if (cExtensions.IsGL_ARB_draw_buffers()) glDrawBuffersARB(m_nMaxColorTargets, db); else if (cExtensions.IsGL_ATI_draw_buffers()) glDrawBuffersATI(m_nMaxColorTargets, db); } } }
bool SurfaceTextureBuffer::MakeCurrent(uint8 nFace) { // Check whether the data is valid and whether there's a texture buffer if (m_cTextureBufferHandler.GetResource() && GetTextureBuffer()) { // Set target face if (GetTextureBuffer()->GetType() == PLRenderer::Resource::TypeTextureBufferCube) m_nFace = nFace; else m_nFace = 0; // Cleanup texture buffer handlers for (uint32 i=0; i<m_lstTextureBufferHandler.GetNumOfElements(); i++) delete m_lstTextureBufferHandler[i]; m_lstTextureBufferHandler.Clear(); // Add primary texture buffer handler PLRenderer::ResourceHandler *pTextureBufferHandler = new PLRenderer::ResourceHandler(); pTextureBufferHandler->SetResource(m_cTextureBufferHandler.GetResource()); m_lstTextureBufferHandler.Add(pTextureBufferHandler); // Frame buffer object used? if (m_pFrameBufferObject && m_cTextureBufferHandler.GetResource()) { m_pFrameBufferObject->SwitchTarget(static_cast<PLRenderer::TextureBuffer&>(*m_cTextureBufferHandler.GetResource()), 0, nFace); m_pFrameBufferObject->Bind(); // Need rendering to depth only PLRenderer::TextureBuffer::EPixelFormat nFormat = GetTextureBuffer()->GetFormat(); if (nFormat == PLRenderer::TextureBuffer::D16 || nFormat == PLRenderer::TextureBuffer::D24 || nFormat == PLRenderer::TextureBuffer::D32) { glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } else { // Get extensions instance const Extensions &cExtensions = static_cast<Renderer&>(GetRenderer()).GetContext().GetExtensions(); // Set draw buffers static const GLuint db[16] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT, GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT, GL_COLOR_ATTACHMENT8_EXT, GL_COLOR_ATTACHMENT9_EXT, GL_COLOR_ATTACHMENT10_EXT, GL_COLOR_ATTACHMENT11_EXT, GL_COLOR_ATTACHMENT12_EXT, GL_COLOR_ATTACHMENT13_EXT, GL_COLOR_ATTACHMENT14_EXT, GL_COLOR_ATTACHMENT15_EXT}; if (cExtensions.IsGL_ARB_draw_buffers()) glDrawBuffersARB(m_nMaxColorTargets, db); else if (cExtensions.IsGL_ATI_draw_buffers()) glDrawBuffersATI(m_nMaxColorTargets, db); } // Else... } // ... If there's no frame buffer, we can still 'render to texture' by only using glCopyTexSubImage2D() to // copy the drawn stuff into a texture buffer. But this way, the current framebuffer content is 'overdrawn' and // the texture buffer size we can render in is limited to the screen size. // Enable/disable multisample - "shouldn't" have an effect when render to texture, but safe is safe :D GetRenderer().SetRenderState(PLRenderer::RenderState::MultisampleEnable, !(GetFlags() & NoMultisampleAntialiasing)); // Done return true; } // Error! return false; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ATIDrawBuffers_nglDrawBuffersATI(JNIEnv *env, jclass clazz, jint size, jobject buffers, jint buffers_position, jlong function_pointer) { const GLenum *buffers_address = ((const GLenum *)(*env)->GetDirectBufferAddress(env, buffers)) + buffers_position; glDrawBuffersATIPROC glDrawBuffersATI = (glDrawBuffersATIPROC)((intptr_t)function_pointer); glDrawBuffersATI(size, buffers_address); }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; GLuint tex0, tex1, fb; GLenum status; const GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, }; piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); tex0 = attach_texture(0); tex1 = attach_texture(1); glDrawBuffersATI(2, attachments); status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status); piglit_report_result(PIGLIT_SKIP); } /* Clear render targets (textures) to red */ glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glMultiTexCoord4fv(GL_TEXTURE0, result0); glMultiTexCoord4fv(GL_TEXTURE1, result1); glEnable(GL_FRAGMENT_PROGRAM_ARB); piglit_draw_rect(0, 0, piglit_width, piglit_height); glDisable(GL_FRAGMENT_PROGRAM_ARB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); /* Draw the two green textures to halves of the window. */ glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, tex0); piglit_draw_rect_tex(0, 0, piglit_width / 2, piglit_height, 0, 0, 1, 1); glBindTexture(GL_TEXTURE_2D, tex1); piglit_draw_rect_tex(piglit_width / 2, 0, piglit_width / 2, piglit_height, 0, 0, 1, 1); glDisable(GL_TEXTURE_2D); glDeleteTextures(1, &tex0); glDeleteTextures(1, &tex1); glDeleteFramebuffersEXT(1, &fb); pass = pass && piglit_probe_rect_rgba(0, 0, piglit_width / 2, piglit_height, result0); pass = pass && piglit_probe_rect_rgba(piglit_width / 2, 0, piglit_width / 2, piglit_height, result1); glutSwapBuffers(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }