/** * Generates a shadow map into the specified framebuffer. * @param rstate RenderState with rendering parameters * @param camera camera with light viewpoint * @param framebufferId ID of framebuffer to render shadow map into * @param scene_objects temporary storage for culling * @see Light::makeShadowMap Renderer::makeShadowMaps */ void GLRenderer::renderShadowMap(RenderState& rstate, Camera* camera, GLuint framebufferId, std::vector<SceneObject*>& scene_objects) { cullFromCamera(rstate.scene, camera, rstate.shader_manager, scene_objects); GLint drawFbo = 0, readFbo = 0; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFbo); glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFbo); const GLenum attachments[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferId)); GL(glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments)); GL(glViewport(rstate.viewportX, rstate.viewportY, rstate.viewportWidth, rstate.viewportHeight)); glClearColor(0,0,0,1); GL(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); rstate.shadow_map = true; for (auto it = render_data_vector.begin(); it != render_data_vector.end(); ++it) { RenderData* rdata = *it; if (rdata->cast_shadows()) { GL(renderRenderData(rstate, rdata)); } } rstate.shadow_map = false; GL(glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, &attachments[1])); glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo); }
/*!**************************************************************************** @Function RenderScene @Return bool true if no error occured @Description Main rendering loop function of the program. The shell will call this function every frame. eglSwapBuffers() will be performed by PVRShell automatically. PVRShell will also manage important OS events. Will also manage relevent OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLES3ShadowMapping::RenderScene() { Update(); // Bind the frame buffer object glBindFramebuffer(GL_FRAMEBUFFER, m_uiFrameBufferObject); // Clear the screen and depth buffer so we can render from the light's view glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); // Set the current viewport to our texture size but leave a one pixel margin. // As we are clamping to the edge of the texture when shadow mapping, no object // should be rendered to the border, otherwise stretching artefacts might occur // outside of the coverage of the shadow map. glViewport(1, 1, m_ui32ShadowMapSize-2, m_ui32ShadowMapSize-2); // Since we don't care about colour when rendering the depth values to // the shadow-map texture, we disable color writing to increase speed. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Cull the front faces, so that only the backfaces are rendered into the shadowmap glCullFace(GL_FRONT); // Draw everything that we would like to cast a shadow RenderSceneWithEffect(INDEX_RENDERSHADOW, m_mLightProjection, m_mLightView); // Set the culling mode for the normal rendering glCullFace(GL_BACK); // Turn colour buffer writes back on again glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Restore our normal viewport size to our screen width and height glViewport(0, 0,PVRShellGet(prefWidth),PVRShellGet(prefHeight)); //Invalidate the framebuffer attachments we don't need to avoid unnecessary copying to system memory const GLenum attachment = GL_COLOR_ATTACHMENT0; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachment); glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo); // Clear the colour and depth buffers, we are now going to render the scene again from scratch glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Load the shadow shader. This shader requires additional parameters; texProjMatrix for the depth buffer // look up and the light direction for diffuse light (the effect is a lot nicer with the addition of the // diffuse light). glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_uiShadowMapTexture); glActiveTexture(GL_TEXTURE0); RenderSceneWithEffect(INDEX_RENDERSCENE, m_mProjection, m_mView); m_Print3D.DisplayDefaultTitle("ShadowMap", "", ePVRTPrint3DSDKLogo); m_Print3D.Print3D(5.0f, 90.0f, 1.0f, 0xFFFFFFFF, "Bias: %f", m_fBias); m_Print3D.Flush(); return true; }
void GLRenderTexture::invalidateFrameBuffer(GLenum target, bool is_fbo, const bool color_buffer, const bool depth_buffer) { const int offset = (int) !color_buffer; const int count = (int) color_buffer + ((int) depth_buffer) * 2; const GLenum fboAttachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; const GLenum attachments[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; glInvalidateFramebuffer(target, count, (is_fbo ? fboAttachments : attachments) + offset); }
void GVRActivity::beginRenderingEye(const int eye) { frameBuffer_[eye].bind(); GL(glViewport(x, y, width, height)); GL(glScissor(0, 0, frameBuffer_[eye].mWidth, frameBuffer_[eye].mHeight)); GL(glInvalidateFramebuffer(GL_FRAMEBUFFER, sizeof(attachments)/sizeof(GLenum), attachments)); }
void FramebufferObject::invalidateAttachments(int Nums, GLenum* Attachments) { bind(); glInvalidateFramebuffer( GL_DRAW_BUFFER, Nums, Attachments); }
void RenderTextureArray::beginRendering() { const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; glViewport(0, 0, width(), height()); glScissor(0, 0, width(), height()); glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments); glClearColor(0, 0, 0, 1); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); }
void rtt::stop_draw() { check_fbo(current_buffer); if(current_buffer->anti_aliasing[0] != TEXTURE_ANTI_ALIASING::NONE && current_buffer->anti_aliasing[0] != TEXTURE_ANTI_ALIASING::SSAA_2 && current_buffer->anti_aliasing[0] != TEXTURE_ANTI_ALIASING::SSAA_4 && current_buffer->anti_aliasing[0] != TEXTURE_ANTI_ALIASING::FXAA && current_buffer->anti_aliasing[0] != TEXTURE_ANTI_ALIASING::SSAA_4_3_FXAA && current_buffer->anti_aliasing[0] != TEXTURE_ANTI_ALIASING::SSAA_2_FXAA) { if(current_buffer->depth_type == DEPTH_TYPE::RENDERBUFFER || current_buffer->depth_type == DEPTH_TYPE::TEXTURE_2D) { glBindFramebuffer(GL_READ_FRAMEBUFFER, current_buffer->fbo_id); for(size_t i = 0; i < current_buffer->attachment_count; i++) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_buffer->resolve_buffer[i]); #if !defined(FLOOR_IOS) || defined(PLATFORM_X64) glBlitFramebuffer(0, 0, (int)current_buffer->draw_width, (int)current_buffer->draw_height, 0, 0, (int)current_buffer->draw_width, (int)current_buffer->draw_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); #else glResolveMultisampleFramebufferAPPLE(); #endif } #if defined(FLOOR_IOS) #if !defined(PLATFORM_X64) // can only have one attachment static const array<GLenum, 2> discards {{ GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT }}; #else // can have multiple color attachments vector<GLenum> discards { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT }; for(size_t i = 1; i < current_buffer->attachment_count; i++) { discards.emplace_back(GL_COLOR_ATTACHMENT0 + i); } #endif glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, (int)discards.size(), &discards[0]); #endif } } for(unsigned int i = 0; i < current_buffer->attachment_count; i++) { if(current_buffer->auto_mipmap[i]) { // TODO: fix this //glBindTexture(current_buffer->target[i], current_buffer->tex[i]); //glGenerateMipmap(current_buffer->target[i]); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); }
void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments) { #ifndef MAGNUM_TARGET_GLES2 glInvalidateFramebuffer(GLenum(bindInternal()), count, attachments); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glDiscardFramebufferEXT(GLenum(bindInternal()), count, attachments); #else static_cast<void>(count); static_cast<void>(attachments); CORRADE_ASSERT_UNREACHABLE(); #endif }
void GVRActivity::beginRenderingEye(const int eye) { frameBuffer_[eye].bind(); GL(glViewport(x, y, width, height)); GL(glScissor(0, 0, frameBuffer_[eye].mWidth, frameBuffer_[eye].mHeight)); GL(glDepthMask(GL_TRUE)); GL(glEnable(GL_DEPTH_TEST)); GL(glDepthFunc(GL_LEQUAL)); GL(glInvalidateFramebuffer(GL_FRAMEBUFFER, sizeof(attachments)/sizeof(GLenum), attachments)); GL(glClear(GL_DEPTH_BUFFER_BIT)); }
void RenderingEngine3::resolve_msaa(const GLuint readFBO, const GLuint writeFBO) { #if defined (MSAA_ENABLED) glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, writeFBO); glBlitFramebuffer(0, 0, bufferWidth_, bufferHeight_, 0, 0, bufferWidth_, bufferHeight_, GL_COLOR_BUFFER_BIT, GL_LINEAR); GLenum discardAttachments[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT }; glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, discardAttachments); #else GLenum discardAttachments[] = { GL_DEPTH_ATTACHMENT }; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discardAttachments); #endif }
void FGLRenderBuffers::BlitToEyeTexture(int eye) { CreateEyeBuffers(eye); glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye]); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) { GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT }; glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments); } glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); }
//============================================================================== void GlFramebuffer::bind(Bool invalidate) { if(m_bindDefault) { glBindFramebuffer(GL_FRAMEBUFFER, 0); } else { ANKI_ASSERT(m_glName != 0); glBindFramebuffer(GL_FRAMEBUFFER, m_glName); // Set the draw buffers U count = 0; Array<GLenum, MAX_COLOR_ATTACHMENTS> colorAttachEnums; // Draw buffers for(U i = 0; i < MAX_COLOR_ATTACHMENTS; i++) { if(m_attachments[i].isCreated()) { colorAttachEnums[count++] = GL_COLOR_ATTACHMENT0 + i; } } ANKI_ASSERT(count > 0 || m_attachments[MAX_COLOR_ATTACHMENTS].isCreated()); glDrawBuffers(count, &colorAttachEnums[0]); // Invalidate if(invalidate) { static const Array<GLenum, GlFramebuffer::MAX_COLOR_ATTACHMENTS + 1> ATTACHMENT_TOKENS = {{ GL_DEPTH_STENCIL_ATTACHMENT, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}}; glInvalidateFramebuffer( GL_FRAMEBUFFER, ATTACHMENT_TOKENS.size(), &ATTACHMENT_TOKENS[0]); } } }
void FGLRenderBuffers::BlitSceneToTexture() { mCurrentPipelineTexture = 0; if (mSamples <= 1) return; glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) { GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT }; glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments); } glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); }
bool render() { glm::vec2 WindowSize(this->getWindowSize()); { glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glm::mat4* Pointer = (glm::mat4*)glMapBufferRange( GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, WindowSize.x, WindowSize.y, 0.1f, 100.0f); glm::mat4 Model = glm::mat4(1.0f); *Pointer = Projection * this->view() * Model; // Make sure the uniform buffer is uploaded glUnmapBuffer(GL_UNIFORM_BUFFER); } ////////////////////////////// // Render multisampled texture glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName[framebuffer::MULTISAMPLE]); glViewportIndexedf(0, 0, 0, GLfloat(FRAMEBUFFER_SIZE.x), GLfloat(FRAMEBUFFER_SIZE.y)); glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]); glBindProgramPipeline(PipelineName[pipeline::MULTISAMPLE]); glBindVertexArray(VertexArrayName[pipeline::MULTISAMPLE]); glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]); glEnable(GL_MULTISAMPLE); glDrawArraysInstancedBaseInstance(GL_LINE_LOOP, 0, GLsizei(VertexData.size()), 3, 0); glDisable(GL_MULTISAMPLE); ////////////////////////// // Resolving multisampling glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferName[framebuffer::MULTISAMPLE]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferName[framebuffer::COLOR]); glBlitFramebuffer( 0, 0, FRAMEBUFFER_SIZE.x, FRAMEBUFFER_SIZE.y, 0, 0, FRAMEBUFFER_SIZE.x, FRAMEBUFFER_SIZE.y, GL_COLOR_BUFFER_BIT, GL_NEAREST); GLenum attachments[1] = {GL_COLOR_ATTACHMENT0}; glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, attachments); glBindFramebuffer(GL_FRAMEBUFFER, 0); ////////////////////////////////////// // Render resolved multisample texture glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y); glBindFramebuffer(GL_FRAMEBUFFER, 0); //glDisable(GL_MULTISAMPLE); glActiveTexture(GL_TEXTURE0); //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, TextureName[texture::MULTISAMPLE]); glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLOR]); glBindVertexArray(VertexArrayName[pipeline::SPLASH]); glBindProgramPipeline(PipelineName[pipeline::SPLASH]); glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 6, 1, 0); return true; }
void OGLESFrameBuffer::Discard(uint32_t flags) { if (glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_discard_framebuffer()) { std::vector<GLenum> attachments; if (fbo_ != 0) { if (flags & CBM_Color) { for (size_t i = 0; i < clr_views_.size(); ++ i) { if (clr_views_[i]) { attachments.push_back(static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i)); } } } if (flags & CBM_Depth) { if (rs_view_) { attachments.push_back(GL_DEPTH_ATTACHMENT); } } if (flags & CBM_Stencil) { if (rs_view_) { attachments.push_back(GL_STENCIL_ATTACHMENT); } } } else { if (flags & CBM_Color) { attachments.push_back(GL_COLOR); } if (flags & CBM_Depth) { attachments.push_back(GL_DEPTH); } if (flags & CBM_Stencil) { attachments.push_back(GL_STENCIL); } } OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); GLuint old_fbo = re.BindFramebuffer(); re.BindFramebuffer(fbo_); if (glloader_GLES_VERSION_3_0()) { glInvalidateFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(attachments.size()), &attachments[0]); } else { glDiscardFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLsizei>(attachments.size()), &attachments[0]); } re.BindFramebuffer(old_fbo); } else { this->Clear(flags, Color(0, 0, 0, 0), 1, 0); } }
/*!**************************************************************************** @Function RenderScene @Return bool true if no error occured @Description Main rendering loop function of the program. The shell will call this function every frame. eglSwapBuffers() will be performed by PVRShell automatically. PVRShell will also manage important and relevant OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLES3EdgeDetection::RenderScene() { // Declares world orientation variables. PVRTMat4 mWorld, mMVP; // Updates the current time. m_ulCurrentTime=PVRShellGetTime(); #ifdef SHOW_MAX_FPS //Updates and checks framerate. m_iFrameCount+=1; if (m_ulCurrentTime-m_ulPreviousTimeFPS>=1000) { m_fFPS=(GLfloat)m_iFrameCount/(GLfloat)(m_ulCurrentTime-m_ulPreviousTimeFPS)*1000.0f; m_ulPreviousTimeFPS=m_ulCurrentTime; m_iFrameCount=0; } // Display fps data m_Print3D.Print3D(2.0f, 10.0f, 0.75f, 0xff0000ff, "%i fps", (int)m_fFPS); #endif // Time dependant updates for the rotational velocity of the scene. m_fAngleY += 0.0002f*PVRT_PI*(m_ulCurrentTime-m_ulPreviousTimeAngle); m_ulPreviousTimeAngle=PVRShellGetTime(); // Render to our texture (bracketed for viewing convenience) { // Use the first shader program to perform the initial render of the mask. glUseProgram(m_PreShader.uiId); // Bind render-to-texture frame buffer and set the viewPort glBindFramebuffer(GL_FRAMEBUFFER, m_uiFramebufferObject); if(m_i32TexWidth != m_i32WinWidth || m_i32TexHeight != m_i32WinHeight) glViewport(0, 0, m_i32TexWidth, m_i32TexHeight); #if defined(__PALMPDK__) // Enable writing to the alpha channel again as usually it is disabled so // we don't blend with the video layer on webOS devices. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); #endif // Clear the color and depth buffer of our FBO glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Rotates the scene and sets the model-view-projection matrix mWorld = PVRTMat4::RotationY(m_fAngleY); mMVP = m_mR2TProjection * m_mR2TView * mWorld; // Send the view matrix information to the shader. glUniformMatrix4fv(m_PreShader.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.f); // Enable vertex attribute array glEnableVertexAttribArray(eVERTEX_ARRAY); //Enable depth testing and culling. glEnable(GL_DEPTH_TEST); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Draw our models by looping through each mesh as defined by nNumMesh. for (unsigned int i=0; i<m_Scene.nNumMeshNode; i++) { DrawMesh(i); } // Unbind the VBO and index buffer. glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); //Invalidate the framebuffer attachments we don't need to avoid unnecessary copying to system memory const GLenum attachment = GL_DEPTH_ATTACHMENT; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachment); } // Bind the original frame buffer to draw to screen and set the Viewport. glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFramebuffer); if(m_i32TexWidth != m_i32WinWidth || m_i32TexHeight != m_i32WinHeight) glViewport(0, 0, m_i32WinWidth, m_i32WinHeight); // Clear the color and depth buffers for the screen. glClear(GL_COLOR_BUFFER_BIT); // Uses PVRShell input handling to update the line width in the edge detection shaders. if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { m_fLineWidth++; if (m_fLineWidth>10) m_fLineWidth=10; } if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) { m_fLineWidth--; if (m_fLineWidth<1) m_fLineWidth=1; } // Uses PVRShell input to choose which post shader program to use for post processing. // Loops through all shaders defined in EPostShaders if (PVRShellIsKeyPressed(PVRShellKeyNameUP)) { if (m_uiShaderID==eNumPostShaders-1) m_uiShaderID=0; else m_uiShaderID++; } else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN)) { if (m_uiShaderID==0) m_uiShaderID=eNumPostShaders-1; else m_uiShaderID--; } // Sets the shader based on the shader ID value, and sets the line width each frame (as it can change); glUseProgram(m_PostShaders[m_uiShaderID].uiId); glUniform2f(m_PostShaders[m_uiShaderID].auiLoc[ePixelSize],m_fLineWidth/(float)m_i32TexWidth,m_fLineWidth/(float)m_i32TexHeight); /* Note: We do not need to pass any projection data to these shaders as they are used only to render a texture to a full screen quad which is parallel with the viewport. The model meshes have already been positioned in the previous shader and now only exist as a 2D image.*/ // Enable texture attribute array glEnableVertexAttribArray(eTEXCOORD_ARRAY); // Draw the fullscreen quad to render the screen to. DrawQuad(); // Disable the vertex and texture attribute arrays glDisableVertexAttribArray(eTEXCOORD_ARRAY); glDisableVertexAttribArray(eVERTEX_ARRAY); // Print the demo title, current post shader's name and the line width if applicable m_Print3D.DisplayDefaultTitle("Edge Detection", "", ePVRTPrint3DSDKLogo); m_Print3D.Print3D(5,80,1,0xff885500,g_aszPostShaderNames[m_uiShaderID]); if (!strcmp(c_aszPostShaderDefines[m_uiShaderID][0],"EDGE_DETECTION")) m_Print3D.Print3D(5,90,0.7f,0xff000055,"Line Width = %i", (int)m_fLineWidth); m_Print3D.Flush(); return true; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglInvalidateFramebuffer(JNIEnv *__env, jclass clazz, jint target, jint numAttachments, jlong attachmentsAddress, jlong __functionAddress) { const GLenum *attachments = (const GLenum *)(intptr_t)attachmentsAddress; glInvalidateFramebufferPROC glInvalidateFramebuffer = (glInvalidateFramebufferPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glInvalidateFramebuffer(target, numAttachments, attachments); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglInvalidateFramebuffer__IIJ(JNIEnv *__env, jclass clazz, jint target, jint numAttachments, jlong attachmentsAddress) { glInvalidateFramebufferPROC glInvalidateFramebuffer = (glInvalidateFramebufferPROC)tlsGetFunction(892); intptr_t attachments = (intptr_t)attachmentsAddress; UNUSED_PARAM(clazz) glInvalidateFramebuffer(target, numAttachments, attachments); }
void MediaSurface::Update() { if ( !AndroidSurfaceTexture ) { LOG( "!AndroidSurfaceTexture" ); return; } if ( TexId <= 0 ) { //LOG( "TexId <= 0" ); return; } AndroidSurfaceTexture->Update(); if ( AndroidSurfaceTexture->nanoTimeStamp == LastSurfaceTexNanoTimeStamp ) { return; } LastSurfaceTexNanoTimeStamp = AndroidSurfaceTexture->nanoTimeStamp; // don't mess up Unity state GLStateSave stateSave; // If we haven't allocated our GL objects yet, do it now. // This isn't done at Init, because GL may not be current then. if ( UnitSquare.vertexArrayObject == 0 ) { LOG( "Allocating GL objects" ); UnitSquare = BuildTesselatedQuad( 1, 1 ); CopyMovieProgram = BuildProgram( "uniform highp mat4 Mvpm;\n" "attribute vec4 Position;\n" "attribute vec2 TexCoord;\n" "varying highp vec2 oTexCoord;\n" "void main()\n" "{\n" " gl_Position = Position;\n" " oTexCoord = TexCoord;\n" "}\n" , "#extension GL_OES_EGL_image_external : require\n" "uniform samplerExternalOES Texture0;\n" "varying highp vec2 oTexCoord;\n" "void main()\n" "{\n" " gl_FragColor = texture2D( Texture0, oTexCoord );\n" "}\n" ); } // If the SurfaceTexture has changed dimensions, we need to // reallocate the texture and FBO. glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_EXTERNAL_OES, AndroidSurfaceTexture->textureId ); // FIXME: no way to get texture dimensions even in ES 3.0??? int width = 960; int height = 540; if ( width != TexIdWidth || height != TexIdHeight ) { LOG( "New surface size: %ix%i", width, height ); TexIdWidth = width; TexIdHeight = height; if ( Fbo ) { glDeleteFramebuffers( 1, &Fbo ); } glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, TexId ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, TexIdWidth, TexIdHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glBindTexture( GL_TEXTURE_2D, 0 ); glActiveTexture( GL_TEXTURE0 ); glGenFramebuffers( 1, &Fbo ); glBindFramebuffer( GL_FRAMEBUFFER, Fbo ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TexId, 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } glBindFramebuffer( GL_FRAMEBUFFER, Fbo ); glDisable( GL_DEPTH_TEST ); glDisable( GL_SCISSOR_TEST ); glDisable( GL_STENCIL_TEST ); glDisable( GL_CULL_FACE ); glDisable( GL_BLEND ); const GLenum fboAttachments[1] = { GL_COLOR_ATTACHMENT0 }; glInvalidateFramebuffer( GL_FRAMEBUFFER, 1, fboAttachments ); glViewport( 0, 0, TexIdWidth, TexIdHeight ); glUseProgram( CopyMovieProgram.program ); UnitSquare.Draw(); glUseProgram( 0 ); glBindTexture( GL_TEXTURE_EXTERNAL_OES, 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glBindTexture( GL_TEXTURE_2D, TexId ); glGenerateMipmap( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, 0 ); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglInvalidateFramebuffer(JNIEnv *env, jclass clazz, jint target, jint numAttachments, jlong attachments, jlong function_pointer) { const GLenum *attachments_address = (const GLenum *)(intptr_t)attachments; glInvalidateFramebufferPROC glInvalidateFramebuffer = (glInvalidateFramebufferPROC)((intptr_t)function_pointer); glInvalidateFramebuffer(target, numAttachments, attachments_address); }