void unload() { delete scene; glDeleteFramebuffers(1, &fbo); glDeleteTextures(texture_count, texture); delete [] texture; }
int main(int argc, char *argv[]) { if (argc > 1){ if (strcmp(argv[1], "-debug") == 0 ) mode = MODE_DEBUG; else if ( strcmp(argv[1], "-oculus") == 0 ) mode = MODE_OCULUS; else if ( strcmp(argv[1], "-oculus-debug") == 0 ) mode = MODE_OCULUS_DEBUG; else return 100; }else mode = MODE_DEBUG; int err; // Init OVR library, hardware and sensors. err = init_ovr(); if ( err != 0 ) exit( 10 + err ); //Init windows and OpenGL context err = init_SDL_GL(); if ( err != 0 ) exit( 0 + err ); // Load and Init shader and shaders Program err = load_init_shaders(); if ( err != 0 ) exit( 20 + err ); // Load the Vertices, vertex arrays, etc... And bind them, along with the shaders. err = load_vertex(); if ( err != 0 ) exit( 30 + err ); // Loads the texture from files and bien them as uniform in the frag shader err = load_textures(); if ( err != 0 ) exit( 40 + err ); if (mode != MODE_DEBUG){ // Inits the frame buffer, usefull for rendering the scene in a texture to send it to Oculus err = init_framebuffers(); if ( err != 0 ) exit( 50 + err ); err = init_render_ovr(); if ( err != 0 ) exit( 60 + err ); } std::cout << "Recommended w " << recommendedTex0Size.w << std::endl << "Recommended h " << recommendedTex0Size.h << std::endl; // Tansformations //--------------------------------------------- // ---- Transfo glm::mat4 trans; GLuint uniTrans = glGetUniformLocation(shaderProgram, "trans"); // ---- View glm::mat4 view; // ---- Projection glm::mat4 proj; // Render in Texture, and display //------------------------------------------------- if (mode == MODE_OCULUS_DEBUG ){ load_init_passthrough_shaders(); GLuint passthroughOB; glGenBuffers(1, &passthroughOB); glBindBuffer(GL_ARRAY_BUFFER, passthroughOB); glBufferData(GL_ARRAY_BUFFER, sizeof(passthroughScreen), passthroughScreen, GL_STATIC_DRAW); // Binding the fragment Shader output to the current buffer glBindFragDataLocation(passthroughShadersProgram, 0, "passthroughColor"); errorCode = glGetError(); // Link and Use Program glLinkProgram(passthroughShadersProgram); glUseProgram(passthroughShadersProgram); // Store the attributes for the shaders glGenVertexArrays(1, &passthroughVAO); glBindVertexArray(passthroughVAO); // Attributes Locations for Shaders and Enable GLint posAttrib = glGetAttribLocation(passthroughShadersProgram, "position"); glVertexAttribPointer(posAttrib, 0, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*) 2 ); glEnableVertexAttribArray(posAttrib); GLint colorAttrib = glGetAttribLocation(passthroughShadersProgram, "texCoords"); glVertexAttribPointer(colorAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2) ); glEnableVertexAttribArray(colorAttrib); glUseProgram(passthroughShadersProgram); glUniform1i(glGetUniformLocation(passthroughShadersProgram, "renderedTex"), 0); } // Event Loop //-------------------------------------------------- SDL_Event windowEvent; while (true) { if (SDL_PollEvent(&windowEvent)) { // Quit events if (windowEvent.type == SDL_QUIT) break; else if (windowEvent.type == SDL_KEYUP && windowEvent.key.keysym.sym == SDLK_ESCAPE) break; } // Enabling ressources to draw the cube // Before entering the rendering loop glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); // ---- View view = glm::lookAt( glm::vec3(5.0f, 5.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f) ); GLint uniView = glGetUniformLocation(shaderProgram, "view"); glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view)); // ---- Projection if ( mode == MODE_DEBUG ){ proj = glm::perspective(45.0f, 1280.0f / 720.0f, 1.0f, 10.0f); }else{ proj = glm::perspective(45.0f, 640.0f / 720.0f, 1.0f, 10.0f); } GLint uniProj = glGetUniformLocation(shaderProgram, "proj"); glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj)); //Turn around Z trans = glm::rotate( trans, 0.7f, glm::vec3(0.0f, 0.0f, 1.0f) ); glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans)); if ( mode == MODE_OCULUS || mode == MODE_OCULUS_DEBUG ){ hdmFrameTiming = ovrHmd_BeginFrame(hmd, 0); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++){ ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex]; headPose[eye] = ovrHmd_GetEyePose(hmd, eye); if (eye == ovrEye_Right){ glScissor(renderTargetSize.w / 2, 0, renderTargetSize.w / 2, renderTargetSize.h); glViewport(renderTargetSize.w / 2, 0, renderTargetSize.w / 2, renderTargetSize.h); }else{ glScissor(0, 0, renderTargetSize.w / 2, renderTargetSize.h); glViewport(0, 0, renderTargetSize.w / 2, renderTargetSize.h); } if (eye == ovrEye_Right) glClearColor(0.0f, 0.3f, 0.0f, 1.0f); else glClearColor(0.3f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Drawing glDrawArrays(GL_TRIANGLES, 0, 36); } if (mode == MODE_OCULUS ){ glScissor(0, 0, renderTargetSize.w, renderTargetSize.h); glViewport(0, 0, renderTargetSize.w, renderTargetSize.h); ovrHmd_EndFrame(hmd, headPose, eyeTex); Sleep(1); }else if ( mode == MODE_OCULUS_DEBUG ){ glBindBuffer(GL_FRAMEBUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glUseProgram(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindVertexArray(passthroughVAO); glDisable(GL_DEPTH_TEST); glUseProgram(passthroughShadersProgram); glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLES, 0, 6); } }else if (mode == MODE_DEBUG){ // Clear the screen and the depth buffer (as it is filled with 0 initially, // nothing will be draw (0 = on top); glClearColor(0.0f, 0.3f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Drawing glDrawArrays(GL_TRIANGLES, 0, 36); } if ( mode != MODE_OCULUS ) SDL_GL_SwapWindow(window); } // Destoy the HMD and shutdown the library ovrHmd_Destroy(hmd); ovr_Shutdown(); // Quite SDL and OpenGL glDeleteFramebuffers(1, &frameBuffer); SDL_GL_DeleteContext(context); SDL_Quit(); return 0; }
FrameBufferObject::~FrameBufferObject() { glDeleteFramebuffers( 1, &m_FBOId ); m_FBOId = 0; SAFE_DELETE( m_mesh ); }
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples, bool mipmap) { QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); fbo_guard.setContext(ctx); bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx))) return; size = sz; target = texture_target; // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); fbo_guard.setId(fbo); glDevice.setFBO(q, attachment); QT_CHECK_GLERROR(); // init texture if (samples == 0) { glGenTextures(1, &texture); glBindTexture(target, texture); glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) glGenerateMipmap(GL_TEXTURE_2D); #ifndef QT_OPENGL_ES glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #else glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texture, 0); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); glBindTexture(target, 0); color_buffer = 0; } else { mipmap = false; GLint maxSamples; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); glGenRenderbuffers(1, &color_buffer); glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); if (glRenderbufferStorageMultisampleEXT && samples > 0) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internal_format, size.width(), size.height()); } else { samples = 0; glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format, size.width(), size.height()); } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); if (valid) glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); } // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer // might not be supported while separate buffers are, according to QTBUG-12861. if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); stencil_buffer = depth_buffer; glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); stencil_buffer = depth_buffer = 0; } } if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil || (attachment == QGLFramebufferObject::Depth))) { glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); depth_buffer = 0; } } if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { glGenRenderbuffers(1, &stencil_buffer); Q_ASSERT(!glIsRenderbuffer(stencil_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer); Q_ASSERT(glIsRenderbuffer(stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_STENCIL_INDEX8_EXT, size.width(), size.height()); #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_STENCIL_INDEX, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, size.width(), size.height()); #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, size.width(), size.height()); #endif } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &stencil_buffer); stencil_buffer = 0; } } // The FBO might have become valid after removing the depth or stencil buffer. valid = checkFramebufferStatus(); if (depth_buffer && stencil_buffer) { fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; } else if (depth_buffer) { fbo_attachment = QGLFramebufferObject::Depth; } else { fbo_attachment = QGLFramebufferObject::NoAttachment; } glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); if (!valid) { if (color_buffer) glDeleteRenderbuffers(1, &color_buffer); else glDeleteTextures(1, &texture); if (depth_buffer) glDeleteRenderbuffers(1, &depth_buffer); if (stencil_buffer && depth_buffer != stencil_buffer) glDeleteRenderbuffers(1, &stencil_buffer); glDeleteFramebuffers(1, &fbo); fbo_guard.setId(0); } QT_CHECK_GLERROR(); format.setTextureTarget(target); format.setSamples(int(samples)); format.setAttachment(fbo_attachment); format.setInternalTextureFormat(internal_format); format.setMipmap(mipmap); }
void FHTML5OpenGL::ProcessExtensions( const FString& ExtensionsString ) { FOpenGLES2::ProcessQueryGLInt(); FOpenGLBase::ProcessExtensions(ExtensionsString); bSupportsMapBuffer = ExtensionsString.Contains(TEXT("GL_OES_mapbuffer")); bSupportsDepthTexture = ExtensionsString.Contains(TEXT("GL_OES_depth_texture")); bSupportsOcclusionQueries = ExtensionsString.Contains(TEXT("GL_ARB_occlusion_query2")) || ExtensionsString.Contains(TEXT("GL_EXT_occlusion_query_boolean")); bSupportsRGBA8 = ExtensionsString.Contains(TEXT("GL_OES_rgb8_rgba8")); bSupportsBGRA8888 = ExtensionsString.Contains(TEXT("GL_APPLE_texture_format_BGRA8888")) || ExtensionsString.Contains(TEXT("GL_IMG_texture_format_BGRA8888")) || ExtensionsString.Contains(TEXT("GL_EXT_texture_format_BGRA8888")); bSupportsVertexHalfFloat = false;//ExtensionsString.Contains(TEXT("GL_OES_vertex_half_float")); bSupportsTextureFloat = ExtensionsString.Contains(TEXT("GL_OES_texture_float")); bSupportsTextureHalfFloat = ExtensionsString.Contains(TEXT("GL_OES_texture_half_float")) && ExtensionsString.Contains(TEXT("GL_OES_texture_half_float_linear")); bSupportsSGRB = ExtensionsString.Contains(TEXT("GL_EXT_sRGB")); bSupportsColorBufferHalfFloat = ExtensionsString.Contains(TEXT("GL_EXT_color_buffer_half_float")); bSupportsShaderFramebufferFetch = ExtensionsString.Contains(TEXT("GL_EXT_shader_framebuffer_fetch")) || ExtensionsString.Contains(TEXT("GL_NV_shader_framebuffer_fetch")); // @todo ios7: SRGB support does not work with our texture format setup (ES2 docs indicate that internalFormat and format must match, but they don't at all with sRGB enabled) // One possible solution us to use GLFormat.InternalFormat[bSRGB] instead of GLFormat.Format bSupportsSGRB = false;//ExtensionsString.Contains(TEXT("GL_EXT_sRGB")); bSupportsDXT = ExtensionsString.Contains(TEXT("GL_NV_texture_compression_s3tc")) || ExtensionsString.Contains(TEXT("GL_EXT_texture_compression_s3tc")) || ExtensionsString.Contains(TEXT("WEBGL_compressed_texture_s3tc")) || (ExtensionsString.Contains(TEXT("GL_EXT_texture_compression_dxt1")) && // ANGLE (for HTML5_Win32) exposes these 3 as discrete extensions ExtensionsString.Contains(TEXT("GL_ANGLE_texture_compression_dxt3")) && ExtensionsString.Contains(TEXT("GL_ANGLE_texture_compression_dxt5")) ); bSupportsPVRTC = ExtensionsString.Contains(TEXT("GL_IMG_texture_compression_pvrtc")) ; bSupportsATITC = ExtensionsString.Contains(TEXT("GL_ATI_texture_compression_atitc")) || ExtensionsString.Contains(TEXT("GL_AMD_compressed_ATC_texture")); bSupportsVertexArrayObjects = ExtensionsString.Contains(TEXT("GL_OES_vertex_array_object")) ; bSupportsDiscardFrameBuffer = ExtensionsString.Contains(TEXT("GL_EXT_discard_framebuffer")); bSupportsNVFrameBufferBlit = ExtensionsString.Contains(TEXT("GL_NV_framebuffer_blit")); bSupportsShaderTextureLod = ExtensionsString.Contains(TEXT("GL_EXT_shader_texture_lod")); bSupportsTextureCubeLodEXT = bSupportsShaderTextureLod; // This never exists in WebGL (ANGLE exports this, so we want to force it to false) bSupportsRGBA8 = false; // This is not color-renderable in WebGL/ANGLE (ANGLE exposes this) bSupportsBGRA8888 = false; // ANGLE/WEBGL_depth_texture is sort of like OES_depth_texture, you just can't upload bulk data to it (via Tex*Image2D); that should be OK? bSupportsDepthTexture = ExtensionsString.Contains(TEXT("WEBGL_depth_texture")) || // Catch "WEBGL_depth_texture", "MOZ_WEBGL_depth_texture" and "WEBKIT_WEBGL_depth_texture". ExtensionsString.Contains(TEXT("GL_ANGLE_depth_texture")) || // for HTML5_WIN32 build with ANGLE ExtensionsString.Contains(TEXT("GL_OES_depth_texture")); // for a future HTML5 build without ANGLE #if PLATFORM_HTML5_BROWSER // The core WebGL spec has a combined GL_DEPTH_STENCIL_ATTACHMENT, unlike the core GLES2 spec. bCombinedDepthStencilAttachment = true; // Note that WebGL always supports packed depth stencil renderbuffers (DEPTH_STENCIL renderbuffor format), but for textures // needs WEBGL_depth_texture (at which point it's DEPTH_STENCIL + UNSIGNED_INT_24_8) // @todo: if we can always create PF_DepthStencil as DEPTH_STENCIL renderbuffers, we could remove the dependency bSupportsPackedDepthStencil = bSupportsDepthTexture; #else bCombinedDepthStencilAttachment = false; bSupportsPackedDepthStencil = ExtensionsString.Contains(TEXT("GL_OES_packed_depth_stencil")); #endif if (!bSupportsDepthTexture) { UE_LOG(LogRHI, Warning, TEXT("This browser does not support WEBGL_depth_texture. Rendering will not function since fallback code is not available.")); } if (bSupportsTextureHalfFloat && !bSupportsColorBufferHalfFloat) { // Initial implementations of WebGL's texture_float screwed up, and allowed // rendering to fp textures, even though the underlying EXT_texture_float doesn't // explicitly allow anything such. FP rendering without explicit // EXT_color_buffer_half_float may be possible, so we test for that here // by checking for framebuffer completeness. The spec is "wrong" as far as // clamping and the like (which WEBGL_color_buffer_float/EXT_color_buffer_half_float // fixes, but in practice it might "just work"). // // See http://www.khronos.org/webgl/public-mailing-list/archives/1211/msg00133.html // for more information. UE_LOG(LogRHI, Warning, TEXT("Trying to enable fp rendering without explicit EXT_color_buffer_half_float by checking for framebuffer completeness")); GLenum err = glGetError(); if (err != GL_NO_ERROR) { UE_LOG(LogRHI, Warning, TEXT("Detected OpenGL error 0x%04x before checking for implicit half-float fb support"), err); } GLuint tex, fb; #if PLATFORM_HTML5_WIN32 glClearColor( 1.0, 0.5, 0.0,1.0); glClear( GL_COLOR_BUFFER_BIT ); #endif glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_HALF_FLOAT_OES, NULL); glGenFramebuffers(1, &fb); glBindFramebuffer(GL_FRAMEBUFFER, fb); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); GLenum fbstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); #if PLATFORM_HTML5_WIN32 // keep glReadPixel out of floating point tests for HTML5 Browser builds, glReadPixels doesn't work consistently across browser and is // hidden behind inconsistent webgl extentions. TArray<FLinearColor> Data; Data.AddUninitialized(32*32); glViewport(0, 0, 32, 32); glClear(GL_COLOR_BUFFER_BIT); FMemory::Memzero(Data.GetData(),32*32*sizeof(FLinearColor)); glReadPixels(0, 0, 32, 32, GL_RGBA, GL_FLOAT, Data.GetData()); err = glGetError(); UE_LOG(LogRHI, Log, TEXT(" %f %f %f %f"), Data[0].R,Data[0].G,Data[0].B,Data[0].A); #endif bSupportsColorBufferHalfFloat = fbstatus == GL_FRAMEBUFFER_COMPLETE && err == GL_NO_ERROR; if (bSupportsColorBufferHalfFloat) { UE_LOG(LogRHI, Log, TEXT("Enabling implicit ColorBufferHalfFloat after checking fb completeness")); } else { UE_LOG(LogRHI, Log, TEXT("Could not enable implicit ColorBufferHalfFloat after checking fb completeness")); } glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fb); glDeleteTextures(1, &tex); } // Report shader precision int Range[2]; glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_LOW_FLOAT, Range, &ShaderLowPrecision); glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, Range, &ShaderMediumPrecision); glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, Range, &ShaderHighPrecision); UE_LOG(LogRHI, Log, TEXT("Fragment shader lowp precision: %d"), ShaderLowPrecision); UE_LOG(LogRHI, Log, TEXT("Fragment shader mediump precision: %d"), ShaderMediumPrecision); UE_LOG(LogRHI, Log, TEXT("Fragment shader highp precision: %d"), ShaderHighPrecision); }
int main() { // Initialize GLFW and set some hints that will create an OpenGL 3.3 context // using core profile. glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a fixed 800x600 window that is not resizable. GLFWwindow* window = glfwCreateWindow(kWindowWidth, kWindowHeight, "LearnGL", nullptr, nullptr); if (window == nullptr) { std::cerr << "Failed to created GLFW window" << std::endl; glfwTerminate(); return 1; } // Create an OpenGL context and pass callbacks to GLFW. glfwMakeContextCurrent(window); glfwSetKeyCallback(window, keyCallback); glfwSetCursorPosCallback(window, mouseCallback); glfwSetScrollCallback(window, scrollCallback); // Lock the mouse in the window. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW" << std::endl; glfwTerminate(); return 1; } // Create a viewport the same size as the window. glfwGetFramebufferSize is // used rather than the size constants since some windowing systems have a // discrepancy between window size and framebuffer size // (e.g HiDPi screen coordinates), int fbWidth, fbHeight; glfwGetFramebufferSize(window, &fbWidth, &fbHeight); glViewport(0, 0, fbWidth, fbHeight); // Enable multisampling for using MSAA. glEnable(GL_MULTISAMPLE); // Enabled SRGB for gamma correction. glEnable(GL_FRAMEBUFFER_SRGB); // Enable use of the depth buffer since we're working on 3D and want to // prevent overlapping polygon artifacts. glEnable(GL_DEPTH_TEST); // Read and compile the vertex and fragment shaders using // the shader helper class. shader = Shader("glsl/vertex.glsl", "glsl/fragment.glsl", "glsl/geometry.glsl"); depthShader = Shader("glsl/depth_vert.glsl", "glsl/depth_frag.glsl"); postShader = Shader("glsl/post_vert.glsl", "glsl/post_frag.glsl"); containerTexture = loadTexture("assets/container2.png"); containerSpecular = loadTexture("assets/container2_specular.png"); containerEmission = loadTexture("assets/matrix.jpg"); // Container mesh data. GLfloat vertices[] = { // Vertices // Normals // UVs -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; // Points for the geometry shader tutorial. GLfloat points[] = { -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right -0.5f, -0.5f, 1.0f, 1.0f, 0.0f // Bottom-left }; // Create and bind a framebuffer. GLuint FBO; glGenFramebuffers(1, &FBO); glBindFramebuffer(GL_FRAMEBUFFER, FBO); // Create an empty texture to be attached to the framebuffer. // Give a null pointer to glTexImage2D since we want an empty texture. GLuint frameColorBufferMultiSampled; glGenTextures(1, &frameColorBufferMultiSampled); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, frameColorBufferMultiSampled); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, kMSAASamples, GL_RGB, fbWidth, fbHeight, GL_TRUE); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); // Attach the texture to the framebuffer. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, frameColorBufferMultiSampled, 0); // Create a renderbuffer to hold our depth and stencil buffers with a size // of the window's framebuffer size. GLuint RBO; glGenRenderbuffers(1, &RBO); glBindRenderbuffer(GL_RENDERBUFFER, RBO); glRenderbufferStorageMultisample(GL_RENDERBUFFER, kMSAASamples, GL_DEPTH24_STENCIL8, fbWidth, fbHeight); glBindRenderbuffer(GL_RENDERBUFFER, 0); // Attach the render buffer (provides depth and stencil) to the framebuffer. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO); // Panic if the framebuffer is somehow incomplete at this stage. This should // never happen if we attached the texture but it's good practice to check. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "ERROR: Framebuffer is not complete!" << std::endl; glfwTerminate(); return 1; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // Generate texture for intermediate stage. GLuint screenTexture; glGenTextures(1, &screenTexture); glBindTexture(GL_TEXTURE_2D, screenTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbWidth, fbHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); // Second framebuffer for post. GLuint intermediateFBO; glGenFramebuffers(1, &intermediateFBO); glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // Panic if the framebuffer is somehow incomplete at this stage. This should // never happen if we attached the texture but it's good practice to check. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "ERROR: Framebuffer is not complete!" << std::endl; glfwTerminate(); return 1; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // Create a texture to hold the depth map data. // The depth map is used for shadow mapping. GLuint depthMap; glGenTextures(1, &depthMap); glBindTexture(GL_TEXTURE_2D, depthMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, kShadowWidth, kShadowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); GLfloat borderColor[] = { 1.0, 1.0, 1.0, 1.0 }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glBindTexture(GL_TEXTURE_2D, 0); GLuint depthMapFBO; glGenFramebuffers(1, &depthMapFBO); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); // Panic if the framebuffer is somehow incomplete at this stage. This should // never happen if we attached the texture but it's good practice to check. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "ERROR: Framebuffer is not complete!" << std::endl; glfwTerminate(); return 1; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // Create a VBO to store the vertex data, an EBO to store indice data, and // create a VAO to retain our vertex attribute pointers. GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // Fill the VBO and set vertex attributes. glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Create a lamp box thing using the existing container VBO. GLuint lightVAO; glGenVertexArrays(1, &lightVAO); // Use the container's VBO and set vertex attributes. glBindVertexArray(lightVAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); // Vertex attributes for the frame quad in NDC. GLfloat frameVertices[] = { // Positions // UVs -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }; // Create a VBO and VAO for the post-processing step. GLuint frameVBO, frameVAO; glGenVertexArrays(1, &frameVAO); glGenBuffers(1, &frameVBO); glBindVertexArray(frameVAO); glBindBuffer(GL_ARRAY_BUFFER, frameVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(frameVertices), frameVertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); // Create a VBO and VAO for the geometry shader test. The VBO will contain // only the position. GLuint pointsVBO, pointsVAO; glGenVertexArrays(1, &pointsVAO); glGenBuffers(1, &pointsVBO); glBindVertexArray(pointsVAO); glBindBuffer(GL_ARRAY_BUFFER, pointsVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); // Create a perspective camera to fit the viewport. screenWidth = (GLfloat)fbWidth; screenHeight = (GLfloat)fbHeight; camera = PerspectiveCamera( glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, glm::radians(-90.0f), 0.0f), glm::radians(45.0f), screenWidth / screenHeight, 0.1f, 100.0f ); GLfloat delta = 0.0f; GLfloat lastFrame = 0.0f; // Render loop. while (!glfwWindowShouldClose(window)) { GLfloat currentFrame = glfwGetTime(); delta = currentFrame - lastFrame; lastFrame = currentFrame; // Check and call events. glfwPollEvents(); move(delta); // Use the depth shader and set the required uniforms. The depth shader uses // a special lightSpaceMatrix with an orthographic projection looking at the // specific mesh to cast a shadow for. // // Render to the depth map for shadow mapping. glViewport(0, 0, kShadowWidth, kShadowHeight); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); depthShader.use(); drawContainers(VBO, depthShader, true, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Bind the off screen framebuffer (for post-processing) and clear the // screen to a nice blue color. glViewport(0, 0, fbWidth, fbHeight); glBindFramebuffer(GL_FRAMEBUFFER, FBO); glClearColor(0.1f, 0.15f, 0.15f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // Update the time counter for the camera zoom. const GLfloat limitTime = 1.0f; fovTime += delta; if (fovTime > limitTime) { fovTime = limitTime; } // Update the perspective to account for changes in fov. // Used by the scroll to zoom feature. camera.fov = easeOutQuart(fovTime, startFov, (startFov - targetFov) * -1, limitTime); camera.update(); shader.use(); setupMatrices(); drawContainers(VBO, shader, false, depthMap); glBindFramebuffer(GL_READ_FRAMEBUFFER, FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO); glBlitFramebuffer(0, 0, fbWidth, fbHeight, 0, 0, fbWidth, fbHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Unbind the offscreen framebuffer containing the unprocessed frame. glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); postShader.use(); glBindVertexArray(frameVAO); // Send the texture sampler to the shader. GLuint frameTexture = glGetUniformLocation(postShader.program, "frameTexture"); glUniform1i(frameTexture, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, screenTexture); // Render the color buffer in the framebuffer to the quad with post shader. glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); // Swap buffers used for double buffering. glfwSwapBuffers(window); } // Destroy the off screen framebuffer. glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &FBO); // Properly deallocate the VBO and VAO. glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW and clean any resources before exiting. glfwTerminate(); return 0; }
bool testFramebufferBlitLayered(int x, int y, bool srcLayered, bool dstLayered) { bool pass = true; GLuint srcFBO, dstFBO; GLuint srcTex, dstTex; GLenum fbStatus; /* Set up source fbo */ glGenFramebuffers(1, &srcFBO); glBindFramebuffer(GL_FRAMEBUFFER, srcFBO); piglit_check_gl_error(GL_NO_ERROR); if (srcLayered) { srcTex = create_bind_texture(GL_TEXTURE_3D, true); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTex, 0); } else { srcTex = create_bind_texture(GL_TEXTURE_2D, true); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTex, 0); } /* Check source framebuffer status */ fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (fbStatus != GL_FRAMEBUFFER_COMPLETE) { printf("testFramebufferBlitLayered srcFBO Status: %s\n", piglit_get_gl_enum_name(fbStatus)); return false; } /* Set up dstt fbo */ glGenFramebuffers(1, &dstFBO); glBindFramebuffer(GL_FRAMEBUFFER, dstFBO); if (dstLayered) { dstTex = create_bind_texture(GL_TEXTURE_3D, false); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTex, 0); } else { dstTex = create_bind_texture(GL_TEXTURE_2D, false); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0); } /* Check destination framebuffer status */ fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (fbStatus != GL_FRAMEBUFFER_COMPLETE) { printf("testFramebufferBlitLayered dstFBO Status: %s\n", piglit_get_gl_enum_name(fbStatus)); return false; } /* Check for if any errors have occured */ if (!piglit_check_gl_error(GL_NO_ERROR)) { printf("Error setting up framebuffers for test.\n"); return false; } /* Blit from source to destination framebuffers */ glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO); glBlitFramebuffer(0, 0, texWidth, texHeight, 0, 0, texWidth, texHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); /* Display the results */ display_texture(x, y, srcTex, srcLayered ? texDepth : 1); display_texture(x + texWidth, y, dstTex, dstLayered ? texDepth : 1); /* Check for pass condition */ if (dstLayered) { pass = piglit_probe_rect_rgb(x + texWidth, y, texWidth, texHeight, srcColors[0]) && pass; pass = piglit_probe_rect_rgb(x + texWidth, y + texHeight, texWidth, texHeight, dstColors[1]) && pass; } else { pass = piglit_probe_rect_rgb(x + texWidth, y, texWidth, texDepth * texHeight, srcColors[0]) && pass; } /* Clean up */ glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo); glDeleteFramebuffers(1, &srcFBO); glDeleteFramebuffers(1, &dstFBO); glDeleteTextures(1, &srcTex); glDeleteTextures(1, &dstTex); /* Check for if any errors have occured */ if (!piglit_check_gl_error(GL_NO_ERROR)) { printf("Error setting up framebuffers for test.\n"); return false; } return pass; }
enum piglit_result piglit_display(void) { GLubyte *win_image, *fbo_image; GLuint fbo, rb; bool pass = true; win_image = (GLubyte *) malloc(piglit_width * piglit_height * 3); fbo_image = (GLubyte *) malloc(piglit_width * piglit_height * 3); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, piglit_width, piglit_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); assert(glGetError() == 0); assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); /* draw reference image in the window */ glBindFramebuffer(GL_FRAMEBUFFER, 0); draw_test_image(); glReadPixels(0, 0, piglit_width, piglit_height, GL_RGB, GL_UNSIGNED_BYTE, win_image); /* draw test image in fbo */ glBindFramebuffer(GL_FRAMEBUFFER, fbo); glReadBuffer(GL_COLOR_ATTACHMENT0); draw_test_image(); glReadPixels(0, 0, piglit_width, piglit_height, GL_RGB, GL_UNSIGNED_BYTE, fbo_image); /* compare images */ if (memcmp(win_image, fbo_image, piglit_width * piglit_height * 3)) { #if 0 /* helpful debug code */ int i, k; for (i = k = 0; i < piglit_width * piglit_height * 3; i++) { if (win_image[i] != fbo_image[i] && k++ < 40) printf("%d: %d vs. %d\n", i, win_image[i], fbo_image[i]); } #endif printf("Image comparison failed!\n"); pass = false; } else if (!piglit_automatic) { printf("Image comparison passed.\n"); } glBindFramebuffer(GL_FRAMEBUFFER, 0); #if 0 /* for debug/compare (alternate diplaying Window vs. FBO image) */ { int i; glWindowPos2i(0,0); for (i = 0; i < 10; i++) { GLubyte *image = (i & 1) ? fbo_image : win_image; printf("Showing %s image\n", (i & 1) ? "FBO" : "window"); glDrawPixels(piglit_width, piglit_height, GL_RGB, GL_UNSIGNED_BYTE, image); piglit_present_results(); sleep(1); } } #endif piglit_present_results(); glDeleteRenderbuffers(1, &rb); glDeleteFramebuffers(1, &fbo); free(win_image); free(fbo_image); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void mGLES2ShaderDeinit(struct mGLES2Shader* shader) { glDeleteTextures(1, &shader->tex); glDeleteShader(shader->fragmentShader); glDeleteProgram(shader->program); glDeleteFramebuffers(1, &shader->fbo); }
FBO2D::~FBO2D() { glDeleteFramebuffers(1, &frameBuffer); glDeleteRenderbuffers(1, &depthBuffer); glDeleteTextures(1, &textureBuffer); }
void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbName); glDeleteTextures(1, &texName); }
GLUSvoid terminate(GLUSvoid) { glBindBuffer(GL_ARRAY_BUFFER, 0); if (g_verticesVBO) { glDeleteBuffers(1, &g_verticesVBO); g_verticesVBO = 0; } if (g_normalsVBO) { glDeleteBuffers(1, &g_normalsVBO); g_normalsVBO = 0; } if (g_texCoordsVBO) { glDeleteBuffers(1, &g_texCoordsVBO); g_texCoordsVBO = 0; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (g_indicesVBO) { glDeleteBuffers(1, &g_indicesVBO); g_indicesVBO = 0; } glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); if (g_texture) { glDeleteTextures(1, &g_texture); g_texture = 0; } glBindVertexArray(0); if (g_vao) { glDeleteVertexArrays(1, &g_vao); g_vao = 0; } glUseProgram(0); glusProgramDestroy(&g_program); // glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); if (g_mirrorTexture) { glDeleteTextures(1, &g_mirrorTexture); g_mirrorTexture = 0; } glBindRenderbuffer(GL_RENDERBUFFER, 0); if (g_depthMirrorTexture) { glDeleteRenderbuffers(1, &g_depthMirrorTexture); g_depthMirrorTexture = 0; } glBindFramebuffer(GL_FRAMEBUFFER, 0); if (g_fboMirrorTexture) { glDeleteFramebuffers(1, &g_fboMirrorTexture); g_fboMirrorTexture = 0; } terminateWavefront(); }
int main(void) { const GLubyte* renderer; const GLubyte* version; int windowHeight, windowWidth; bool keys[128]; initUpdateObject(); srand( time( NULL ) ); fprintf(stderr, "Initializeing GLFW..."); if ( !glfwInit() ) exit(EXIT_FAILURE); glfwWindowHint(GLFW_SAMPLES, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); windowHeight = 1280; windowWidth = 1280; window = glfwCreateWindow(windowWidth, windowHeight, "3D Navier-Stokes Simulator", NULL, NULL); if ( !window ) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); glfwSwapInterval(1); glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, cursor_position_callback); glfwSetMouseButtonCallback(window, mouse_click_callback); //Camera camera((float)glfwGetTime(), windowWidth, windowHeight); glewExperimental = GL_TRUE; if ( glewInit() != GLEW_OK ) { fprintf( stderr, "Failed to initialize GLEW\n" ); return -1; } std::cout << "Normal error <" << glGetError() << "> please ignore\n\n"; char* gpu = (char*)glGetString(GL_RENDERER); fprintf(stderr, "GPU being used: %s\n", gpu); glClearColor( 0.1, 0.45, 0.5, 1.0 ); field = new Fluid(FLUIDSIZE, windowWidth); std::cout << "Installing shaders..."; //program.program[BLUR] = GLSL::loadShaders("shd/poisson.vert", "shd/poisson.frag"); program.program[FRAMEBUFFER] = GLSL::loadShadersGeom("shd/vert.glsl", "shd/geom.glsl", "shd/frag.glsl"); std::cout << "Completed\n"; //Here /*glGenFramebuffers(1, &program.frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, program.frameBuffer); glGenTextures(1, &program.texture); glBindTexture(GL_TEXTURE_2D, program.texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, windowHeight, windowWidth, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 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_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);*/ //To here GLSL::initShaderVars(); GLSL::initArrays(); GLSL::initVBO(); glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_TRUE); //General framecount variable int count = 0; glm::mat4 view = glm::mat4(1.f); glm::mat4 projection = glm::perspective(80.f, 1.f, 0.1f, 100.f); glm::mat4 scale; glm::mat4 translate; glm::mat4 rotate; glm::mat4 model; std::cout << "\n------ Simulator Controls ------\n"; std::cout << "Press 'v' to add velocity to the system.\n"; std::cout << "Press 'o' to empty the cube when it gets too full.\n"; std::cout << "Press 'p' to stop emptyig the cube.\n"; std::cout << "Press 'l' to toggle mobile spheres density insertion.\n"; std::cout << "Use WSQE to move the spheres around.\n"; std::cout << "\n------ Viewing Controls ------\n"; std::cout << "Press '1' to view blue smoke shading.\n"; std::cout << "Press '2' to view velocity magnitude shading.\n"; std::cout << "Press '3' to view velocity magnitude negative shading.\n"; std::cout << "Press 'a' to rotate the cube left.\n"; std::cout << "Press 'd' to rotate the cube right.\n"; std::cout << "Press '+' to zoom in.\n"; std::cout << "Press '-' to zoom out.\n"; while (!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program.program[FRAMEBUFFER]); //Camera::update(); Environment::setParams(field); GLSL::bufferData(field); glEnableVertexAttribArray( program.attribute_vertex ); glBindBuffer( GL_ARRAY_BUFFER, program.vbo ); glVertexAttribPointer( program.attribute_vertex, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 ); // Enable density array glEnableVertexAttribArray( program.attribute_density ); glBindBuffer( GL_ARRAY_BUFFER, program.dbo ); glVertexAttribPointer( program.attribute_density, 1, GL_FLOAT, GL_FALSE, 0, (void*)0 ); // Enable velocity array glEnableVertexAttribArray( program.attribute_velocity_x ); glBindBuffer( GL_ARRAY_BUFFER, program.velxbo ); glVertexAttribPointer( program.attribute_velocity_x, 1, GL_FLOAT, GL_FALSE, 0, (void*)0 ); // Enable velocity array glEnableVertexAttribArray( program.attribute_velocity_y ); glBindBuffer( GL_ARRAY_BUFFER, program.velybo ); glVertexAttribPointer( program.attribute_velocity_y, 1, GL_FLOAT, GL_FALSE, 0, (void*)0 ); // Enable velocity array glEnableVertexAttribArray(program.attribute_velocity_z); glBindBuffer(GL_ARRAY_BUFFER, program.velzbo); glVertexAttribPointer(program.attribute_velocity_z, 1, GL_FLOAT, GL_FALSE, 0, (void*)0); rotate = glm::rotate(glm::mat4(1.f), object.angle, glm::vec3(0.f, 1.f, 0.f)); scale = glm::scale(glm::mat4(1.f), glm::vec3(object.zoom, object.zoom, object.zoom)); translate = glm::translate(glm::mat4(1.f), glm::vec3(0.f, 0.f, -0.5f)); model = translate*scale*rotate; //Bind the index array glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, program.ibo ); glUniform1i( program.uniform_size, FLUIDSIZE ); glUniformMatrix4fv(program.uniform_proj_matrix, 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(program.uniform_view_matrix, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(program.uniform_model_matrix, 1, GL_FALSE, glm::value_ptr(model)); glUniform1i(program.uniform_shading_option, object.colorChoice); glUniform1i(program.uniform_pixel_size, object.pixelSize); glUniform3fv(program.uniform_color, 1, glm::value_ptr(object.color)); //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, program.texture, 0); //GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; //glDrawBuffers(1, DrawBuffers); //glUseProgram(program.program[BLUR]); assert(glGetError() == GL_NO_ERROR); glDrawElements(GL_POINTS, FLUIDSIZE*FLUIDSIZE*FLUIDSIZE, GL_UNSIGNED_INT, 0); assert(glGetError() == GL_NO_ERROR); glDisableVertexAttribArray(program.attribute_vertex); glDisableVertexAttribArray(program.attribute_density); glDisableVertexAttribArray(program.attribute_velocity_x); glDisableVertexAttribArray(program.attribute_velocity_y); glDisableVertexAttribArray(program.attribute_velocity_z); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //Here /*GLuint quad_vertexbuffer; glGenBuffers(1, &quad_vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(program.quad_vertex_array), program.quad_vertex_array, GL_STATIC_DRAW); glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, windowWidth, windowHeight); glUseProgram(program.program[BLUR]); glDrawArrays(GL_TRIANGLES, 0, 6);*/ //To here glUseProgram (0); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteFramebuffers(1, &program.frameBuffer); glDeleteBuffers(1, &program.vbo); glDeleteBuffers(1, &program.ibo); glDeleteBuffers(1, &program.velxbo); glDeleteBuffers(1, &program.velybo); glDeleteBuffers(1, &program.velzbo); glDeleteBuffers(1, &program.dbo); glfwTerminate(); delete field; return 0; }
sat_maker::~sat_maker() { glDeleteFramebuffers(2, fbo); glDeleteTextures(2, texture); //glDeleteTextures(2, depth_texture); }
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 ); }
FramebufferObject::~FramebufferObject() { glDeleteRenderbuffers(1, &depthRBO); glDeleteTextures(1, &FBOTexture); glDeleteFramebuffers(1, &FBO); }
void saveCorePNG (FILE * writer, GLuint texture, int w, int h) { GLint tw, th; glBindTexture (GL_TEXTURE_2D, texture); getTextureDimensions(texture, &tw, &th); GLubyte* image = new GLubyte [tw*th*4]; if (! checkNew (image)) return; glPixelStorei (GL_PACK_ALIGNMENT, 1); // glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image); #ifdef HAVE_GLES2 GLuint old_fbo, new_fbo; GLint old_vp[4]; glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&old_fbo); glGetIntegerv(GL_VIEWPORT, old_vp); glGenFramebuffers(1, &new_fbo); glBindFramebuffer(GL_FRAMEBUFFER, new_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); glViewport(0, 0, tw, th); glReadPixels(0, 0, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, image); glBindFramebuffer(GL_FRAMEBUFFER, old_fbo); glViewport(old_vp[0], old_vp[1], old_vp[2], old_vp[3]); glDeleteFramebuffers(1, &new_fbo); #else setPixelCoords (true); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLfloat texCoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; int xoffset = 0; while (xoffset < tw) { int w = (tw-xoffset < viewportWidth) ? tw-xoffset : viewportWidth; int yoffset = 0; while (yoffset < th) { int h = (th-yoffset < viewportHeight) ? th-yoffset : viewportHeight; glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)tw-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)-yoffset+th, 0., (GLfloat)tw-xoffset, (GLfloat)-yoffset+th, 0. }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); glUseProgram(0); for (int i = 0; i<h; i++) { glReadPixels(viewportOffsetX, viewportOffsetY+i, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, image+xoffset*4+(yoffset+i)*4*tw); } yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); #endif png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fatal ("Error saving image!"); return; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr){ png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fatal ("Error saving image!"); return; } png_init_io(png_ptr, writer); png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); unsigned char * row_pointers[h]; for (int i = 0; i < h; i++) { row_pointers[i] = image + 4*i*tw; } png_set_rows(png_ptr, info_ptr, row_pointers); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); delete [] image; image = NULL; }
ShadowMap::~ShadowMap() { glDeleteFramebuffers(1, &_framebufferId); glDeleteTextures(1, &_depthTextureId); }
void RenderManager::resize(int winWidth, int winHeight){ if(fragDataTex.size()>0){ glDeleteTextures(fragDataTex.size(),&fragDataTex[0]); glDeleteTextures(1,&fragDepthTex); glDeleteTextures(1, &fragNoiseTex); fragDataTex.clear(); glDeleteFramebuffers(1,&fragDataFB); } // The texture we're going to render to fragDataTex.resize(fragDataNamesP1.size()); // TEX1: Diffuse Texture glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glGenTextures(1, &fragDataTex[0]); glBindTexture(GL_TEXTURE_2D, fragDataTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, winWidth, winHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);//NULL means reserve texture memory, but texels are undefined // TEX2: Normal Texture glActiveTexture (GL_TEXTURE2); glEnable( GL_TEXTURE_2D ); glGenTextures(1, &fragDataTex[1]); glBindTexture(GL_TEXTURE_2D, fragDataTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, winWidth, winHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // TEX3: Original Position Texture glActiveTexture(GL_TEXTURE3); glEnable(GL_TEXTURE_2D); glGenTextures(1, &fragDataTex[2]); glBindTexture(GL_TEXTURE_2D, fragDataTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, winWidth, winHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // TEX4: AO Texture glActiveTexture(GL_TEXTURE4); glEnable(GL_TEXTURE_2D); glGenTextures(1, &fragAOTex); glBindTexture(GL_TEXTURE_2D, fragAOTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, winWidth, winHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // TEX5: Light intensity glActiveTexture(GL_TEXTURE5); glEnable(GL_TEXTURE_2D); glGenTextures(1, &fragDataTex[3]); glBindTexture(GL_TEXTURE_2D, fragDataTex[3]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);// GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, winWidth, winHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); ///////////////////////////////////////// // DEPTH glActiveTexture (GL_TEXTURE8); glEnable( GL_TEXTURE_2D ); glGenTextures(1, &fragDepthTex); glBindTexture(GL_TEXTURE_2D, fragDepthTex); //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, winWidth, winHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, winWidth, winHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTexture(GL_TEXTURE9); glEnable(GL_TEXTURE_2D); glGenTextures(1, &fragDepthTex_AO); glBindTexture(GL_TEXTURE_2D, fragDepthTex_AO); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, winWidth, winHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ///////////////////////////////////////// // FRAME BUFFER fragDataFB = 0; glGenFramebuffers(1, &fragDataFB); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fragDataTex[0], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fragDataTex[1], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, fragDataTex[2], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, fragDataTex[3], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fragDepthTex, 0); // Set the list of draw buffers. GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, DrawBuffers); // "3" is the size of DrawBuffers // Always check that our framebuffer is ok if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){ printf("+1ERROR: GL_FRAMEBUFFER_COMPLETE false\n"); exit(0); } glBindFramebuffer(GL_FRAMEBUFFER, 0); // FRAME BUFFER AO fragDataFB_AO = 0; glGenFramebuffers(1, &fragDataFB_AO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fragAOTex, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fragDepthTex, 0); // Set the list of draw buffers. GLenum DrawBuffers_AO[] = { GL_COLOR_ATTACHMENT0 }; glDrawBuffers(1, DrawBuffers_AO); // "3" is the size of DrawBuffers // Always check that our framebuffer is ok if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("+2ERROR: GL_FRAMEBUFFER_COMPLETE false\n"); exit(0); } glBindFramebuffer(GL_FRAMEBUFFER, 0); ////////////////////////////////////////////////////////////////////////////////// // Noise fragNoiseTex = 0; glActiveTexture(GL_TEXTURE7); glEnable(GL_TEXTURE_2D); glGenTextures(1, &fragNoiseTex); glBindTexture(GL_TEXTURE_2D, fragNoiseTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); qsrand(5648943215); int sizeX = winWidth; int sizeZ = winHeight; std::vector<GLfloat> data(sizeX*sizeZ*3); for (int c = 0; c < sizeX*sizeZ*3; c++) { if (c % 3 == 0 || c % 3 == 1) data[c] = (float(qrand()) / RAND_MAX)*2.0f - 1.0f; else data[c] = 0.0f; //0 in component z } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, sizeX, sizeZ, 0, GL_RGB, GL_FLOAT, &data[0]); glGenerateMipmap(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); resizeSsaoKernel(); }//
FrameBuffer::~FrameBuffer() { glDeleteFramebuffers(1,&m_frameBuffer); glDeleteRenderbuffers(1,&m_depthBuffer); glDeleteTextures(1, &m_targetTexture); }
void FramebufferImplementation_Legacy::destroy(GLuint id) const { glDeleteFramebuffers(1, &id); }
GLFrameBuffer::~GLFrameBuffer() { glDeleteFramebuffers( 1, &fbo_id ); // FIXME: Should clean up texture and renderbuffer attachments as well!! }
MLAcceleratedImageFilter::~MLAcceleratedImageFilter() { glDeleteFramebuffers(1, &_fboId); glDeleteRenderbuffers(1, &_rboId); }
GBuffer::~GBuffer() { glDeleteFramebuffers(1, &framebuffer); glDeleteTextures(textures.size(), textures.data() ); glDeleteTextures(1, &depthTexture); }
//----------------------------------------------------------------------------- // Destructor //----------------------------------------------------------------------------- FBO::~FBO() { glDeleteTextures(1, &m_ColorTextureID); glDeleteFramebuffers(1, &m_FrameBuffer); }
/** * Test one cube map face to see if glGetTexImage from a cube face into * a PBO works correctly. */ static bool test_face(GLuint face) { const GLenum cubeFaceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; const GLuint expectedColor = Colors[face]; GLuint texData[TEX_NUMPIXELS]; GLuint cubeTex, fbo, packPBO; GLuint f, i; void *ptr; /* Create the cubemap texture. */ glGenTextures(1, &cubeTex); glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex); glPixelStorei(GL_UNPACK_ROW_LENGTH, TEX_WIDTH); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (f = 0; f < 6; ++f) { for (i = 0; i < TEX_NUMPIXELS; ++i) { texData[i] = Colors[f]; } glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, 0, GL_SRGB8_ALPHA8, TEX_WIDTH, TEX_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData); } /* Setup the FBO. */ glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeFaceTarget, cubeTex, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("Incomplete framebuffer object\n"); return false; } glDrawBuffer(GL_COLOR_ATTACHMENT0); /* Read back cubemap face into PBO */ glGenBuffers(1, &packPBO); glBindBuffer(GL_PIXEL_PACK_BUFFER, packPBO); glBufferData(GL_PIXEL_PACK_BUFFER, TEX_NUMPIXELS * sizeof(GLuint), NULL, GL_STREAM_READ); glPixelStorei(GL_PACK_ROW_LENGTH, TEX_WIDTH); glPixelStorei(GL_PACK_ALIGNMENT, 1); glGetTexImage(cubeFaceTarget, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); /* Map pack PBO to get results. */ ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (!ptr) { printf("failed to map PBO\n"); return false; } for (i = 0; i < TEX_NUMPIXELS; ++i) { texData[i] = Colors[6]; /* gray */ } memcpy(texData, ptr, TEX_NUMPIXELS * sizeof(GLuint)); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); if (expectedColor != texData[0]) { printf("Colors don't match for face %u\n", face); printf("Expected 0x%08x but found 0x%08x \n", expectedColor, texData[0]); return false; } glDeleteTextures(1, &cubeTex); glDeleteFramebuffers(1, &fbo); glDeleteBuffers(1, &packPBO); /* if we get here we passed */ return true; }
void sglDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { glDeleteFramebuffers(n, framebuffers); }
/** @brief @param sizeTex 목표 크기 */ void XGraphicsOpenGL::ResizeTexture( ID idTex, const XE::POINT& sizeTexPrev, const XE::POINT& sizeTexNew, GLenum glType, GLenum glFormatSurface ) { // FBO생성 GLuint fbo; glGenFramebuffers( 1, &fbo ); glBindFramebuffer( GL_FRAMEBUFFER, fbo ); // idTex를 어태치 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, idTex, 0 ); _CHECK_GL_ERROR(); GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); if( status != GL_FRAMEBUFFER_COMPLETE ) { XTRACE( "fbo status=%d", status ); return; } // 임시 텍스쳐버퍼 생성 GLuint glTexTemp; glGenTextures( 1, &glTexTemp ); _CHECK_GL_ERROR(); glBindTexture( GL_TEXTURE_2D, glTexTemp ); _CHECK_GL_ERROR(); auto glFormatMem = glFormatSurface; // 둘은 반드시 일치해야한다., glTexImage2D( GL_TEXTURE_2D, 0, glFormatSurface, // internal format sizeTexPrev.w, sizeTexPrev.h, 0, glFormatMem, // pImgSrc의 포맷 glType, nullptr ); _CHECK_GL_ERROR(); // 어태치된 소스측 텍스쳐로부터 임시버퍼로 카피 glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sizeTexPrev.w, sizeTexPrev.h ); _CHECK_GL_ERROR(); // 소스측 어태치 해제 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 ); _CHECK_GL_ERROR(); // 임시버퍼를 FBO에 어태치 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexTemp, 0 ); _CHECK_GL_ERROR(); status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); if( status != GL_FRAMEBUFFER_COMPLETE ) { XTRACE( "fbo status=%d", status ); return; } // 리사이징 XGraphicsOpenGL::sBindTexture( idTex ); _CHECK_GL_ERROR(); auto pClearBuff = new DWORD[ (int)sizeTexNew.Size() ]; memset( pClearBuff, 0, sizeof(DWORD) * (int)sizeTexNew.Size() ); glTexImage2D( GL_TEXTURE_2D, 0, glFormatSurface, // internal format sizeTexNew.w, sizeTexNew.h, 0, glFormatMem, // pImgSrc의 포맷 glType, pClearBuff /*nullptr*/ ); _CHECK_GL_ERROR(); SAFE_DELETE_ARRAY( pClearBuff ); // 어태치된 임시버퍼 텍스쳐로부터 리사이징된 원래텍스쳐로 카피 glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sizeTexPrev.w, sizeTexPrev.h ); _CHECK_GL_ERROR(); // 임시버퍼 삭제 glDeleteTextures( 1, &glTexTemp ); glTexTemp = 0; _CHECK_GL_ERROR(); glDeleteFramebuffers( 1, &fbo ); _CHECK_GL_ERROR(); }
PGRAPH_OpenGL::~PGRAPH_OpenGL() { glDeleteFramebuffers(1, &framebuffer); }
Framebuffer::~Framebuffer() { glDeleteTextures(1, &_colorTexture); //glDeleteTextures(1, &_depthTexture); glDeleteFramebuffers(1, &_fbo); }