static int BlendFunc(lua_State *L) { GLuint buf; GLenum sfactor, dfactor, sfactorAlpha, dfactorAlpha; if(lua_isinteger(L, 1)) { buf = luaL_checkinteger(L, 1); sfactor = checkblendfactor(L, 2); dfactor = checkblendfactor(L, 3); if(lua_isstring(L, 4)) { sfactorAlpha = checkblendfactor(L, 4); dfactorAlpha = checkblendfactor(L, 5); glBlendFuncSeparatei(buf, sfactor, dfactor, sfactorAlpha, dfactorAlpha); } else glBlendFunci(buf, sfactor, dfactor); } else { sfactor = checkblendfactor(L, 1); dfactor = checkblendfactor(L, 2); if(lua_isstring(L, 3)) { sfactorAlpha = checkblendfactor(L, 3); dfactorAlpha = checkblendfactor(L, 4); glBlendFuncSeparate(sfactor, dfactor, sfactorAlpha, dfactorAlpha); } else glBlendFunc(sfactor, dfactor); } CheckError(L); return 0; }
void SceneManager::Render(Camera * camera) { Shader *R2T = Manager::Shader->GetShader("rendertargets"); R2T->Use(); camera->BindPosition(R2T->loc_eye_pos); camera->BindViewMatrix(R2T->loc_view_matrix); camera->BindProjectionMatrix(R2T->loc_projection_matrix); glUniform1f(R2T->loc_transparency, 1); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); list<GameObject*> transparentObjects; for (auto *obj : frustumObjects) { if (obj->mesh && obj->mesh->meshType == MeshType::STATIC) { if (obj->renderer->IsTransparent()) { transparentObjects.push_back(obj); } else { obj->Render(R2T); } } } // Render transparent objects glEnable(GL_BLEND); glBlendEquationi(0, GL_FUNC_ADD); glBlendFunci(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for (auto *obj : transparentObjects) { if (obj->mesh && obj->mesh->meshType == MeshType::STATIC) { glUniform1f(R2T->loc_transparency, obj->renderer->GetOpacity()); obj->Render(R2T); } } glUniform1f(R2T->loc_transparency, 0.3f); for (auto *obj : lights) { obj->Render(R2T); } glDisable(GL_BLEND); // Render Skinned meshes Shader *R2TSk = Manager::Shader->GetShader("r2tskinning"); if (R2TSk) { R2TSk->Use(); camera->BindPosition(R2TSk->loc_eye_pos); camera->BindViewMatrix(R2TSk->loc_view_matrix); camera->BindProjectionMatrix(R2TSk->loc_projection_matrix); for (auto *obj : frustumObjects) { if (obj->mesh && obj->mesh->meshType == MeshType::SKINNED) { obj->Render(R2TSk); } } } }
void raytracer_app::recurse(int depth) { glBindFramebuffer(GL_FRAMEBUFFER, ray_fbo[depth + 1]); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 }; glDrawBuffers(6, draw_buffers); glEnablei(GL_BLEND, 0); glBlendFunci(0, GL_ONE, GL_ONE); // static const float zeros[] = { 0.0f, 0.0f, 0.0f, 0.0f }; // glClearBufferfv(GL_COLOR, 0, zeros); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_position[depth]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tex_reflected[depth]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, tex_reflection_intensity[depth]); // Render glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); if (depth != (max_depth - 1)) { recurse(depth + 1); } //*/ /* if (depth != 0) { glBindTexture(GL_TEXTURE_2D, tex_refracted[depth]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, tex_refraction_intensity[depth]); // Render glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); if (depth != (max_depth - 1)) { recurse(depth + 1); } } //**/ glDisablei(GL_BLEND, 0); }
void PipelineImpl::setColorState(GlState& state) const { if(state.m_stateHashes.m_color == m_hashes.m_color) { return; } state.m_stateHashes.m_color = m_hashes.m_color; if(m_blendEnabled) { glEnable(GL_BLEND); for(U i = 0; i < m_in.m_color.m_attachmentCount; ++i) { const Attachment& att = m_cache.m_attachments[i]; glBlendFunci(i, att.m_srcBlendMethod, att.m_dstBlendMethod); glBlendEquationi(i, att.m_blendFunction); glColorMaski(i, att.m_channelWriteMask[0], att.m_channelWriteMask[1], att.m_channelWriteMask[2], att.m_channelWriteMask[3]); state.m_colorWriteMasks[i][0] = att.m_channelWriteMask[0]; state.m_colorWriteMasks[i][1] = att.m_channelWriteMask[1]; state.m_colorWriteMasks[i][2] = att.m_channelWriteMask[2]; state.m_colorWriteMasks[i][3] = att.m_channelWriteMask[3]; } } else { glDisable(GL_BLEND); for(U i = 0; i < m_in.m_color.m_attachmentCount; ++i) { const Attachment& att = m_cache.m_attachments[i]; glColorMaski(i, att.m_channelWriteMask[0], att.m_channelWriteMask[1], att.m_channelWriteMask[2], att.m_channelWriteMask[3]); state.m_colorWriteMasks[i][0] = att.m_channelWriteMask[0]; state.m_colorWriteMasks[i][1] = att.m_channelWriteMask[1]; state.m_colorWriteMasks[i][2] = att.m_channelWriteMask[2]; state.m_colorWriteMasks[i][3] = att.m_channelWriteMask[3]; } } }
int main() { // Create and initialize window. setErrorCallbackAndInit(error_callback); GraphicsWindow* window = new GraphicsWindow(1200,800,"Test Window",NULL,NULL,key_callback); window->makeContextCurrent(); // Initalize glew. initGlew(); // Create and initialize Camera FreeCamera* camera = new FreeCamera(45.0f, 16.0f/9.0f, 0.0f, 0.0f, 0.1f, 10000.0f, 0.0004f, 3.0f, glm::vec3(0,0,-50), glm::vec3(0,1,0), glm::vec3(0,0,0), true); camera->setViewport(window->getWindowWidth(),window->getWindowHeight(),0.5f,0.5f); // Load accumulation shader for accumulating all the transparent matrials, as well as their alphas. GLSLProgram* defaultShader = new GLSLProgram(); defaultShader->initShaderProgram("Vert.glsl","","","","Frag.glsl"); // Load screen filling quad shader. GLSLProgram* screenFillingQuadShader = new GLSLProgram(); screenFillingQuadShader->initShaderProgram("screenFillingQuadVert.glsl","","","","screenFillingQuadFrag.glsl"); // Load accumulation shader for accumulating all the transparent matrials, as well as their alphas. GLSLProgram* accumTransparencyRevealageShader = new GLSLProgram(); accumTransparencyRevealageShader->initShaderProgram("AccumTransparencyRevealageVert.glsl","","","","AccumTransparencyRevealageFrag.glsl"); // Load Weighted Average shader, which will be used for final compositing (a variation of screen filling quad shader using multiple textures). GLSLProgram* newOITCoverageShader = new GLSLProgram(); newOITCoverageShader->initShaderProgram("NewOITCoverageVert.glsl","","","","NewOITCoverageFrag.glsl"); // Create screen filling quad. Quad* screenFillingQuad = new Quad(glm::vec3(-1.0,1.0,0), glm::vec3(-1.0,-1.0,0), glm::vec3(1.0,-1.0,0), glm::vec3(1.0,1.0,0), glm::vec3(0), 0, 0, 0); screenFillingQuad->initQuad(); screenFillingQuad->setGLSLProgram(*newOITCoverageShader); TextureManager::GetInstance().loadTexture("../Content/Textures/Particle_Smoke/smoke_particle_red_base.png"); TextureManager::GetInstance().loadTexture("../Content/Textures/Particle_Smoke/smoke_particle_grey_base_2.png"); TextureManager::GetInstance().loadTexture("../Content/Textures/Particle_Smoke/smoke_particle_grey_base_3.png"); Quad* quad1 = new Quad(glm::vec3(100+100,100+100,-1), glm::vec3(100+100,-100+100,-1), glm::vec3(-100+100,-100+100,-1), glm::vec3(-100+100,100+100,-1), glm::vec3(0), 10, 10, 0); quad1->initQuad(); quad1->initDefaultTexture(255,0,0,89); quad1->setTexture(TextureManager::GetInstance().getTextureHandle("../Content/Textures/Particle_Smoke/smoke_particle_grey_base_3.png")); Quad* quad2 = new Quad(glm::vec3(100+100,100+100,-20), glm::vec3(100+100,-100+100,-20), glm::vec3(-100+100,-100+100,-20), glm::vec3(-100+100,100+100,-20), glm::vec3(0), 10, 10, 0); quad2->initQuad(); quad2->initDefaultTexture(0,255,0,89); quad2->setTexture(TextureManager::GetInstance().getTextureHandle("../Content/Textures/Particle_Smoke/smoke_particle_grey_base_2.png")); Quad* quad3 = new Quad(glm::vec3(100+100,100+100,20), glm::vec3(100+100,-100+100,20), glm::vec3(-100+100,-100+100,20), glm::vec3(-100+100,100+100,20), glm::vec3(0), 10, 10, 0); quad3->initQuad(); quad3->initDefaultTexture(0,0,255,89); quad3->setTexture(TextureManager::GetInstance().getTextureHandle("../Content/Textures/Particle_Smoke/smoke_particle_red_base.png")); Quad* quad4 = new Quad(glm::vec3(100+100,100+100,-40), glm::vec3(100+100,-100+100,-40), glm::vec3(-100+100,-100+100,-40), glm::vec3(-100+100,100+100,-40), glm::vec3(0), 10, 10, 0); quad4->initQuad(); quad4->initDefaultTexture(255,0,127,50); Quad* quad5 = new Quad(glm::vec3(100+100,100+100,40), glm::vec3(100+100,-100+100,40), glm::vec3(-100+100,-100+100,40), glm::vec3(-100+100,100+100,40), glm::vec3(0), 10, 10, 0); quad5->initQuad(); quad5->initDefaultTexture(255,127,0,50); ModelLoader* modelImporter = new ModelLoader(); modelImporter->importModel("../Content/Models/crytek-sponza/sponza.obj", processFlagsOnModelImport); // Create and initialize model Model* model = new Model(glm::vec3(0,0,0), "../Content/Models/crytek-sponza/"); model->loadModel(modelImporter->getScene()); // Create framebuffers std::vector<unsigned int> activeColorAttachmentsOpaque; std::vector<unsigned int> activeColorAttachmentsTransparent; Framebuffer* opaqueFrameBuffer = new Framebuffer(window->getWindowWidth(),window->getWindowHeight()); activeColorAttachmentsOpaque.push_back(0); opaqueFrameBuffer->setColorAttachment(0); //frameBuffer->setDepthAttachment(); opaqueFrameBuffer->setDepthStencilTexture(); opaqueFrameBuffer->unbind(); Framebuffer* accumFrameBuffer = new Framebuffer(window->getWindowWidth(),window->getWindowHeight()); activeColorAttachmentsTransparent.push_back(0); activeColorAttachmentsTransparent.push_back(1); accumFrameBuffer->setColorAttachment(0); accumFrameBuffer->setColorAttachment(1); //frameBuffer->setDepthAttachment(); accumFrameBuffer->setDepthStencilTexture(); accumFrameBuffer->unbind(); // Additional textures to pass for the second transparency render pass. std::vector<GLuint> additionalTextureHandles; additionalTextureHandles.push_back(accumFrameBuffer->getColorAttachment(0)); additionalTextureHandles.push_back(accumFrameBuffer->getColorAttachment(1)); std::vector<GLuint> opaqueTextureHandle; opaqueTextureHandle.push_back(opaqueFrameBuffer->getColorAttachment(0)); // Move this to "GraphicsWindow" glfwSetCursorPos(window->getWindowHandle(), (double) (window->getWindowWidth()/2.0), (double) (window->getWindowHeight()/2.0)); // Move this to "Camera" //glClearColor(0.4f,0.6f,0.94f,0.0f); glClearColor(0.0f,0.0f,0.0f,0.0f); const float clearColorWhite = 1.0f; const float clearColorBlack = 0.0f; // Sampler GLuint sampler = 0; glGenSamplers(1, &sampler); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); check_gl_error(); // Render Loop while(!window->shouldClose()) { //glClearColor(0.0f,0.0f,0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Update camera camera->camControll(window->getWindowHandle()); camera->update(); // Update shader uniforms model->getCurrentGLSLProgram()->use(); model->getCurrentGLSLProgram()->setUniform("lightPosition", camera->getCamPos()); model->getCurrentGLSLProgram()->setUniform("camPosition", camera->getCamPos()); model->getCurrentGLSLProgram()->setUniform("viewMatrix", camera->getVMatrix()); model->getCurrentGLSLProgram()->setUniform("normalMatrix", camera->getTranspInvMVMatrix()); // Change this! model->getCurrentGLSLProgram()->setUniform("VPMatrix", camera->getVPMatrix()); opaqueFrameBuffer->clean(); opaqueFrameBuffer->bind(); opaqueFrameBuffer->bindForRenderPass(activeColorAttachmentsOpaque); model->renderOpaque(); //quad4->render(); //quad5->render(); //opaqueFrameBuffer->unbind(); //// Blitting the opaque scene depth to propperly depth test the transparen against it. //opaqueFrameBuffer->bindForReading(); //accumFrameBuffer->bindForWriting(); //glBlitFramebuffer(0, 0, window->getWindowWidth(), window->getWindowHeight(), 0, 0, window->getWindowWidth(), window->getWindowHeight(), // GL_DEPTH_BUFFER_BIT, GL_NEAREST); //opaqueFrameBuffer->unbind(); //_______________________________________________________________________________________________________________________________________________________________________________ // Acuumulation pass accumTransparencyRevealageShader->use(); accumTransparencyRevealageShader->setUniform("VPMatrix", camera->getVPMatrix()); model->setGLSLProgram(accumTransparencyRevealageShader); quad1->setGLSLProgram(*accumTransparencyRevealageShader); quad2->setGLSLProgram(*accumTransparencyRevealageShader); quad3->setGLSLProgram(*accumTransparencyRevealageShader); quad4->setGLSLProgram(*accumTransparencyRevealageShader); quad5->setGLSLProgram(*accumTransparencyRevealageShader); accumFrameBuffer->clean(); accumFrameBuffer->bind(); accumFrameBuffer->bindForRenderPass(activeColorAttachmentsTransparent); accumFrameBuffer->cleanColorAttachment(1,clearColorWhite); opaqueFrameBuffer->unbind(); // Blitting the opaque scene depth to propperly depth test the transparen against it. opaqueFrameBuffer->bindForReading(); accumFrameBuffer->bindForWriting(); glBlitFramebuffer(0, 0, window->getWindowWidth(), window->getWindowHeight(), 0, 0, window->getWindowWidth(), window->getWindowHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); opaqueFrameBuffer->unbind(); accumFrameBuffer->bind(); accumFrameBuffer->bindForRenderPass(activeColorAttachmentsTransparent); glEnable(GL_BLEND); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); //glEnable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); model->renderTransparent(); quad1->render(); quad2->render(); quad3->render(); //quad4->render(); //quad5->render(); accumFrameBuffer->unbind(); model->setGLSLProgram(defaultShader); quad1->setGLSLProgram(*defaultShader); quad2->setGLSLProgram(*defaultShader); quad3->setGLSLProgram(*defaultShader); quad4->setGLSLProgram(*defaultShader); quad5->setGLSLProgram(*defaultShader); glDisable(GL_BLEND); //glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); //_______________________________________________________________________________________________________________________________________________________________________________ // Final compositing pass //screenFillingQuad->setGLSLProgram(*screenFillingQuadShader); //screenFillingQuad->getCurrentShaderProgram()->use(); //screenFillingQuad->renderWithAdditionalTextures(opaqueTextureHandle,sampler); newOITCoverageShader->use(); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); screenFillingQuad->renderWithAdditionalTextures(additionalTextureHandles,sampler); glDepthMask(GL_TRUE); glDisable(GL_BLEND); //_______________________________________________________________________________________________________________________________________________________________________________ // For debug! //screenFillingQuad->setGLSLProgram(*screenFillingQuadShader); //screenFillingQuad->getCurrentShaderProgram()->use(); //screenFillingQuad->setTexture(opaqueFrameBuffer->getColorAttachment(0)); //screenFillingQuad->render(); accumFrameBuffer->clean(); window->swapBuffers(); glfwPollEvents(); check_gl_error(); } glfwTerminate(); window->release(); return 0; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengles_GLES32_glBlendFunci(JNIEnv *__env, jclass clazz, jint buf, jint src, jint dst) { glBlendFunciPROC glBlendFunci = (glBlendFunciPROC)tlsGetFunction(331); UNUSED_PARAM(clazz) glBlendFunci(buf, src, dst); }
//! glBlendFunci wrapper. May throw. inline void blendFunci(GLuint const buf, GLenum const src, GLenum const dst) { glBlendFunci(buf, src, dst); checkError("glBlendFunci"); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL40_nglBlendFunci(JNIEnv *__env, jclass clazz, jint buf, jint sfactor, jint dfactor, jlong __functionAddress) { glBlendFunciPROC glBlendFunci = (glBlendFunciPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glBlendFunci(buf, sfactor, dfactor); }
void Renderer::renderInternal( const RenderData& renderData ) { m_fbo->useAsTarget(); GL_ASSERT( glDepthMask( GL_TRUE ) ); GL_ASSERT( glColorMask( 1, 1, 1, 1 ) ); GL_ASSERT( glDrawBuffers( 6, buffers ) ); const Core::Color clearColor( 0.6, 0.6, 0.6, 1.0 ); const Core::Color clearZeros( 0.0, 0.0, 0.0, 0.0 ); const Core::Color clearOnes( 1.0, 1.0, 1.0, 1.0 ); const Scalar clearDepth( 1.0 ); GL_ASSERT( glClearBufferfv( GL_COLOR, 0, clearColor.data() ) ); // Clear ambient GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearZeros.data() ) ); // Clear position GL_ASSERT( glClearBufferfv( GL_COLOR, 2, clearZeros.data() ) ); // Clear normal GL_ASSERT( glClearBufferfv( GL_COLOR, 3, clearOnes.data() ) ); // Clear picking GL_ASSERT( glClearBufferfv( GL_COLOR, 4, clearZeros.data() ) ); // Clear color GL_ASSERT( glClearBufferfv( GL_COLOR, 5, clearZeros.data() ) ); // Clear renderpass GL_ASSERT( glClearBufferfv( GL_DEPTH, 0, &clearDepth ) ); // Clear depth // Z + Ambient Prepass GL_ASSERT( glEnable( GL_DEPTH_TEST ) ); GL_ASSERT( glDepthFunc( GL_LESS ) ); GL_ASSERT( glDepthMask( GL_TRUE ) ); GL_ASSERT( glDisable( GL_BLEND ) ); GL_ASSERT( glDrawBuffers( 4, buffers ) ); // Draw ambient, position, normal, picking m_depthAmbientShader->bind(); m_opaqueRenderQueue.render( m_depthAmbientShader ); #ifdef NO_TRANSPARENCY m_transparentRenderQueue.render( m_depthAmbientShader ); #endif // Light pass GL_ASSERT( glDepthFunc( GL_LEQUAL ) ); GL_ASSERT( glDepthMask( GL_FALSE ) ); GL_ASSERT( glEnable( GL_BLEND ) ); GL_ASSERT( glBlendFunc( GL_ONE, GL_ONE ) ); GL_ASSERT( glDrawBuffers( 1, buffers + 4 ) ); // Draw color texture if ( m_lights.size() > 0 ) { for ( const auto& l : m_lights ) { // TODO(Charly): Light render params RenderParameters params; l->getRenderParameters( params ); m_opaqueRenderQueue.render( params ); #ifdef NO_TRANSPARENCY m_transparentRenderQueue.render( params ); #endif } } else { DirectionalLight l; l.setDirection( Core::Vector3( 0.3f, 1, 0 ) ); RenderParameters params; l.getRenderParameters( params ); m_opaqueRenderQueue.render( params ); #ifdef NO_TRANSPARENCY m_transparentRenderQueue.render( params ); #endif } // Draw debug stuff, do not overwrite depth map but do depth testing GL_ASSERT( glDisable( GL_BLEND ) ); GL_ASSERT( glDepthMask( GL_FALSE ) ); GL_ASSERT( glEnable( GL_DEPTH_TEST ) ); GL_ASSERT( glDepthFunc( GL_LESS ) ); m_debugRenderQueue.render(); // Draw UI stuff, always drawn on top of everything else GL_ASSERT( glDepthFunc( GL_ALWAYS ) ); m_uiRenderQueue.render(); m_fbo->unbind(); #ifndef NO_TRANSPARENCY m_oitFbo->useAsTarget(); GL_ASSERT( glDrawBuffers( 2, buffers ) ); // RT0 stores a sum, RT1 stores a product. GL_ASSERT( glClearBufferfv( GL_COLOR, 0, clearZeros.data() ) ); GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearOnes.data() ) ); GL_ASSERT( glDepthFunc( GL_LESS ) ); GL_ASSERT( glEnable( GL_BLEND ) ); GL_ASSERT( glBlendEquation( GL_FUNC_ADD ) ); GL_ASSERT( glBlendFunci( 0, GL_ONE, GL_ONE ) ); GL_ASSERT( glBlendFunci( 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA ) ); m_oiTransparencyShader->bind(); m_transparentRenderQueue.render( m_oiTransparencyShader ); GL_ASSERT( glDisable( GL_BLEND ) ); m_oitFbo->unbind(); #endif // Draw renderpass texture m_fbo->bind(); GL_ASSERT( glDrawBuffers( 1, buffers + 5 ) ); GL_ASSERT( glDepthFunc( GL_ALWAYS ) ); m_renderpassCompositingShader->bind(); m_renderpassCompositingShader->setUniform( "ambient", m_renderpassTextures[RENDERPASS_TEXTURE_AMBIENT].get(), 0 ); m_renderpassCompositingShader->setUniform( "color", m_renderpassTextures[RENDERPASS_TEXTURE_LIGHTED].get(), 1 ); m_renderpassCompositingShader->setUniform( "renderpass", 0 ); m_quadMesh->render(); #ifndef NO_TRANSPARENCY GL_ASSERT( glEnable( GL_BLEND ) ); GL_ASSERT( glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ) ); m_renderpassCompositingShader->setUniform( "oitSumColor", m_oitTextures[OITPASS_TEXTURE_ACCUM].get(), 2 ); m_renderpassCompositingShader->setUniform( "oitSumWeight", m_oitTextures[OITPASS_TEXTURE_REVEALAGE].get(), 3 ); m_renderpassCompositingShader->setUniform( "renderpass", 1 ); m_quadMesh->render(); #endif GL_ASSERT( glDepthFunc( GL_LESS ) ); GL_ASSERT( glDisable( GL_BLEND ) ); GL_ASSERT( glDepthMask( GL_TRUE ) ); GL_ASSERT( glDepthFunc( GL_LESS ) ); m_fbo->unbind(); }
void TopazSample::renderStandartWeightedBlendedOIT() { glEnable(GL_DEPTH_TEST); glDisable(GL_POLYGON_OFFSET_FILL); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_SCENE, ubos.sceneUbo); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_IDENTITY, ubos.identityUbo); glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); drawModel(GL_TRIANGLES, *shaderPrograms["draw"], *models.at(0)); glBindFramebuffer(GL_FRAMEBUFFER, 0); /* first pass oit */ glDisable(GL_DEPTH_TEST); // TODO : change on transparent list of models for (auto model = models.begin() + 1; model != models.end(); model++) { /* geometry pass */ { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); GLfloat clearColorZero[4] = { 0.0f }; GLfloat clearColorOne[4] = { 1.0f }; glClearBufferfv(GL_COLOR, 0, clearColorZero); glClearBufferfv(GL_COLOR, 1, clearColorOne); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); objectData.objectColor = nv::vec4f(1.0f, 1.0f, 1.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getBufferID("ubo"), 0, sizeof(ObjectData), &objectData); objectData.objectColor = nv::vec4f(1.0f, 0.0f, 0.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getCornerBufferID("ubo"), 0, sizeof(ObjectData), &objectData); drawModel(GL_TRIANGLES, *shaderPrograms["weightBlended"], **model); glDisable(GL_BLEND); CHECK_GL_ERROR(); } /* composition pass */ { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OIT, ubos.weightBlendedUbo, 0, sizeof(WeightBlendedData)); // check uniform buffer offset { const char* uniformNames[] = { "weightBlendedData.background", "weightBlendedData.colorTex0", "weightBlendedData.colorTex1" }; std::unique_ptr<GLint> parameters(new GLint[3]); std::unique_ptr<GLuint> uniformIndices(new GLuint[3]); glGetUniformIndices(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformNames, uniformIndices.get()); glGetActiveUniformsiv(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformIndices.get(), GL_UNIFORM_OFFSET, parameters.get()); GLint* offset = parameters.get(); } { shaderPrograms["weightBlendedFinal"]->enable(); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(VERTEX_POS, 0); glEnableVertexAttribArray(VERTEX_POS); glBindVertexBuffer(0, fullScreenRectangle.vboFullScreen, 0, sizeof(nv::vec3f)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); shaderPrograms["weightBlendedFinal"]->disable(); } CHECK_GL_ERROR(); } } }
void TopazSample::initCommandListWeightBlended() { if (!isTokenInternalsInited) { hwsupport = init_NV_command_list(sysGetProcAddress) ? true : false; nvtokenInitInternals(hwsupport, bindlessVboUbo); isTokenInternalsInited = true; } enum States { STATE_CLEAR, STATE_OPAQUE, STATE_TRANSPARENT, STATE_TRASPARENT_LINES, STATE_COMPOSITE, STATES_COUNT }; if (hwsupport) { for (size_t i = 0; i < STATES_COUNT; i++) { glCreateStatesNV(1, &cmdlist.stateObjectsWeightBlended[i]); } glGenBuffers(1, &cmdlist.tokenBufferWeightBlended); glCreateCommandListsNV(1, &cmdlist.tokenCmdListWeightBlended); } NVTokenSequence& seq = cmdlist.tokenSequenceWeightBlended; std::string& stream = cmdlist.tokenDataWeightBlended; size_t offset = 0; { NVTokenUbo ubo; ubo.setBuffer(ubos.sceneUbo, ubos.sceneUbo64, 0, sizeof(SceneData)); ubo.setBinding(UBO_SCENE, NVTOKEN_STAGE_VERTEX); nvtokenEnqueue(stream, ubo); ubo.setBinding(UBO_SCENE, NVTOKEN_STAGE_FRAGMENT); nvtokenEnqueue(stream, ubo); } // 1. render 'background' into framebuffer 'fbos.scene' { auto& model = models.at(0); setTokenBuffers(model.get(), stream); NVTokenDrawElems draw; draw.setParams(model->getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES)); draw.setMode(GL_TRIANGLES); nvtokenEnqueue(stream, draw); pushTokenParameters(seq, offset, stream, fbos.scene, cmdlist.stateObjectsWeightBlended[STATE_OPAQUE]); } // 2. geometry pass OIT for (auto model = models.begin() + 1; model != models.end(); model++) { // like call glClearBufferfv { NVTokenVbo vbo; vbo.setBinding(0); vbo.setBuffer(fullScreenRectangle.vboFullScreen, fullScreenRectangle.vboFullScreen64, 0); nvtokenEnqueue(stream, vbo); NVTokenUbo ubo; ubo.setBuffer(ubos.identityUbo, ubos.identityUbo64, 0, sizeof(IdentityData)); ubo.setBinding(UBO_IDENTITY, NVTOKEN_STAGE_VERTEX); nvtokenEnqueue(stream, ubo); NVTokenDrawArrays draw; draw.setParams(4, 0); draw.setMode(GL_TRIANGLE_STRIP); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_CLEAR]); // 2. geometry pass { setTokenBuffers((*model).get(), stream); NVTokenDrawElems draw; draw.setParams((*model)->getModel()->getCompiledIndexCount(NvModelPrimType::TRIANGLES)); draw.setMode(GL_TRIANGLES); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_TRANSPARENT]); { setTokenBuffers((*model).get(), stream, true); NVTokenDrawElems draw; draw.setParams((*model)->getCornerIndices().size()); draw.setMode(GL_LINE_STRIP); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, oit->getFramebufferID(), cmdlist.stateObjectsWeightBlended[STATE_TRASPARENT_LINES]); // 3. composite pass { NVTokenVbo vbo; vbo.setBinding(0); vbo.setBuffer(fullScreenRectangle.vboFullScreen, fullScreenRectangle.vboFullScreen64, 0); nvtokenEnqueue(stream, vbo); NVTokenUbo ubo; ubo.setBuffer(ubos.identityUbo, ubos.identityUbo64, 0, sizeof(IdentityData)); ubo.setBinding(UBO_IDENTITY, NVTOKEN_STAGE_VERTEX); nvtokenEnqueue(stream, ubo); NVTokenUbo uboWeightBlended; uboWeightBlended.setBuffer(ubos.weightBlendedUbo, ubos.weightBlendedUbo64, 0, sizeof(WeightBlendedData)); uboWeightBlended.setBinding(UBO_OIT, NVTOKEN_STAGE_FRAGMENT); nvtokenEnqueue(stream, uboWeightBlended); NVTokenDrawArrays draw; draw.setParams(4, 0); draw.setMode(GL_TRIANGLE_STRIP); nvtokenEnqueue(stream, draw); } pushTokenParameters(seq, offset, stream, fbos.scene, cmdlist.stateObjectsWeightBlended[STATE_COMPOSITE]); } if (hwsupport) { glNamedBufferStorageEXT(cmdlist.tokenBufferWeightBlended, cmdlist.tokenDataWeightBlended.size(), &cmdlist.tokenDataWeightBlended.at(0), 0); cmdlist.tokenSequenceListWeightBlended = cmdlist.tokenSequenceWeightBlended; for (size_t i = 0; i < cmdlist.tokenSequenceListWeightBlended.offsets.size(); i++) { cmdlist.tokenSequenceListWeightBlended.offsets[i] += (GLintptr)&cmdlist.tokenDataWeightBlended.at(0); } } glEnableVertexAttribArray(VERTEX_POS); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(VERTEX_POS, 0); glEnable(GL_DEPTH_TEST); // 1. opaque modes { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); shaderPrograms["draw"]->enable(); glBindVertexBuffer(0, 0, 0, 9 * sizeof(float)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_OPAQUE], GL_TRIANGLES); shaderPrograms["draw"]->disable(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } glDisable(GL_DEPTH_TEST); // like a glClearBufferfv { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); shaderPrograms["clear"]->enable(); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_CLEAR], GL_TRIANGLES); shaderPrograms["clear"]->disable(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // 2. oit first step { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); // ??? //glEnable(GL_POLYGON_STIPPLE); //glPolygonStipple(brushStyle->brushPattern8to32(QtStyles::DiagCrossPattern).data()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); shaderPrograms["weightBlended"]->enable(); glBindVertexBuffer(0, 0, 0, 9 * sizeof(float)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_TRANSPARENT], GL_TRIANGLES); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_TRASPARENT_LINES], GL_LINES); shaderPrograms["weightBlended"]->disable(); // ??? //glDisable(GL_POLYGON_STIPPLE); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // 3. oit second step { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glDisable(GL_BLEND); shaderPrograms["weightBlendedFinal"]->enable(); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjectsWeightBlended[STATE_COMPOSITE], GL_TRIANGLES); shaderPrograms["weightBlendedFinal"]->disable(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } // compile command list NVTokenSequence& sequenceList = cmdlist.tokenSequenceListWeightBlended; glCommandListSegmentsNV(cmdlist.tokenCmdListWeightBlended, 1); glListDrawCommandsStatesClientNV(cmdlist.tokenCmdListWeightBlended, 0, (const void**)&sequenceList.offsets[0], &sequenceList.sizes[0], &sequenceList.states[0], &sequenceList.fbos[0], int(sequenceList.states.size())); glCompileCommandListNV(cmdlist.tokenCmdListWeightBlended); }