// --------------------------------------------------------------------------- // Function: prep_framebuffers // Design: Belongs to OpenGL component // Purpose: // Updated: Sep 10, 2012 // --------------------------------------------------------------------------- void prep_framebuffers() { if (!GL_ARB_framebuffer_object || !glewGetExtension("GL_ARB_framebuffer_object")) { std::cerr << "NO FBO SUPPORT" << std::endl; exit(EXIT_FAILURE); } else { std::cout << "GL_ARB_framebuffer_object SUPPORT" << std::endl; } // if (!checkForErrors()) { // std::cerr << "Stage 0w - Problem generating desktop FBO" << std::endl; // exit(EXIT_FAILURE); // } checkForErrors(); glGenFramebuffers(1, &desktopFBO); if (!checkForErrors()) { std::cerr << "Stage 0z - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } glBindFramebuffer(GL_FRAMEBUFFER, desktopFBO); if (!checkForErrors() ) { std::cerr << "Stage 0y - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } if(desktopTexture == 0) { glGenTextures(1, &desktopTexture); } glBindTexture(GL_TEXTURE_2D, desktopTexture); if (!checkForErrors()) { std::cerr << "Stage 0a - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (!checkForErrors()) { std::cerr << "Stage 0b - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); if (!checkForErrors()) { std::cerr << "Stage 0c - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, physicalWidth, physicalHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); if (!checkForErrors()) { std::cerr << "Stage 0d - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, desktopTexture, 0); if (!checkForErrors() || glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "Stage 0e - Problem generating desktop FBO" << std::endl; exit(EXIT_FAILURE); } glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffers(2, fbos); glGenRenderbuffers(1, &depthBuffer); glGenTextures(2, textures); for (int i = 0; i < 1; ++i) {//2; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]); glBindTexture(GL_TEXTURE_2D, textures[i]); 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_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i], 0); glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer); if (i == 0) { glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, textureWidth, textureHeight); } glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer); if (!checkForErrors()) { std::cerr << "Stage 1 - Problem generating FBO " << i << std::endl; exit(EXIT_FAILURE); } std::cout << "Generating FBO #" << i << std::endl; std::cout << "FBO: " << textureWidth << "x" << textureHeight << std::endl; if (!checkForErrors() || glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cerr << "Stage 2 - Problem generating FBO " << i << std::endl; exit(EXIT_FAILURE); } glBindFramebuffer(GL_FRAMEBUFFER, 0); } }
vsSurface::vsSurface( const Settings& settings, bool depthOnly, bool multisample ): m_width(settings.width), m_height(settings.height), m_texture(0), m_textureCount(settings.buffers), m_depth(0), m_stencil(0), m_fbo(0), m_isRenderbuffer(false) { CheckGLError("vsSurface"); GLint maxSamples = 0; if ( multisample ) glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); GLenum internalFormat = GL_RGBA8; GLenum pixelFormat = GL_RGBA; GLenum type = GL_UNSIGNED_INT_8_8_8_8_REV; GLenum filter = settings.linear ? GL_LINEAR : GL_NEAREST; vsAssert( !( multisample && settings.mipMaps ), "Can't do both multisample and mipmaps!" ); glActiveTexture(GL_TEXTURE0); // create FBO glGenFramebuffers(1, &m_fbo); glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); m_texture = new GLuint[m_textureCount]; if ( depthOnly ) { glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } else { for ( int i = 0; i < m_textureCount; i++ ) { if (multisample) { glGenRenderbuffers(1, &m_texture[i]); glBindRenderbuffer( GL_RENDERBUFFER, m_texture[i] ); glRenderbufferStorageMultisample( GL_RENDERBUFFER, maxSamples, pixelFormat, m_width, m_height ); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, m_texture[i]); m_isRenderbuffer = true; } else { glGenTextures(1, &m_texture[i]); glBindTexture(GL_TEXTURE_2D, m_texture[i]); m_isRenderbuffer = false; glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_width, m_height, 0, pixelFormat, type, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_TEXTURE_2D, m_texture[i], 0); if ( settings.mipMaps ) { glGenerateMipmap(GL_TEXTURE_2D); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f ); glBindTexture(GL_TEXTURE_2D, 0); } } } if (settings.depth || depthOnly) { if ( multisample ) { glGenRenderbuffers(1, &m_depth); glBindRenderbuffer(GL_RENDERBUFFER, m_depth); if ( settings.stencil ) { glRenderbufferStorageMultisample( GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, m_width, m_height ); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depth); } else { glRenderbufferStorageMultisample( GL_RENDERBUFFER, maxSamples, GL_DEPTH_COMPONENT24, m_width, m_height ); } glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth); } else { glGenTextures(1, &m_depth); glBindTexture(GL_TEXTURE_2D, m_depth); //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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); //glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); //if ( stencil ) //{ //glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_width, m_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); //} //else { glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_width, m_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); } glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depth, 0); } } CheckFBO(); glBindFramebuffer(GL_FRAMEBUFFER, 0); CheckGLError("vsSurface"); }
bool GBuffer::setupFbo(unsigned int windowWidth, unsigned int windowHeight) { m_buffer_w = windowWidth; m_buffer_h = windowHeight; // delete existing fbo, textures, and render buffer in case we are regenerating at new size glDeleteTextures(GBUFFER_NUM_TEXTURES, m_textures); glDeleteRenderbuffers(1, &m_renderBuffer); glDeleteFramebuffers(1, &m_fbo); // create an fbo glGenFramebuffers(1, &m_fbo); glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // create all gbuffer textures glGenTextures(GBUFFER_NUM_TEXTURES, m_textures); // albedo/diffuse (16-bit channel rgba) glBindTexture(GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_ALBEDO]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_buffer_w, m_buffer_h, 0, GL_RGBA, GL_FLOAT, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_TEXTURE_TYPE_ALBEDO, GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_ALBEDO], 0); // normals + depth (32-bit RGBA float for accuracy) glBindTexture(GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_NORMALS_DEPTH]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_buffer_w, m_buffer_h, 0, GL_RGBA, GL_FLOAT, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_TEXTURE_TYPE_NORMALS_DEPTH, GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_NORMALS_DEPTH], 0); // lighting pass (16-bit RGBA) glBindTexture(GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_LIGHT_PASS]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_buffer_w, m_buffer_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_TEXTURE_TYPE_LIGHT_PASS, GL_TEXTURE_2D, m_textures[GBUFFER_TEXTURE_TYPE_LIGHT_PASS], 0); // create depth texture (we don't use this explicitly, but since we use depth testing when rendering + for our stencil pass, our FBO needs a depth buffer) // we make it a renderbuffer and not a texture as we'll never access it directly in a shader glGenRenderbuffers(1, &m_renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH32F_STENCIL8, m_buffer_w, m_buffer_h); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_renderBuffer); // check status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); if (status != GL_FRAMEBUFFER_COMPLETE) { ofLogError("GBuffer::setupFbo()", "Could not create framebuffer"); return false; } return true; }
int main() { // glfw: initialize and configure // ------------------------------ 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); // uncomment this statement to fix compilation on OS X // glfw window creation // -------------------- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // tell GLFW to capture our mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // glad: load all OpenGL function pointers // --------------------------------------- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); // build and compile shaders // ------------------------- Shader shader("6.lighting.vs", "6.lighting.fs"); Shader hdrShader("6.hdr.vs", "6.hdr.fs"); // load textures // ------------- unsigned int woodTexture = loadTexture(FileSystem::getPath("resources/textures/wood.png").c_str(), true); // note that we're loading the texture as an SRGB texture // configure floating point framebuffer // ------------------------------------ unsigned int hdrFBO; glGenFramebuffers(1, &hdrFBO); // create floating point color buffer unsigned int colorBuffer; glGenTextures(1, &colorBuffer); glBindTexture(GL_TEXTURE_2D, colorBuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // create depth buffer (renderbuffer) unsigned int rboDepth; glGenRenderbuffers(1, &rboDepth); glBindRenderbuffer(GL_RENDERBUFFER, rboDepth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, SCR_WIDTH, SCR_HEIGHT); // attach buffers glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "Framebuffer not complete!" << std::endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); // lighting info // ------------- // positions std::vector<glm::vec3> lightPositions; lightPositions.push_back(glm::vec3( 0.0f, 0.0f, 49.5f)); // back light lightPositions.push_back(glm::vec3(-1.4f, -1.9f, 9.0f)); lightPositions.push_back(glm::vec3( 0.0f, -1.8f, 4.0f)); lightPositions.push_back(glm::vec3( 0.8f, -1.7f, 6.0f)); // colors std::vector<glm::vec3> lightColors; lightColors.push_back(glm::vec3(200.0f, 200.0f, 200.0f)); lightColors.push_back(glm::vec3(0.1f, 0.0f, 0.0f)); lightColors.push_back(glm::vec3(0.0f, 0.0f, 0.2f)); lightColors.push_back(glm::vec3(0.0f, 0.1f, 0.0f)); // shader configuration // -------------------- shader.use(); shader.setInt("diffuseTexture", 0); hdrShader.use(); hdrShader.setInt("hdrBuffer", 0); // render loop // ----------- while (!glfwWindowShouldClose(window)) { // per-frame time logic // -------------------- float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // input // ----- processInput(window); // render // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 1. render scene into floating point framebuffer // ----------------------------------------------- glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)SCR_WIDTH / (GLfloat)SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); shader.use(); shader.setMat4("projection", projection); shader.setMat4("view", view); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, woodTexture); // set lighting uniforms for (unsigned int i = 0; i < lightPositions.size(); i++) { shader.setVec3("lights[" + std::to_string(i) + "].Position", lightPositions[i]); shader.setVec3("lights[" + std::to_string(i) + "].Color", lightColors[i]); } shader.setVec3("viewPos", camera.Position); // render tunnel glm::mat4 model = glm::mat4(); model = glm::translate(model, glm::vec3(0.0f, 0.0f, 25.0)); model = glm::scale(model, glm::vec3(2.5f, 2.5f, 27.5f)); shader.setMat4("model", model); shader.setInt("inverse_normals", true); renderCube(); glBindFramebuffer(GL_FRAMEBUFFER, 0); // 2. now render floating point color buffer to 2D quad and tonemap HDR colors to default framebuffer's (clamped) color range // -------------------------------------------------------------------------------------------------------------------------- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); hdrShader.use(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, colorBuffer); hdrShader.setInt("hdr", hdr); hdrShader.setFloat("exposure", exposure); renderQuad(); std::cout << "hdr: " << (hdr ? "on" : "off") << "| exposure: " << exposure << std::endl; // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }
void Framebuffer::attachColorBuffer(const Renderbuffer& rb) { bind(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb.getHandle()); _color = true; }
void OGLESTexture2D::CopyToSubTextureCube(Texture& target, uint32_t dst_array_index, CubeFaces dst_face, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height, uint32_t src_array_index, CubeFaces src_face, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height) { KFL_UNUSED(src_face); BOOST_ASSERT(TT_Cube == target.Type()); OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if (glloader_GLES_VERSION_3_0() && ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_))))) { GLuint fbo_src, fbo_dst; re.GetFBOForBlit(fbo_src, fbo_dst); GLuint old_fbo = re.BindFramebuffer(); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src); if (array_size_ > 1) { glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index); } else { if (sample_count_ <= 1) { glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level); } else { glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texture_); } } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst); if (target.ArraySize() > 1) { glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, dst_level, dst_array_index * 6 + dst_face - CF_Positive_X); } else { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + dst_face, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level); } glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height, dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height, GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR); re.BindFramebuffer(old_fbo, true); } else { if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format())) { if (IsCompressedFormat(format_)) { BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3))); BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3))); BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3))); BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3))); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height); Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height); uint32_t const block_size = NumFormatBytes(format_) * 4; uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; y += 4) { std::memcpy(d, s, src_width / 4 * block_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } else { size_t const format_size = NumFormatBytes(format_); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height); Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height); uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; ++ y) { std::memcpy(d, s, src_width * format_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } } else { this->ResizeTextureCube(target, dst_array_index, dst_face, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height, src_array_index, CF_Positive_X, src_level, src_x_offset, src_y_offset, src_width, src_height, true); } } }
void createFramebuffer() { glActiveTexture(GL_TEXTURE0); glGenTextures(1, &FBOTexture); glBindTexture(GL_TEXTURE_2D, FBOTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FRAME_BUFFER_WIDTH, FRAME_BUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glGenRenderbuffers(1, &FBODepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, FBODepthBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, FRAME_BUFFER_WIDTH, FRAME_BUFFER_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); glGenFramebuffers(1, &frameBufferObject); glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, FBOTexture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER, FBODepthBuffer); GLenum status; if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { cout << "Issue with Framebuffers" << endl; } float vertices[] = { -1, -1, 1, -1, -1, 1, 1, 1, }; glGenVertexArrays(1, &fullScreenVAO); glBindVertexArray(fullScreenVAO); glGenBuffers(1, &fullScreenVBO); glBindBuffer(GL_ARRAY_BUFFER, fullScreenVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer( 0, // attribute 2, // number of elements per vertex, here (x,y) GL_FLOAT, // the type of each element GL_FALSE, // take our values as-is 0, // no extra data between each position 0 // offset of first element ); GLuint vertexShaderProgram = 0; string vsPath = ASSET_PATH + SHADER_PATH + "/simplePostProcessVS.glsl"; vertexShaderProgram = loadShaderFromFile(vsPath, VERTEX_SHADER); checkForCompilerErrors(vertexShaderProgram); GLuint fragmentShaderProgram = 0; string fsPath = ASSET_PATH + SHADER_PATH + "/simplePostProcessFS.glsl"; fragmentShaderProgram = loadShaderFromFile(fsPath, FRAGMENT_SHADER); checkForCompilerErrors(fragmentShaderProgram); fullScreenShaderProgram = glCreateProgram(); glAttachShader(fullScreenShaderProgram, vertexShaderProgram); glAttachShader(fullScreenShaderProgram, fragmentShaderProgram); //Link attributes glBindAttribLocation(fullScreenShaderProgram, 0, "vertexPosition"); glLinkProgram(fullScreenShaderProgram); checkForLinkErrors(fullScreenShaderProgram); //now we can delete the VS & FS Programs glDeleteShader(vertexShaderProgram); glDeleteShader(fragmentShaderProgram); }
FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) { CheckGLExtensions(); #ifndef USING_GLES2 if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) { return fbo_ext_create(width, height, num_color_textures, z_stencil, colorDepth); } else if (!gl_extensions.ARB_framebuffer_object) { return nullptr; } // If GLES2, we have basic FBO support and can just proceed. #endif FBO *fbo = new FBO(); fbo->native_fbo = false; fbo->width = width; fbo->height = height; fbo->colorDepth = colorDepth; // Color texture is same everywhere glGenFramebuffers(1, &fbo->handle); glGenTextures(1, &fbo->color_texture); // Create the surfaces. glBindTexture(GL_TEXTURE_2D, fbo->color_texture); 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // TODO: We could opt to only create 16-bit render targets on slow devices. For later. switch (colorDepth) { case FBO_8888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; case FBO_4444: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL); break; case FBO_5551: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL); break; case FBO_565: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); break; } 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (gl_extensions.IsGLES) { if (gl_extensions.OES_packed_depth_stencil) { ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", width, height); // Standard method fbo->stencil_buffer = 0; fbo->z_buffer = 0; // 24-bit Z, 8-bit stencil combined glGenRenderbuffers(1, &fbo->z_stencil_buffer); glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); // Bind it all together glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); } else { ILOG("Creating %i x %i FBO using separate stencil", width, height); // TEGRA fbo->z_stencil_buffer = 0; // 16/24-bit Z, separate 8-bit stencil glGenRenderbuffers(1, &fbo->z_buffer); glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_buffer); // Don't forget to make sure fbo_standard_z_depth() matches. glRenderbufferStorage(GL_RENDERBUFFER, gl_extensions.OES_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, width, height); // 8-bit stencil buffer glGenRenderbuffers(1, &fbo->stencil_buffer); glBindRenderbuffer(GL_RENDERBUFFER, fbo->stencil_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height); // Bind it all together glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer); } } else { fbo->stencil_buffer = 0; fbo->z_buffer = 0; // 24-bit Z, 8-bit stencil glGenRenderbuffers(1, &fbo->z_stencil_buffer); glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); // Bind it all together glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); } GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch(status) { case GL_FRAMEBUFFER_COMPLETE: // ILOG("Framebuffer verified complete."); break; case GL_FRAMEBUFFER_UNSUPPORTED: ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); break; default: FLOG("Other framebuffer error: %i", status); break; } // Unbind state we don't need glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); currentDrawHandle_ = fbo->handle; currentReadHandle_ = fbo->handle; return fbo; }
bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat format, GLuint depthStencilFormat) { CCASSERT(format != Texture2D::PixelFormat::A8, "only RGB and RGBA formats are valid for a render texture"); bool ret = false; void *data = nullptr; do { _fullRect = _rtTextureRect = Rect(0,0,w,h); //Size size = Director::getInstance()->getWinSizeInPixels(); //_fullviewPort = Rect(0,0,size.width,size.height); w = (int)(w * CC_CONTENT_SCALE_FACTOR()); h = (int)(h * CC_CONTENT_SCALE_FACTOR()); _fullviewPort = Rect(0,0,w,h); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO); // textures must be power of two squared int powW = 0; int powH = 0; if (Configuration::getInstance()->supportsNPOT()) { powW = w; powH = h; } else { powW = ccNextPOT(w); powH = ccNextPOT(h); } auto dataLen = powW * powH * 4; data = malloc(dataLen); CC_BREAK_IF(! data); memset(data, 0, dataLen); _pixelFormat = format; _texture = new (std::nothrow) Texture2D(); if (_texture) { _texture->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h)); } else { break; } GLint oldRBO; glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldRBO); if (Configuration::getInstance()->checkForGLExtension("GL_QCOM")) { _textureCopy = new (std::nothrow) Texture2D(); if (_textureCopy) { _textureCopy->initWithData(data, dataLen, (Texture2D::PixelFormat)_pixelFormat, powW, powH, Size((float)w, (float)h)); } else { break; } } // generate FBO glGenFramebuffers(1, &_FBO); glBindFramebuffer(GL_FRAMEBUFFER, _FBO); // associate texture with FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0); if (depthStencilFormat != 0) { //create and attach depth buffer glGenRenderbuffers(1, &_depthRenderBufffer); glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBufffer); glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, (GLsizei)powW, (GLsizei)powH); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBufffer); // if depth format is the one with stencil part, bind same render buffer as stencil attachment if (depthStencilFormat == GL_DEPTH24_STENCIL8) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBufffer); } } // check if it worked (probably worth doing :) ) CCASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Could not attach texture to framebuffer"); _texture->setAliasTexParameters(); // retained setSprite(Sprite::createWithTexture(_texture)); _texture->release(); _sprite->setFlippedY(true); _sprite->setBlendFunc( BlendFunc::ALPHA_PREMULTIPLIED ); glBindRenderbuffer(GL_RENDERBUFFER, oldRBO); glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO); // Diabled by default. _autoDraw = false; // add sprite for backward compatibility addChild(_sprite); ret = true; } while (0); CC_SAFE_FREE(data); return ret; }
void GLES2FrameBufferObject::initialise() { // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); mManager->releaseRenderBuffer(mMultisampleColourBuffer); /// First buffer must be bound if(!mColour[0].buffer) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attachment 0 must have surface attached", "GLES2FrameBufferObject::initialise"); } // If we're doing multisampling, then we need another FBO which contains a // renderbuffer which is set up to multisample, and we'll blit it to the final // FBO afterwards to perform the multisample resolve. In that case, the // mMultisampleFB is bound during rendering and is the one with a depth/stencil ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets(); /// Store basic stats size_t width = mColour[0].buffer->getWidth(); size_t height = mColour[0].buffer->getHeight(); GLuint format = mColour[0].buffer->getGLFormat(); // Bind simple buffer to add colour attachments glBindFramebuffer(GL_FRAMEBUFFER, mFB); GL_CHECK_ERROR; /// Bind all attachment points to frame buffer for(size_t x=0; x<maxSupportedMRTs; ++x) { if(mColour[x].buffer) { if(mColour[x].buffer->getWidth() != width || mColour[x].buffer->getHeight() != height) { StringStream ss; ss << "Attachment " << x << " has incompatible size "; ss << mColour[x].buffer->getWidth() << "x" << mColour[x].buffer->getHeight(); ss << ". It must be of the same as the size of surface 0, "; ss << width << "x" << height; ss << "."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLES2FrameBufferObject::initialise"); } if(mColour[x].buffer->getGLFormat() != format) { StringStream ss; ss << "Attachment " << x << " has incompatible format."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLES2FrameBufferObject::initialise"); } mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0+x, mColour[x].zoffset); } else { // Detach glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+x, GL_RENDERBUFFER, 0); GL_CHECK_ERROR; } } // Now deal with depth / stencil if (mMultisampleFB) { // Bind multisample buffer glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB); GL_CHECK_ERROR; // Create AA render buffer (colour) // note, this can be shared too because we blit it to the final FBO // right after the render is finished mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); // Attach it, because we won't be attaching below and non-multisample has // actually been attached to other FBO mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, mMultisampleColourBuffer.zoffset); // depth & stencil will be dealt with below } GL_CHECK_ERROR; /// Depth buffer is not handled here anymore. /// See GLES2FrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; for(size_t x=0; x<OGRE_MAX_MULTIPLE_RENDER_TARGETS; ++x) { // Fill attached colour buffers if(mColour[x].buffer) { bufs[x] = GL_COLOR_ATTACHMENT0 + x; } else { bufs[x] = GL_NONE; } } /// Check status GLuint status; status = glCheckFramebufferStatus(GL_FRAMEBUFFER); GL_CHECK_ERROR; /// Bind main buffer #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // The screen buffer is 1 on iOS glBindFramebuffer(GL_FRAMEBUFFER, 1); #else glBindFramebuffer(GL_FRAMEBUFFER, 0); #endif GL_CHECK_ERROR; switch(status) { case GL_FRAMEBUFFER_COMPLETE: // All is good break; case GL_FRAMEBUFFER_UNSUPPORTED: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "All framebuffer formats with this texture internal format unsupported", "GLES2FrameBufferObject::initialise"); default: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Framebuffer incomplete or other FBO status error", "GLES2FrameBufferObject::initialise"); } }
int main() { // glfw: initialize and configure // ------------------------------ 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); // uncomment this statement to fix compilation on OS X // glfw window creation // -------------------- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // tell GLFW to capture our mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // glad: load all OpenGL function pointers // --------------------------------------- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); // build and compile shaders // ------------------------- Shader shader("5.1.framebuffers.vs", "5.1.framebuffers.fs"); Shader screenShader("5.1.framebuffers_screen.vs", "5.1.framebuffers_screen.fs"); // set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ float cubeVertices[] = { // positions // texture Coords -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; float planeVertices[] = { // positions // texture Coords 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, -5.0f, -0.5f, 5.0f, 0.0f, 0.0f, -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, 5.0f, -0.5f, -5.0f, 2.0f, 2.0f }; float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates. // positions // texCoords -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 }; // cube VAO unsigned int cubeVAO, cubeVBO; glGenVertexArrays(1, &cubeVAO); glGenBuffers(1, &cubeVBO); glBindVertexArray(cubeVAO); glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // plane VAO unsigned int planeVAO, planeVBO; glGenVertexArrays(1, &planeVAO); glGenBuffers(1, &planeVBO); glBindVertexArray(planeVAO); glBindBuffer(GL_ARRAY_BUFFER, planeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // screen quad VAO unsigned int quadVAO, quadVBO; glGenVertexArrays(1, &quadVAO); glGenBuffers(1, &quadVBO); glBindVertexArray(quadVAO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); // load textures // ------------- unsigned int cubeTexture = loadTexture(FileSystem::getPath("resources/textures/marble.jpg").c_str()); unsigned int floorTexture = loadTexture(FileSystem::getPath("resources/textures/metal.png").c_str()); // shader configuration // -------------------- shader.use(); shader.setInt("texture1", 0); screenShader.use(); screenShader.setInt("screenTexture", 0); // framebuffer configuration // ------------------------- unsigned int framebuffer; glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); // create a color attachment texture unsigned int textureColorbuffer; glGenTextures(1, &textureColorbuffer); glBindTexture(GL_TEXTURE_2D, textureColorbuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0); // create a renderbuffer object for depth and stencil attachment (we won't be sampling these) unsigned int rbo; glGenRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it // now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); // draw as wireframe //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // render loop // ----------- while (!glfwWindowShouldClose(window)) { // per-frame time logic // -------------------- float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // input // ----- processInput(window); // render // ------ // bind to framebuffer and draw scene as we normally would to color texture glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad) // make sure we clear the framebuffer's content glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.use(); glm::mat4 model; glm::mat4 view = camera.GetViewMatrix(); glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); shader.setMat4("view", view); shader.setMat4("projection", projection); // cubes glBindVertexArray(cubeVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, cubeTexture); model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f)); shader.setMat4("model", model); glDrawArrays(GL_TRIANGLES, 0, 36); model = glm::mat4(); model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f)); shader.setMat4("model", model); glDrawArrays(GL_TRIANGLES, 0, 36); // floor glBindVertexArray(planeVAO); glBindTexture(GL_TEXTURE_2D, floorTexture); shader.setMat4("model", glm::mat4()); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); // now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture glBindFramebuffer(GL_FRAMEBUFFER, 0); glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test. // clear all relevant buffers glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways) glClear(GL_COLOR_BUFFER_BIT); screenShader.use(); glBindVertexArray(quadVAO); glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // use the color attachment texture as the texture of the quad plane glDrawArrays(GL_TRIANGLES, 0, 6); // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); } // optional: de-allocate all resources once they've outlived their purpose: // ------------------------------------------------------------------------ glDeleteVertexArrays(1, &cubeVAO); glDeleteVertexArrays(1, &planeVAO); glDeleteVertexArrays(1, &quadVAO); glDeleteBuffers(1, &cubeVBO); glDeleteBuffers(1, &planeVBO); glDeleteBuffers(1, &quadVBO); glfwTerminate(); return 0; }
int main() { // glfw: initialize and configure // ------------------------------ glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X #endif // glfw window creation // -------------------- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // tell GLFW to capture our mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // glad: load all OpenGL function pointers // --------------------------------------- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); // build and compile shaders // ------------------------- Shader shader("11.anti_aliasing.vs", "11.anti_aliasing.fs"); Shader screenShader("11.aa_post.vs", "11.aa_post.fs"); // set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ float cubeVertices[] = { // positions -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates. // positions // texCoords -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 }; // setup cube VAO unsigned int cubeVAO, cubeVBO; glGenVertexArrays(1, &cubeVAO); glGenBuffers(1, &cubeVBO); glBindVertexArray(cubeVAO); glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // setup screen VAO unsigned int quadVAO, quadVBO; glGenVertexArrays(1, &quadVAO); glGenBuffers(1, &quadVBO); glBindVertexArray(quadVAO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); // configure MSAA framebuffer // -------------------------- unsigned int framebuffer; glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); // create a multisampled color attachment texture unsigned int textureColorBufferMultiSampled; glGenTextures(1, &textureColorBufferMultiSampled); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0); // create a (also multisampled) renderbuffer object for depth and stencil attachments unsigned int rbo; glGenRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); // configure second post-processing framebuffer unsigned int intermediateFBO; glGenFramebuffers(1, &intermediateFBO); glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO); // create a color attachment texture unsigned int screenTexture; glGenTextures(1, &screenTexture); glBindTexture(GL_TEXTURE_2D, screenTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); // shader configuration // -------------------- shader.use(); screenShader.setInt("screenTexture", 0); // render loop // ----------- while (!glfwWindowShouldClose(window)) { // per-frame time logic // -------------------- float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // input // ----- processInput(window); // render // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 1. draw scene as normal in multisampled buffers glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // set transformation matrices shader.use(); glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 1000.0f); shader.setMat4("projection", projection); shader.setMat4("view", camera.GetViewMatrix()); shader.setMat4("model", glm::mat4(1.0f)); glBindVertexArray(cubeVAO); glDrawArrays(GL_TRIANGLES, 0, 36); // 2. now blit multisampled buffer(s) to normal colorbuffer of intermediate FBO. Image is stored in screenTexture glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO); glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); // 3. now render quad with scene's visuals as its texture image glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); // draw Screen quad screenShader.use(); glBindVertexArray(quadVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, screenTexture); // use the now resolved color attachment as the quad's texture glDrawArrays(GL_TRIANGLES, 0, 6); // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }
int main(int argc, char* argv[]) { log_data = new Log(); // ugh SDL_Window* window = 0; SDL_GLContext gl = 0; int win_w; int win_h; if(initGL(&window, &gl, &win_w, &win_h) == 1) return 1; GLuint gl_depth_buff_id; GLuint gl_framebuffer_id; blit_renderer br; initBlitRenderer(&br); renderer r; initRenderer(&r); glGenRenderbuffers(1, &gl_depth_buff_id); glBindRenderbuffer(GL_RENDERBUFFER, gl_depth_buff_id); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, br.texture_width, br.texture_height); glGenFramebuffers(1, &gl_framebuffer_id); glBindFramebuffer(GL_FRAMEBUFFER, gl_framebuffer_id); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, br.gl_texture_buff_id, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gl_depth_buff_id); Uint8 done = 0; SDL_Event event; while(!done) { while(SDL_PollEvent(&event)) { if( false || event.type == SDL_QUIT || event.type == SDL_KEYDOWN #if DO_PLATFORM == DO_PLATFORM_ANDROID || event.type == SDL_FINGERDOWN #endif ) { done = 1; } } updateRenderer(&r); //draw into FB glBindFramebuffer(GL_FRAMEBUFFER, gl_framebuffer_id); renderRenderer(&r,br.texture_width,br.texture_height); //blit FB glBindFramebuffer(GL_FRAMEBUFFER, 0); renderBlitRenderer(&br,win_w,win_h); SDL_GL_SwapWindow(window); SDL_Delay(10); } SDL_GL_DeleteContext(gl); IMG_Quit(); SDL_Quit(); exit(0); return 0; }
void Mercury::initRendering(void) { // OpenGL 4.3 is the minimum for compute shaders if (!requireMinAPIVersion(NvGLAPIVersionES3_1())) return; // Set Clear Color glClearColor(0.25f, 0.25f, 0.25f, 1.0f); CHECK_GL_ERROR(); NvAssetLoaderAddSearchPath("es3aep-kepler/Mercury"); const char* shaderPrefix = (getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL) ? "#version 430\n" : "#version 310 es\n"; CHECK_GL_ERROR(); { int32_t len; // Initialize Particles Render Program NvScopedShaderPrefix switched(shaderPrefix); std::string renderPartVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartVS.glsl"); std::string renderPartGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartGS.glsl"); mParticlesRenderProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesP[2]; sourcesP[0].type = GL_VERTEX_SHADER; sourcesP[0].src = renderPartVS.c_str(); sourcesP[1].type = GL_FRAGMENT_SHADER; sourcesP[1].src = NvAssetLoaderRead("shaders/renderPartFS.glsl", len); mParticlesRenderProg->setSourceFromStrings(sourcesP, 2); NvAssetLoaderFree((char*)sourcesP[1].src); // Initialize Surface Render Program std::string renderSurfVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfVS.glsl"); std::string renderSurfGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfGS.glsl"); std::string renderSurfFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfFS.glsl"); mSurfaceRenderProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesS[3]; sourcesS[0].type = GL_VERTEX_SHADER; sourcesS[0].src = renderSurfVS.c_str(); sourcesS[1].type = GL_GEOMETRY_SHADER_EXT; sourcesS[1].src = renderSurfGS.c_str(); sourcesS[2].type = GL_FRAGMENT_SHADER; sourcesS[2].src = renderSurfFS.c_str(); mSurfaceRenderProg->setSourceFromStrings(sourcesS, 3); std::string quadVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadVS.glsl"); std::string quadFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadFS.glsl"); mQuadProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesQ[2]; sourcesQ[0].type = GL_VERTEX_SHADER; sourcesQ[0].src = quadVS.c_str(); sourcesQ[1].type = GL_FRAGMENT_SHADER; sourcesQ[1].src = quadFS.c_str(); mQuadProg->setSourceFromStrings(sourcesQ, 2); std::string blurVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurVS.glsl"); std::string blurFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurFS.glsl"); mBlurProg = new NvGLSLProgram; NvGLSLProgram::ShaderSourceItem sourcesB[2]; sourcesB[0].type = GL_VERTEX_SHADER; sourcesB[0].src = blurVS.c_str(); sourcesB[1].type = GL_FRAGMENT_SHADER; sourcesB[1].src = blurFS.c_str(); mBlurProg->setSourceFromStrings(sourcesB, 2); } CHECK_GL_ERROR(); // Set up cubemap for skybox mSkyBoxTexID = NvImageGL::UploadTextureFromDDSFile("textures/sky_cube.dds"); glBindTexture(GL_TEXTURE_CUBE_MAP, mSkyBoxTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECK_GL_ERROR(); // Initialize skybox for screen quad mScreenQuadPos = new ShaderBuffer<nv::vec4f>(4); vec4f* pos = mScreenQuadPos->map(); pos[0] = vec4f(-1.0f, -1.0f, -1.0f, 1.0f); pos[1] = vec4f( 1.0f, -1.0f, -1.0f, 1.0f); pos[2] = vec4f(-1.0f, 1.0f, -1.0f, 1.0f); pos[3] = vec4f( 1.0f, 1.0f, -1.0f, 1.0f); mScreenQuadPos->unmap(); //create ubo and initialize it with the structure data glGenBuffers( 1, &mUBO); glBindBuffer( GL_UNIFORM_BUFFER, mUBO); glBufferData( GL_UNIFORM_BUFFER, sizeof(ShaderParams), &mShaderParams, GL_STREAM_DRAW); CHECK_GL_ERROR(); //create simple single-vertex VBO float vtx_data[] = { 0.0f, 0.0f, 0.0f, 1.0f}; glGenBuffers( 1, &mVBO); glBindBuffer( GL_ARRAY_BUFFER, mVBO); glBufferData( GL_ARRAY_BUFFER, sizeof(vtx_data), vtx_data, GL_STATIC_DRAW); CHECK_GL_ERROR(); // For now, scale back the particle count on mobile. //int32_t particleCount = isMobilePlatform() ? (mNumParticles >> 2) : mNumParticles; int32_t particleCount = mNumParticles; mParticles = new ParticleSystem(particleCount, shaderPrefix); CHECK_GL_ERROR(); int cx, cy, cz; glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &cx ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &cy ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &cz ); LOGI("Max compute work group count = %d, %d, %d\n", cx, cy, cz ); int sx, sy, sz; glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &sx ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &sy ); glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &sz ); LOGI("Max compute work group size = %d, %d, %d\n", sx, sy, sz ); CHECK_GL_ERROR(); //Set clockwise winding glFrontFace(GL_CW); // Texture const int screen_width = getAppContext()->width(); const int screen_height = getAppContext()->height(); // Frame buffer for final scene glGenTextures(gbuffer_size, gbuffer_tex); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (int i = 0; i < gbuffer_size; i++) { glActiveTexture(GL_TEXTURE0 + 3 + i); glBindTexture(GL_TEXTURE_2D, gbuffer_tex[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, screen_width, screen_height, 0, GL_RGBA, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, gbuffer_tex[i], 0); } // Depth buffer glGenRenderbuffers(1, &rbo_depth); glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth); GLuint attachments[gbuffer_size]; for (int i = 0; i < gbuffer_size; i++) { attachments[i] = GL_COLOR_ATTACHMENT0 + i; } glDrawBuffers(gbuffer_size, attachments); GLenum status; if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { LOGE("glCheckFramebufferStatus: error %p", status); exit(0); } glBindFramebuffer(GL_FRAMEBUFFER, 0); }
Bool OpenGLFramebuffer::Attach( const Renderbuffer & p_pRenderBuffer ) { // Cast the texture pointer to an opengl texture const OpenGLRenderbuffer * pOpenGLRenderbuffer = reinterpret_cast< const OpenGLRenderbuffer * >( &p_pRenderBuffer ); // Get the format Texture::ePixelFormat format = pOpenGLRenderbuffer->GetPixelFormat( ); // Get the right attachment type. GLenum attachment = g_OpenGLFrambufferAttachments[ format ]; // Incement the attachment depending on the type if( attachment == GL_COLOR_ATTACHMENT0 ) { // FIX THIS ERROR CHECK! if( m_ColorAttachmentCount > 15 ) { bitLogGraErr( "Attached too many color attachments." ); return false; } // Increment the attachment and the color attachment counter attachment += m_ColorAttachmentCount; m_ColorAttachmentCount++; } else if( attachment == GL_DEPTH_ATTACHMENT || attachment == GL_DEPTH_STENCIL_ATTACHMENT ) { if( m_DepthAttached ) { bitLogGraErr( "Attached too many depth/stencil attachments." ); return false; } // Increment the depth attachment counter m_DepthAttached = true; } // Generate the framebuffer object if necessary if( m_FramebufferObject == 0 ) { glGenFramebuffers( 1, &m_FramebufferObject ); } // Bind the framebuffer glBindFramebuffer( GL_FRAMEBUFFER, m_FramebufferObject ); // Attach the render buffer glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, pOpenGLRenderbuffer->GetId( ) ); // Check the framebuffer status! GLenum FramebufferStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER ); if( FramebufferStatus != GL_FRAMEBUFFER_COMPLETE ) { glBindFramebuffer( GL_FRAMEBUFFER, 0 ); bitLogGraErr( "Framebuffer error." ); return false; } // Unbind the framebuffer glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // Succeeded return true; }
bool CCRenderTexture::initWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat, GLuint uDepthStencilFormat) { CCAssert(eFormat != kCCTexture2DPixelFormat_A8, "only RGB and RGBA formats are valid for a render texture"); bool bRet = false; void *data = NULL; do { w = (int)(w * CC_CONTENT_SCALE_FACTOR()); h = (int)(h * CC_CONTENT_SCALE_FACTOR()); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_nOldFBO); // textures must be power of two squared unsigned int powW = 0; unsigned int powH = 0; if (CCConfiguration::sharedConfiguration()->supportsNPOT()) { powW = w; powH = h; } else { powW = ccNextPOT(w); powH = ccNextPOT(h); } data = malloc((int)(powW * powH * 4)); CC_BREAK_IF(! data); memset(data, 0, (int)(powW * powH * 4)); m_ePixelFormat = eFormat; m_pTexture = new CCTexture2D(); if (m_pTexture) { m_pTexture->initWithData(data, (CCTexture2DPixelFormat)m_ePixelFormat, powW, powH, CCSizeMake((float)w, (float)h)); } else { break; } GLint oldRBO; glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldRBO); if (CCConfiguration::sharedConfiguration()->checkForGLExtension("GL_QCOM")) { m_pTextureCopy = new CCTexture2D(); if (m_pTextureCopy) { m_pTextureCopy->initWithData(data, (CCTexture2DPixelFormat)m_ePixelFormat, powW, powH, CCSizeMake((float)w, (float)h)); } else { break; } } // generate FBO glGenFramebuffers(1, &m_uFBO); glBindFramebuffer(GL_FRAMEBUFFER, m_uFBO); // associate texture with FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pTexture->getName(), 0); if (uDepthStencilFormat != 0) { //create and attach depth buffer glGenRenderbuffers(1, &m_uDepthRenderBufffer); glBindRenderbuffer(GL_RENDERBUFFER, m_uDepthRenderBufffer); glRenderbufferStorage(GL_RENDERBUFFER, uDepthStencilFormat, (GLsizei)powW, (GLsizei)powH); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_uDepthRenderBufffer); // if depth format is the one with stencil part, bind same render buffer as stencil attachment if (uDepthStencilFormat == GL_DEPTH24_STENCIL8) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_uDepthRenderBufffer); } } // check if it worked (probably worth doing :) ) CCAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Could not attach texture to framebuffer"); m_pTexture->setAliasTexParameters(); // retained setSprite(CCSprite::createWithTexture(m_pTexture)); m_pTexture->release(); m_pSprite->setScaleY(-1); ccBlendFunc tBlendFunc = {GL_ONE, GL_ONE_MINUS_SRC_ALPHA }; m_pSprite->setBlendFunc(tBlendFunc); glBindRenderbuffer(GL_RENDERBUFFER, oldRBO); glBindFramebuffer(GL_FRAMEBUFFER, m_nOldFBO); // Diabled by default. m_bAutoDraw = false; // add sprite for backward compatibility addChild(m_pSprite); bRet = true; } while (0); CC_SAFE_FREE(data); return bRet; }
static enum piglit_result run_multisample_test(struct texture_format *src_format, struct texture_format *dst_format) { bool pass = true; int fbo_width, fbo_height; GLuint fbo, rb, src_tex, dst_tex, res_tex; static const GLfloat verts[] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 }; /* Upload the source, destination, and expected result */ src_tex = piglit_multisample_texture(GL_TEXTURE_2D_MULTISAMPLE, 0, src_format->internal_format, TEX_SIZE, TEX_SIZE, 1, samples, src_format->format, src_format->data_type, src_data); dst_tex = piglit_multisample_texture(GL_TEXTURE_2D_MULTISAMPLE, 0, dst_format->internal_format, TEX_SIZE, TEX_SIZE, 1, samples, dst_format->format, dst_format->data_type, dst_data); res_tex = piglit_multisample_texture(GL_TEXTURE_2D_MULTISAMPLE, 0, dst_format->internal_format, TEX_SIZE, TEX_SIZE, 1, samples, dst_format->format, dst_format->data_type, res_data); pass &= piglit_check_gl_error(GL_NO_ERROR); /* If any of these are zero, but there was no error, then it must * not be renderable, so we just skip without even reporting the * subtest. */ if ((src_tex == 0 || dst_tex == 0 || res_tex == 0) && pass) return PIGLIT_SKIP; glCopyImageSubData(src_tex, GL_TEXTURE_2D_MULTISAMPLE, 0, TEX_SIZE / 4, TEX_SIZE / 4, 0, dst_tex, GL_TEXTURE_2D_MULTISAMPLE, 0, TEX_SIZE / 4, TEX_SIZE / 4, 0, TEX_SIZE / 2, TEX_SIZE / 2, 1); pass &= piglit_check_gl_error(GL_NO_ERROR); glCopyImageSubData(dst_tex, GL_TEXTURE_2D_MULTISAMPLE, 0, 0, TEX_SIZE / 2, 0, dst_tex, GL_TEXTURE_2D_MULTISAMPLE, 0, TEX_SIZE / 2, 0, 0, TEX_SIZE / 2, TEX_SIZE / 2, 1); pass &= piglit_check_gl_error(GL_NO_ERROR); if (piglit_automatic) { fbo_width = TEX_SIZE; fbo_height = TEX_SIZE; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, fbo_width, fbo_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); } else { fbo_width = piglit_width; fbo_height = piglit_height; glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo); } pass &= piglit_check_gl_error(GL_NO_ERROR); glViewport(0, 0, fbo_width, fbo_height); glClearColor(1.0f, 0.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); /* Now we use a comparison shader to check to see if the * destination matches the expected result. */ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, dst_tex); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, res_tex); load_compare_program(dst_format); pass &= piglit_check_gl_error(GL_NO_ERROR); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, verts); glDrawArrays(GL_TRIANGLES, 0, 6); glDisableVertexAttribArray(0); pass &= piglit_check_gl_error(GL_NO_ERROR); /* If the destination texture matches the expected result, we * should get green. If not, we get red and this test fails. */ pass &= piglit_probe_rect_rgb(0, 0, fbo_width, fbo_height, green); glDeleteTextures(1, &src_tex); glDeleteTextures(1, &dst_tex); glDeleteTextures(1, &res_tex); if (!piglit_automatic) piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void GLES2FrameBufferObject::initialise() { GLES2RenderSystem* rs = getGLES2RenderSystem(); assert(mContext == rs->_getCurrentContext()); // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); mManager->releaseRenderBuffer(mMultisampleColourBuffer); // First buffer must be bound if(!mColour[0].buffer) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attachment 0 must have surface attached", "GLES2FrameBufferObject::initialise"); } // If we're doing multisampling, then we need another FBO which contains a // renderbuffer which is set up to multisample, and we'll blit it to the final // FBO afterwards to perform the multisample resolve. In that case, the // mMultisampleFB is bound during rendering and is the one with a depth/stencil // Store basic stats uint32 width = mColour[0].buffer->getWidth(); uint32 height = mColour[0].buffer->getHeight(); GLuint format = mColour[0].buffer->getGLFormat(); ushort maxSupportedMRTs = rs->getCapabilities()->getNumMultiRenderTargets(); // Bind simple buffer to add colour attachments OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFB)); bool isDepth = PixelUtil::isDepth(getFormat()); // Bind all attachment points to frame buffer for(unsigned int x = 0; x < maxSupportedMRTs; ++x) { if(mColour[x].buffer) { if(mColour[x].buffer->getWidth() != width || mColour[x].buffer->getHeight() != height) { StringStream ss; ss << "Attachment " << x << " has incompatible size "; ss << mColour[x].buffer->getWidth() << "x" << mColour[x].buffer->getHeight(); ss << ". It must be of the same as the size of surface 0, "; ss << width << "x" << height; ss << "."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLES2FrameBufferObject::initialise"); } if(mColour[x].buffer->getGLFormat() != format) { StringStream ss; ss << "Attachment " << x << " has incompatible format."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLES2FrameBufferObject::initialise"); } mColour[x].buffer->bindToFramebuffer( isDepth ? GL_DEPTH_ATTACHMENT : (GL_COLOR_ATTACHMENT0 + x), mColour[x].zoffset); } else { // Detach OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, static_cast<GLenum>(GL_COLOR_ATTACHMENT0+x), GL_RENDERBUFFER, 0)); } } // Now deal with depth / stencil if (mMultisampleFB) { // Bind multisample buffer OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB)); // Create AA render buffer (colour) // note, this can be shared too because we blit it to the final FBO // right after the render is finished mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); // Attach it, because we won't be attaching below and non-multisample has // actually been attached to other FBO mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, mMultisampleColourBuffer.zoffset); // depth & stencil will be dealt with below } // Depth buffer is not handled here anymore. // See GLES2FrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() if(rs->hasMinGLVersion(3, 0) && OGRE_PLATFORM != OGRE_PLATFORM_EMSCRIPTEN) // ED on Emscripten { GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; GLsizei n=0; for(unsigned int x=0; x<maxSupportedMRTs; ++x) { // Fill attached colour buffers if(mColour[x].buffer) { bufs[x] = isDepth ? GL_DEPTH_ATTACHMENT : (GL_COLOR_ATTACHMENT0 + x); // Keep highest used buffer + 1 n = x+1; } else { bufs[x] = GL_NONE; } } // Drawbuffer extension supported, use it if(!isDepth) OGRE_CHECK_GL_ERROR(glDrawBuffers(n, bufs)); if (mMultisampleFB) { // we need a read buffer because we'll be blitting to mFB OGRE_CHECK_GL_ERROR(glReadBuffer(bufs[0])); } else { // No read buffer, by default, if we want to read anyway we must not forget to set this. OGRE_CHECK_GL_ERROR(glReadBuffer(GL_NONE)); } } // Check status GLuint status; OGRE_CHECK_GL_ERROR(status = glCheckFramebufferStatus(GL_FRAMEBUFFER)); // Bind main buffer #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // The screen buffer is 1 on iOS OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 1)); #else OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0)); #endif switch(status) { case GL_FRAMEBUFFER_COMPLETE: // All is good break; case GL_FRAMEBUFFER_UNSUPPORTED: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "All framebuffer formats with this texture internal format unsupported", "GLES2FrameBufferObject::initialise"); default: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Framebuffer incomplete or other FBO status error", "GLES2FrameBufferObject::initialise"); } }
void GL::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { GL_CHECK(glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer)); }
void fboInit( tFBOInfo* pFBOInfo, int iWidth, int iHeight, int iTextureFilter ) { // bind fbo to texture glGenFramebuffers( 1, &pFBOInfo->mFBO ); glBindFramebuffer( GL_FRAMEBUFFER, pFBOInfo->mFBO ); // color buffer for fbo glGenRenderbuffers( 1, &pFBOInfo->mColorRenderBuffer ); glBindRenderbuffer( GL_RENDERBUFFER, pFBOInfo->mColorRenderBuffer ); #if defined( WIN32 ) || defined( MACOS ) glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB8, iWidth, iHeight ); #else glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB8_OES, iWidth, iHeight ); #endif // WIN32 glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, pFBOInfo->mColorRenderBuffer ); // depth buffer for the fbo glGenRenderbuffers( 1, &pFBOInfo->mDepthRenderBuffer ); glBindRenderbuffer( GL_RENDERBUFFER, pFBOInfo->mDepthRenderBuffer ); #if defined( WIN32 ) || defined( MACOS ) glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, iWidth, iHeight ); #else glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, iWidth, iHeight ); #endif // WIN32 glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pFBOInfo->mDepthRenderBuffer ); // texture glGenTextures( 1, &pFBOInfo->mTexture ); glBindTexture( GL_TEXTURE_2D, pFBOInfo->mTexture ); GLuint iGLFilterType = GL_NEAREST; if( iTextureFilter == FILTER_BILINEAR ) { iGLFilterType = GL_LINEAR; } else if( iTextureFilter == FILTER_NEAREST ) { iGLFilterType = GL_NEAREST; } // attribute 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_MAG_FILTER, iGLFilterType ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iGLFilterType ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pFBOInfo->mTexture, 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); }
bool Init(int w, int h) { // Create a framebuffer object glGenFramebuffers(1, fboId); glBindFramebuffer(GL_FRAMEBUFFER, *fboId); // Create a render buffer glGenRenderbuffers(1, renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, *renderBuffer); // Create a texture for storing the depth glGenTextures(1, depthTextureId); glBindTexture(GL_TEXTURE_2D, *depthTextureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Remove artifact on the edges of the shadowmap glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); Debug("glGetError() 0 = 0x%x", glGetError()); if ( m_hasDepthTextureExtension ) { // We'll use a depth texture to store the depths in the shadow map glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); // Attach the depth texture to FBO depth attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depthTextureId, 0); } else { // We'll use a RGBA texture into which we pack the depth info glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Attach the RGBA texture to FBO color attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *depthTextureId, 0); // Allocate 16-bit depth buffer glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); // Attach the render buffer as depth buffer - will be ignored glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *renderBuffer); } // check FBO status GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); if ( fboStatus != GL_FRAMEBUFFER_COMPLETE ) { Debug("FBO not complete: 0x%x", fboStatus); return false; } // Go back to using the default frame buffer glBindFramebuffer(GL_FRAMEBUFFER, DefaultFramebufferId); return true; }
bool Context::try_create_fbo( GLsizei width , GLsizei height , int flags ) { tplog2( "CREATING FRAMEBUFFER" ); GLuint fbo; GLuintSet rb; bool h_depth = false; bool h_stencil = false; glGenFramebuffers( 1 , & fbo ); glBindFramebuffer( GL_FRAMEBUFFER , fbo ); glFramebufferTexture2D( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , texture_target , texture , 0 ); if ( flags & FBO_TRY_DEPTH_STENCIL ) { tplog2( " CREATING DEPTH/STENCIL RENDERBUFFERS" ); GLuint depth_stencil_rb; glGenRenderbuffers( 1 , & depth_stencil_rb ); glBindRenderbuffer( GL_RENDERBUFFER , depth_stencil_rb ); glRenderbufferStorage( GL_RENDERBUFFER , GL_DEPTH_STENCIL , width , height ); glBindRenderbuffer( GL_RENDERBUFFER , 0 ); glFramebufferRenderbuffer( GL_FRAMEBUFFER , GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER, depth_stencil_rb ); glFramebufferRenderbuffer( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER , depth_stencil_rb ); rb.insert( depth_stencil_rb ); h_depth = true; h_stencil = true; } if ( flags & FBO_TRY_DEPTH ) { tplog2( " CREATING DEPTH RENDERBUFFER" ); GLuint depth_rb; glGenRenderbuffers( 1 , & depth_rb ); glBindRenderbuffer( GL_RENDERBUFFER , depth_rb ); glRenderbufferStorage( GL_RENDERBUFFER , GL_DEPTH_COMPONENT16 , width , height ); glBindRenderbuffer( GL_RENDERBUFFER , 0 ); glFramebufferRenderbuffer( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER , depth_rb ); rb.insert( depth_rb ); h_depth = true; } if ( flags & FBO_TRY_STENCIL ) { tplog2( " CREATING STENCIL RENDERBUFFER" ); GLuint stencil_rb; glGenRenderbuffers( 1 , & stencil_rb ); glBindRenderbuffer( GL_RENDERBUFFER , stencil_rb ); glRenderbufferStorage( GL_RENDERBUFFER , GL_STENCIL_INDEX8 , width , height ); glBindRenderbuffer( GL_RENDERBUFFER , 0 ); glFramebufferRenderbuffer( GL_FRAMEBUFFER , GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER , stencil_rb ); rb.insert( stencil_rb ); h_stencil = true; } if ( GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus( GL_FRAMEBUFFER ) ) { glBindFramebuffer( GL_FRAMEBUFFER , 0 ); tplog2( " DESTROYING FRAMEBUFFER %u" , fbo ); glDeleteFramebuffers( 1 , & fbo ); for ( GLuintSet::const_iterator it = rb.begin(); it != rb.end(); ++it ) { tplog2( " DESTROYING RENDERBUFFER %u" , *it ); glDeleteRenderbuffers( 1 , & * it ); } tplog2( "* FRAMEBUFFER IS NOT COMPLETE" ); return false; } tplog2( "* FRAMEBUFFER IS COMPLETE" ); framebuffer = fbo; renderbuffers.insert( rb.begin() , rb.end() ); have_depth = h_depth; have_stencil = h_stencil; return true; }
void renderer_cool::draw(int vertex_count) { static bool initial_resize = false; if (!initial_resize) { if (enabler->fullscreen) resize(size_x, size_y); else resize((size_x/init->font.small_font_dispx)*init->font.small_font_dispx, (size_y/init->font.small_font_dispy)*init->font.small_font_dispy); //resize(gps->dimx*init->font.small_font_dispx, gps->dimy*init->font.small_font_dispy); reshape_gl(); initial_resize = true; } static df::viewscreen *prevws = NULL; df::viewscreen *ws = Gui::getCurViewscreen(); is_main_scr = df::viewscreen_dwarfmodest::_identity.is_direct_instance(ws) || df::viewscreen_dungeonmodest::_identity.is_direct_instance(ws); if (ws != prevws) { gps->force_full_display_count = 1; prevws = ws; /*if (is_main_scr) { for (int x = 1; x < gps->dimx-gmenu_w-1; x++) { for (int y = 1; y < gps->dimy-1; y++) { const int tile1 = x * gps->dimy + y; for (int i = 0; i < 6; i++) *(fg + tile * 4 * i + 3) = 0; } } }*/ } display_new(is_main_scr); #ifdef WIN32 // We can't do this in plugin_init() because OpenGL context isn't initialized by that time static bool glew_init = false; if (!glew_init) { GLenum err = glewInit(); if (err != GLEW_OK) *out2 << glewGetErrorString(err); glew_init = true; } #endif static int old_dimx, old_dimy, old_winx, old_winy; if (domapshot) { if (domapshot == 10) { old_dimx = gps->dimx; old_dimy = gps->dimy; old_winx = *df::global::window_x; old_winy = *df::global::window_y; grid_resize(world->map.x_count + 36, world->map.y_count + 2); *df::global::window_x = 0; *df::global::window_y = 0; gps->force_full_display_count = 1; } domapshot--; } GLuint framebuffer, renderbuffer; GLenum status; if (domapshot == 5) { // Set the width and height appropriately for your image GLuint imageWidth = gps->dimx * dispx, imageHeight = gps->dimy * dispy; //Set up a FBO with one renderbuffer attachment glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glGenRenderbuffers(1, &renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, imageWidth, imageHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); glViewport(0, 0, gps->dimx * dispx, gps->dimy * dispy); /*glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,gps->dimx,gps->dimy,0,-1,1);*/ } if (is_main_scr) { bool skip = false; if (df::viewscreen_dungeonmodest::_identity.is_direct_instance(ws)) { int m = df::global::ui_advmode->menu; bool tmode = advmode_needs_map(m); skip = !tmode; } if (!skip) { ///// glViewport(goff_x, goff_y_gl, gdimx * gdispx, gdimy * gdispy); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, gdimx, gdimy, 0, -1, 1); //glTranslatef(1,-1,0); //glScissor(off_x+(float)size_x/gps->dimx, off_y+(float)size_y/gps->dimy, gsize_x, gsize_y); //glEnable(GL_SCISSOR_TEST); //glClearColor(1,0,0,1); //glClear(GL_COLOR_BUFFER_BIT); if (multi_rendered && fogdensity > 0) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, fogcolor); glFogf(GL_FOG_DENSITY, fogdensity); glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD); glEnableClientState(GL_FOG_COORD_ARRAY); glFogCoordPointer(GL_FLOAT, 0, fogcoord); } glVertexPointer(2, GL_FLOAT, 0, gvertexes); // Render background colors glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); glColorPointer(4, GL_FLOAT, 0, gbg); glDrawArrays(GL_TRIANGLES, 0, gdimx * gdimy * 6); // Render foreground glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointer(2, GL_FLOAT, 0, gtex); glColorPointer(4, GL_FLOAT, 0, gfg); glDrawArrays(GL_TRIANGLES, 0, gdimx * gdimy * 6); if (multi_rendered) { glDisableClientState(GL_FOG_COORD_ARRAY); glDisable(GL_FOG); } // Prepare and render shadows if (multi_rendered) { int elemcnt = 0; //TODO: don't do this if view not moved and tiles with shadows not changed { gl_texpos *txt = (gl_texpos *) enabler->textures.gl_texpos; int x1 = std::min(gdimx, world->map.x_count-gwindow_x); int y1 = std::min(gdimy, world->map.y_count-gwindow_y); for (int tile = 0; tile < gdimx * gdimy; tile++) { int xx = tile / gdimy; int yy = tile % gdimy; int d = depth[tile]; if (d && d != 0x7f) //TODO: no need for the second check in fort mode { GLfloat *tex = shadowtex + elemcnt * 2; bool top = false, left = false, btm = false, right = false; if (xx > 0 && (depth[((xx - 1)*gdimy + yy)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[0]); elemcnt += 6; left = true; } if (yy < y1 - 1 && (depth[((xx)*gdimy + yy + 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[1]); elemcnt += 6; btm = true; } if (yy > 0 && (depth[((xx)*gdimy + yy - 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[2]); elemcnt += 6; top = true; } if (xx < x1-1 && (depth[((xx + 1)*gdimy + yy)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[3]); elemcnt += 6; right = true; } if (!right && !btm && xx < x1 - 1 && yy < y1 - 1 && (depth[((xx + 1)*gdimy + yy + 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[4]); elemcnt += 6; } if (!left && !btm && xx > 0 && yy < y1 - 1 && (depth[((xx - 1)*gdimy + yy + 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[5]); elemcnt += 6; } if (!left && !top && xx > 0 && yy > 0 && (depth[((xx - 1)*gdimy + yy - 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[6]); elemcnt += 6; } if (!top && !right && xx < x1 - 1 && yy > 0 && (depth[((xx + 1)*gdimy + yy - 1)]) < d) { memcpy(shadowvert + elemcnt * 2, gvertexes + tile * 6 * 2, 6 * 2 * sizeof(float)); SETTEX(shadow_texpos[7]); elemcnt += 6; } } } } if (elemcnt) { glDisableClientState(GL_COLOR_ARRAY); glColor4fv(shadowcolor); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointer(2, GL_FLOAT, 0, shadowtex); glVertexPointer(2, GL_FLOAT, 0, shadowvert); glDrawArrays(GL_TRIANGLES, 0, elemcnt); glEnableClientState(GL_COLOR_ARRAY); } } glDisable(GL_SCISSOR_TEST); glViewport(off_x, off_y, size_x, size_y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, tdimx, tdimy, 0, -1, 1); } } { glVertexPointer(2, GL_FLOAT, 0, vertexes); // Render background colors glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glColorPointer(4, GL_FLOAT, 0, bg); glDrawArrays(GL_TRIANGLES, 0, tdimx*tdimy*6); // Render foreground glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointer(2, GL_FLOAT, 0, tex); glColorPointer(4, GL_FLOAT, 0, fg); glDrawArrays(GL_TRIANGLES, 0, tdimx*tdimy*6); } if (domapshot == 1) { int w = world->map.x_count * dispx; int h = world->map.y_count * dispy; unsigned char *data = (unsigned char *) malloc(w * h * 3); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glReadPixels(dispx, dispy, w, h, GL_BGR, GL_UNSIGNED_BYTE, data); #pragma pack(push,1) typedef struct _TgaHeader { unsigned char IDLength; /* 00h Size of Image ID field */ unsigned char ColorMapType; /* 01h Color map type */ unsigned char ImageType; /* 02h Image type code */ unsigned short CMapStart; /* 03h Color map origin */ unsigned short CMapLength; /* 05h Color map length */ unsigned char CMapDepth; /* 07h Depth of color map entries */ unsigned short XOffset; /* 08h X origin of image */ unsigned short YOffset; /* 0Ah Y origin of image */ unsigned short Width; /* 0Ch Width of image */ unsigned short Height; /* 0Eh Height of image */ unsigned char PixelDepth; /* 10h Image pixel size */ unsigned char ImageDescriptor; /* 11h Image descriptor byte */ } TGAHEAD; #pragma pop TGAHEAD hdr; memset(&hdr, 0, sizeof(hdr)); hdr.ImageType = 2; hdr.Width = w; hdr.Height = h; hdr.PixelDepth = 24; *out2 << w << " " << h << std::endl; std::ofstream img("mapshot.tga", std::ofstream::binary); img.write((const char *)&hdr, sizeof(hdr)); /* for (int j = 0; j<w*h*3; j++) { unsigned char c = data[j+0]; data[0] = data[j+2]; data[j+2] = c; }*/ img.write((const char *)data, w * h * 3); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Delete the renderbuffer attachment glDeleteRenderbuffers(1, &renderbuffer); grid_resize(old_dimx, old_dimy); *df::global::window_x = old_winx; *df::global::window_y = old_winy; gps->force_full_display_count = 1; domapshot = 0; } }
void piglit_init(int argc, char **argv) { GLuint vs, fs_paint_red, fs_sample; GLenum fb_status; /* Parse params */ if (argc != 3) print_usage_and_exit(argv[0]); if (strcmp(argv[1], "sample") == 0) subtest = SUBTEST_SAMPLE; else if (strcmp(argv[1], "read_pixels") == 0) subtest = SUBTEST_READ_PIXELS; else if (strcmp(argv[1], "blit") == 0) subtest = SUBTEST_BLIT; else if (strcmp(argv[1], "copy") == 0) subtest = SUBTEST_COPY; else print_usage_and_exit(argv[0]); if (strcmp(argv[2], "rb") == 0) use_texture = false; else if (strcmp(argv[2], "tex") == 0) use_texture = true; else print_usage_and_exit(argv[0]); /* Detect parameter conflicts */ if (subtest == SUBTEST_SAMPLE && !use_texture) { printf("Subtest 'sample' requires buffer_type 'tex'.\n"); piglit_report_result(PIGLIT_FAIL); } /* Requirements */ piglit_require_gl_version(11); piglit_require_GLSL_version(110); piglit_require_extension("GL_ARB_framebuffer_object"); /* Compile shaders */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text); fs_paint_red = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text_paint_red); prog_paint_red = piglit_link_simple_program(vs, fs_paint_red); if (!prog_paint_red) piglit_report_result(PIGLIT_FAIL); fs_sample = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text_sample); prog_sample = piglit_link_simple_program(vs, fs_sample); if (!prog_sample) piglit_report_result(PIGLIT_FAIL); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); /* Set up framebuffer */ glGenFramebuffers(1, &fb); glBindFramebuffer(GL_FRAMEBUFFER, fb); if (use_texture) { tex1 = allocate_texture(); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0 /* level */); } else { GLuint rb; glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, TEX_WIDTH, TEX_HEIGHT); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); } if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (fb_status != GL_FRAMEBUFFER_COMPLETE) { printf("Framebuffer status: %s\n", piglit_get_gl_enum_name(fb_status)); piglit_report_result(PIGLIT_FAIL); } /* Set up second texture (used by "copy" test only) */ if (subtest == SUBTEST_COPY) tex2 = allocate_texture(); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); }
void Framebuffer::attachDepthBuffer(const Renderbuffer& rb) { bind(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb.getHandle()); _depth = true; }
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_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 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"); Shader lampShader("glsl/lampvertex.glsl", "glsl/lampfragment.glsl"); Shader postShader("glsl/post_vert.glsl", "glsl/post_frag.glsl"); Shader gsShader("glsl/gs_vert.glsl", "glsl/gs_frag.glsl", "glsl/gs_geo.glsl"); GLuint containerTexture = loadTexture("assets/container2.png"); GLuint containerSpecular = loadTexture("assets/container2_specular.png"); GLuint containerEmission = loadTexture("assets/matrix.jpg"); // 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 frameColorBuffer; glGenTextures(1, &frameColorBuffer); glBindTexture(GL_TEXTURE_2D, frameColorBuffer); 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); // Attach the texture to the framebuffer. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameColorBuffer, 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); glRenderbufferStorage(GL_RENDERBUFFER, 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; } // Unbind the framebuffer since we want the main scene to be drawn // to be drawn to the main window. glBindFramebuffer(GL_FRAMEBUFFER, 0); // 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 }; // Positions all containers glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3( 2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3( 1.3f, -2.0f, -2.5f), glm::vec3( 1.5f, 2.0f, -2.5f), glm::vec3( 1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; // 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; // Light information. const glm::vec3 directionalLightDir(0.0f, 1.0f, 0.0f); const glm::vec3 pointLightPositions[] = { glm::vec3( 0.7f, 0.2f, 2.0f), glm::vec3( 2.3f, -3.3f, -4.0f), glm::vec3(-4.0f, 2.0f, -12.0f), glm::vec3( 0.0f, 0.0f, -3.0f) }; // Render loop. while (!glfwWindowShouldClose(window)) { GLfloat currentFrame = glfwGetTime(); delta = currentFrame - lastFrame; lastFrame = currentFrame; // Check and call events. glfwPollEvents(); move(delta); // Bind the off screen framebuffer (for post-processing) and clear the // screen to a nice blue color. 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); const GLfloat limitTime = 1.0f; fovTime += delta; if (fovTime > limitTime) { fovTime = limitTime; } // Update the perspective to account for changes in fov. camera.fov = easeOutQuart(fovTime, startFov, (startFov - targetFov) * -1, limitTime); camera.update(); // Bind the VAO and shader. glBindVertexArray(VAO); shader.use(); // Pass the view and projection matrices from the camera. GLuint viewMatrix = glGetUniformLocation(shader.program, "view"); glUniformMatrix4fv(viewMatrix, 1, GL_FALSE, glm::value_ptr(camera.view)); GLuint projectionMatrix = glGetUniformLocation(shader.program, "projection"); glUniformMatrix4fv(projectionMatrix, 1, GL_FALSE, glm::value_ptr(camera.projection)); // Generate light colors. glm::vec3 lightColor(1.0f, 1.0f, 1.0f); // Directional light glUniform3f(glGetUniformLocation(shader.program, "dirLight.direction"), -0.2f, -1.0f, -0.3f); glUniform3f(glGetUniformLocation(shader.program, "dirLight.ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.program, "dirLight.diffuse"), 0.4f, 0.4f, 0.4f); glUniform3f(glGetUniformLocation(shader.program, "dirLight.specular"), 0.5f, 0.5f, 0.5f); // Point light 1 glUniform3f(glGetUniformLocation(shader.program, "pointLights[0].position"), pointLightPositions[0].x, pointLightPositions[0].y, pointLightPositions[0].z); glUniform3f(glGetUniformLocation(shader.program, "pointLights[0].ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[0].diffuse"), 1.0f, 0.0f, 0.0f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[0].specular"), 1.0f, 1.0f, 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[0].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[0].linear"), 0.09); glUniform1f(glGetUniformLocation(shader.program, "pointLights[0].quadratic"), 0.032); // Point light 2 glUniform3f(glGetUniformLocation(shader.program, "pointLights[1].position"), pointLightPositions[1].x, pointLightPositions[1].y, pointLightPositions[1].z); glUniform3f(glGetUniformLocation(shader.program, "pointLights[1].ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[1].diffuse"), 0.0f, 1.0f, 0.0f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[1].specular"), 1.0f, 1.0f, 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[1].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[1].linear"), 0.09); glUniform1f(glGetUniformLocation(shader.program, "pointLights[1].quadratic"), 0.032); // Point light 3 glUniform3f(glGetUniformLocation(shader.program, "pointLights[2].position"), pointLightPositions[2].x, pointLightPositions[2].y, pointLightPositions[2].z); glUniform3f(glGetUniformLocation(shader.program, "pointLights[2].ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[2].diffuse"), 0.0f, 0.0f, 1.0f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[2].specular"), 1.0f, 1.0f, 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[2].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[2].linear"), 0.09); glUniform1f(glGetUniformLocation(shader.program, "pointLights[2].quadratic"), 0.032); // Point light 4 glUniform3f(glGetUniformLocation(shader.program, "pointLights[3].position"), pointLightPositions[3].x, pointLightPositions[3].y, pointLightPositions[3].z); glUniform3f(glGetUniformLocation(shader.program, "pointLights[3].ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[3].diffuse"), 0.8f, 0.8f, 0.8f); glUniform3f(glGetUniformLocation(shader.program, "pointLights[3].specular"), 1.0f, 1.0f, 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[3].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.program, "pointLights[3].linear"), 0.09); glUniform1f(glGetUniformLocation(shader.program, "pointLights[3].quadratic"), 0.032); // Sport light 1 glUniform3f(glGetUniformLocation(shader.program, "spotLights[0].position"), camera.position.x, camera.position.y, camera.position.z); glUniform3f(glGetUniformLocation(shader.program, "spotLights[0].direction"), camera.front.x, camera.front.y, camera.front.z); glUniform3f(glGetUniformLocation(shader.program, "spotLights[0].ambient"), 0.0f, 0.0f, 0.0f); glUniform3f(glGetUniformLocation(shader.program, "spotLights[0].diffuse"), 1.0f, 1.0f, 1.0f); glUniform3f(glGetUniformLocation(shader.program, "spotLights[0].specular"), 1.0f, 1.0f, 1.0f); glUniform1f(glGetUniformLocation(shader.program, "spotLights[0].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.program, "spotLights[0].linear"), 0.09); glUniform1f(glGetUniformLocation(shader.program, "spotLights[0].quadratic"), 0.032); glUniform1f(glGetUniformLocation(shader.program, "spotLights[0].cutoff"), glm::cos(glm::radians(12.5f))); glUniform1f(glGetUniformLocation(shader.program, "spotLights[0].outerCutoff"), glm::cos(glm::radians(15.5f))); // Pass material values. GLuint materialShininess = glGetUniformLocation(shader.program, "material.shininess"); GLuint materialDiffuse = glGetUniformLocation(shader.program, "material.diffuse"); GLuint materialSpecular = glGetUniformLocation(shader.program, "material.specular"); GLuint materialEmission = glGetUniformLocation(shader.program, "material.emission"); glUniform1f(materialShininess, 64.0f); glUniform1i(materialDiffuse, 0); glUniform1i(materialSpecular, 1); glUniform1i(materialEmission, 2); // Misc values. GLuint viewPos = glGetUniformLocation(shader.program, "viewPos"); glUniform3f(viewPos, camera.position.x, camera.position.y, camera.position.z); GLuint time = glGetUniformLocation(shader.program, "time"); glUniform1f(time, glfwGetTime()); // Bind the textures. glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, containerTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, containerSpecular); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, containerEmission); // Draw multiple containers! GLuint modelMatrix = glGetUniformLocation(shader.program, "model"); GLuint normalMatrix = glGetUniformLocation(shader.program, "normalMatrix"); for (GLuint i = 0; i < 10; i++) { // Apply world transformations. model = glm::mat4(); model = glm::translate(model, cubePositions[i]); model = glm::rotate(model, i * 20.0f, glm::vec3(1.0f, 0.3f, 0.5f)); glUniformMatrix4fv(modelMatrix, 1, GL_FALSE, glm::value_ptr(model)); // Calculate the normal matrix on the CPU (keep them normals perpendicular). normal = glm::mat3(glm::transpose(glm::inverse(model))); glUniformMatrix3fv(normalMatrix, 1, GL_FALSE, glm::value_ptr(normal)); // Draw the container. glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); // Bind the VAO and shader. glBindVertexArray(lightVAO); lampShader.use(); // Pass the view and projection matrices from the camera. viewMatrix = glGetUniformLocation(lampShader.program, "view"); glUniformMatrix4fv(viewMatrix, 1, GL_FALSE, glm::value_ptr(camera.view)); projectionMatrix = glGetUniformLocation(lampShader.program, "projection"); glUniformMatrix4fv(projectionMatrix, 1, GL_FALSE, glm::value_ptr(camera.projection)); for (GLuint i = 0; i < 4; i++) { // Apply world transformations. model = glm::mat4(); model = glm::translate(model, pointLightPositions[i]); model = glm::scale(model, glm::vec3(0.2f)); modelMatrix = glGetUniformLocation(lampShader.program, "model"); glUniformMatrix4fv(modelMatrix, 1, GL_FALSE, glm::value_ptr(model)); // Draw the lamp. glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); // Draw something with the geometry shader program. //glDisable(GL_DEPTH_TEST); //gsShader.use(); //glBindVertexArray(pointsVAO); //glDrawArrays(GL_POINTS, 0, 4); //glBindVertexArray(0); //glEnable(GL_DEPTH_TEST); // 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"); time = glGetUniformLocation(postShader.program, "time"); glUniform1i(frameTexture, 0); glUniform1f(time, glfwGetTime()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, frameColorBuffer); // 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; }
void Texture::CameraToTex(Camera* cam, int frame){ GLenum target; Global::camera_in_use=cam; if(flags&128){ target=GL_TEXTURE_CUBE_MAP; }else{ target=GL_TEXTURE_2D; } glBindTexture (target, texture); if (framebuffer==0){ framebuffer=new unsigned int[1]; glGenFramebuffers(1, &framebuffer[0]); glGenRenderbuffers(1, &framebuffer[1]); if(flags&128){ for (int i=0;i<6;i++){ switch(i){ case 0: glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case 1: glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case 2: glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case 3: glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case 4: glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case 5: glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; } } }else{ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } } glBindFramebuffer(GL_FRAMEBUFFER, framebuffer[0]); if(flags&128){ switch (cube_face){ case 0: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, texture, 0); break; case 1: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, texture, 0); break; case 2: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texture, 0); break; case 3: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, texture, 0); break; case 4: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, texture, 0); break; case 5: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, texture, 0); break; } }else{ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); } //Depth buffer glBindRenderbuffer(GL_RENDERBUFFER, framebuffer[1]); glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, framebuffer[1]); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, framebuffer[1]); cam->Render(); if (Global::Shadows_enabled==true) ShadowObject::Update(cam); //glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); glBindTexture (target, texture);// glGenerateMipmap(target); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0); }
FrameBufferObject::FrameBufferObject(int width, int height, int depthBufferBitDepth, int stencilBufferBitDepth, GLenum textureFormat, GLenum textureType, std::string name) : width(width), height(height), textureFormat(textureFormat), textureType(textureType), texNum(0), nextIndex(0), Height(height), Width(width), Bound(bound) { if (!glGenFramebuffers) throw; bound = false; setDrawBuffers = false; if (name == "") { char buf[64]; sprintf(buf, "unnamed%d", ++nextIndex); this->name = buf; } else { this->name = name; } glGenFramebuffers(1, &glID); glBindFramebuffer(GL_FRAMEBUFFER, glID); if (depthBufferBitDepth || stencilBufferBitDepth) { GLenum format = 0; if (depthBufferBitDepth && stencilBufferBitDepth) { if (depthBufferBitDepth == 32 && stencilBufferBitDepth == 8) format = GL_DEPTH32F_STENCIL8; else format = GL_DEPTH24_STENCIL8; GLuint id; glGenRenderbuffers(1, &id); renderBuffers.push_back(id); glBindRenderbuffer(GL_RENDERBUFFER, id); glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, id); } else if (stencilBufferBitDepth == 0) { if (depthBufferBitDepth == 16) format = GL_DEPTH_COMPONENT16; else if (depthBufferBitDepth == 24) format = GL_DEPTH_COMPONENT24; else format = GL_DEPTH_COMPONENT32F; GLuint id; glGenRenderbuffers(1, &id); renderBuffers.push_back(id); glBindRenderbuffer(GL_RENDERBUFFER, id); glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, id); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); }
bool do_blit_test(bool use_es2, bool from_missing_to_complete) { GLuint rb[3]; GLuint fb[2]; GLenum status; GLenum err; const unsigned src = from_missing_to_complete ? 0 : 1; const unsigned dst = 1 - src; const char *const names[] = { "buffer with missing attachment", "complete buffer" }; bool pass = true; printf("Testing blit from %s to %s...\n", names[src], names[dst]); /* Create a depth-only FBO and a depth/color FBO. */ glGenRenderbuffers(ARRAY_SIZE(rb), rb); glBindRenderbuffer(GL_RENDERBUFFER, rb[0]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, piglit_width, piglit_height); glBindRenderbuffer(GL_RENDERBUFFER, rb[1]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, piglit_width, piglit_height); glBindRenderbuffer(GL_RENDERBUFFER, rb[2]); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, piglit_width, piglit_height); glGenFramebuffers(ARRAY_SIZE(fb), fb); glBindFramebuffer(GL_FRAMEBUFFER, fb[0]); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb[0]); if (!use_es2) { glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb[1]); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb[1]); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb[2]); err = glGetError(); if (err != 0) { fprintf(stderr, "Unexpected GL error state 0x%04x\n", err); return false; } /* Check completeness of the source surface. */ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb[src]); status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { fprintf(stderr, "Read FBO erroneously incomplete: 0x%04x\n", status); return false; } /* In the source surface, clear the depth buffer and draw a single * rectangle with a constant depth value. The depth test setting here * is correct. */ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb[src]); glClearDepth(0.0); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); piglit_draw_rect_z(0.5, -0.5, -0.5, 1.0, 1.0); /* Check completeness of the destination surface. */ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb[dst]); status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { fprintf(stderr, "Draw FBO erroneously incomplete: 0x%04x\n", status); return false; } glBlitFramebuffer(0, 0, piglit_width, piglit_height, 0, 0, piglit_width, piglit_height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); err = glGetError(); if (err != 0) { fprintf(stderr, "Unexpected GL error state 0x%04x\n", err); return false; } /* Probe depth values from the destination buffer to make sure the * depth part of the blit actually happened. */ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb[dst]); pass = piglit_probe_rect_depth(0.25 * piglit_width, 0.25 * piglit_height, 0.4 * piglit_width, 0.4 * piglit_height, 0.75); pass = piglit_probe_rect_depth(0, 0, piglit_width, 0.2 * piglit_height, 0.0) && pass; glBindFramebuffer(GL_READ_FRAMEBUFFER, piglit_winsys_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo); glDeleteFramebuffers(ARRAY_SIZE(fb), fb); glDeleteRenderbuffers(ARRAY_SIZE(rb), rb); return pass; }
void QKmsBufferManager::setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers) { eglMakeCurrent(m_screen->device()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_screen->device()->eglContext()); m_screen->bindFramebuffer(); if (m_frameBufferObject) { clearBuffers(); } else { //Setup Framebuffer Object glGenFramebuffers(1, &m_frameBufferObject); glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); } //Setup shared Depth/Stencil buffer glGenRenderbuffers(1, &m_depthAndStencilBufferObject); glBindRenderbuffer(GL_RENDERBUFFER, m_depthAndStencilBufferObject); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mode.hdisplay, mode.vdisplay); //Setup "numBuffer" many rendering targets for (int i = 0; i < numBuffers; i++) { QKmsFramebuffer *buffer = new QKmsFramebuffer(); glGenRenderbuffers(1, &buffer->renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->renderBuffer); buffer->graphicsBufferObject = gbm_bo_create(m_screen->device()->gbmDevice(), mode.hdisplay, mode.vdisplay, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); buffer->eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR, buffer->graphicsBufferObject, 0); glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, buffer->eglImage); quint32 stride = gbm_bo_get_pitch(buffer->graphicsBufferObject); quint32 handle = gbm_bo_get_handle(buffer->graphicsBufferObject).u32; int status = drmModeAddFB(m_screen->device()->fd(), mode.hdisplay, mode.vdisplay, 32, 32, stride, handle, &buffer->framebufferId); //Todo: IF this returns true, then this is one less buffer that we use //Not so fatal, but not handled at the moment. if (status) qFatal("failed to add framebuffer"); m_framebuffers.append(buffer); } //Attach the Depth and Stencil buffer glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthAndStencilBufferObject); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthAndStencilBufferObject); //Attach renderbuffer as Color Attachment. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, this->renderTargetBuffer()); }