GLUSvoid terminate(GLUSvoid) { glBindBuffer(GL_ARRAY_BUFFER, 0); if (g_verticesVBO) { glDeleteBuffers(1, &g_verticesVBO); g_verticesVBO = 0; } if (g_normalsVBO) { glDeleteBuffers(1, &g_normalsVBO); g_normalsVBO = 0; } if (g_texCoordsVBO) { glDeleteBuffers(1, &g_texCoordsVBO); g_texCoordsVBO = 0; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (g_indicesVBO) { glDeleteBuffers(1, &g_indicesVBO); g_indicesVBO = 0; } glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); if (g_texture) { glDeleteTextures(1, &g_texture); g_texture = 0; } glBindVertexArray(0); if (g_vao) { glDeleteVertexArrays(1, &g_vao); g_vao = 0; } glUseProgram(0); glusProgramDestroy(&g_program); // glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); if (g_mirrorTexture) { glDeleteTextures(1, &g_mirrorTexture); g_mirrorTexture = 0; } glBindRenderbuffer(GL_RENDERBUFFER, 0); if (g_depthMirrorTexture) { glDeleteRenderbuffers(1, &g_depthMirrorTexture); g_depthMirrorTexture = 0; } glBindFramebuffer(GL_FRAMEBUFFER, 0); if (g_fboMirrorTexture) { glDeleteFramebuffers(1, &g_fboMirrorTexture); g_fboMirrorTexture = 0; } terminateWavefront(); }
void renderbuffer::deactivate() const { glBindRenderbuffer(GL_RENDERBUFFER, 0); }
rtt::fbo* rtt::add_buffer(const unsigned int width_, const unsigned int height_, const GLenum* target, const TEXTURE_FILTERING* filtering, const TEXTURE_ANTI_ALIASING* taa, const GLint* wrap_s, const GLint* wrap_t, const GLint* internal_format, const GLenum* format, const GLenum* type, const unsigned int attachment_count, const rtt::DEPTH_TYPE depth_type, const rtt::STENCIL_TYPE stencil_type) { unsigned int width = width_; unsigned int height = height_; rtt::fbo* buffer = new rtt::fbo(attachment_count); buffers.push_back(buffer); buffer->width = width; buffer->height = height; buffer->draw_width = width; buffer->draw_height = height; buffer->depth_type = depth_type; buffer->stencil_type = stencil_type; buffer->samples = 0; // const size_t max_tex_size = exts->get_max_texture_size(); const float fmax_tex_size = max_tex_size; size2 orig_resolution = size2(width, height); float ssaa = 0.0f; for(unsigned int i = 0; i < buffer->attachment_count; i++) { buffer->anti_aliasing[i] = taa[i]; float ssaa_factor = get_anti_aliasing_scale(buffer->anti_aliasing[i]); if(ssaa_factor <= 1.0f) continue; // // try lower ssaa setting float cur_ssaa_factor = ssaa_factor; while(cur_ssaa_factor >= 2.0f) { if(float(orig_resolution.x) * ssaa_factor > fmax_tex_size || float(orig_resolution.y) * ssaa_factor > fmax_tex_size) { cur_ssaa_factor -= 2.0f; continue; } else break; } if(cur_ssaa_factor <= 0.0f) { log_error("couldn't create a SSAA%u buffer (nor using a smaller SSAA setting)!", ssaa_factor); break; // break, since this won't work with any setting } if(cur_ssaa_factor < ssaa_factor) { log_error("couldn't create a SSAA%u buffer - using SSAA%u instead!", ssaa_factor, cur_ssaa_factor); } ssaa = std::max(ssaa, cur_ssaa_factor); } // apply ssaa if(ssaa > 0.0f) { const float2 ssaa_res = get_resolution_for_scale(ssaa, size2(width, height)); width = (unsigned int)ssaa_res.x; height = (unsigned int)ssaa_res.y; buffer->width = width; buffer->height = height; buffer->draw_width = width; buffer->draw_height = height; } // glGenFramebuffers(1, &buffer->fbo_id); glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id); glGenTextures((GLsizei)attachment_count, &buffer->tex[0]); for(unsigned int i = 0; i < buffer->attachment_count; i++) { #if defined(FLOOR_IOS) && !defined(PLATFORM_X64) if(i > 0) { log_error("too many FBO attachments - only one is allowed on iOS!"); break; } #endif buffer->target[i] = target[i]; glBindTexture(buffer->target[i], buffer->tex[i]); glTexParameteri(buffer->target[i], GL_TEXTURE_MAG_FILTER, (filtering[i] == TEXTURE_FILTERING::POINT ? GL_NEAREST : GL_LINEAR)); glTexParameteri(buffer->target[i], GL_TEXTURE_MIN_FILTER, texman::select_filter(filtering[i])); glTexParameteri(buffer->target[i], GL_TEXTURE_WRAP_S, wrap_s[i]); glTexParameteri(buffer->target[i], GL_TEXTURE_WRAP_T, wrap_t[i]); if(exts->is_anisotropic_filtering_support() && filtering[i] >= TEXTURE_FILTERING::BILINEAR) { glTexParameteri(buffer->target[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, (GLint)exts->get_max_anisotropic_filtering()); } switch(buffer->target[i]) { #if !defined(FLOOR_IOS) case GL_TEXTURE_1D: glTexImage1D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, 0, format[i], type[i], nullptr); break; #endif case GL_TEXTURE_2D: glTexImage2D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, 0, format[i], type[i], nullptr); break; #if !defined(FLOOR_IOS) case GL_TEXTURE_2D_MULTISAMPLE: glTexImage2DMultisample(buffer->target[i], (GLsizei)get_sample_count(buffer->anti_aliasing[0]), texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, false); break; #endif default: glTexImage2D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, 0, format[i], type[i], nullptr); break; } if(filtering[i] > TEXTURE_FILTERING::LINEAR) { buffer->auto_mipmap[i] = true; //glGenerateMipmap(buffer->target[i]); } else buffer->auto_mipmap[i] = false; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, buffer->target[i], buffer->tex[i], 0); #if !defined(FLOOR_IOS) #if defined(A2E_DEBUG) // TODO: fbo/texture checking GLint check_internal_format = 0, check_type = 0, check_size = 0; glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_INTERNAL_FORMAT, &check_internal_format); glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_RED_TYPE, &check_type); glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_RED_SIZE, &check_size); //log_debug("FBO: iformat: %X, type: %X, size: %d", check_internal_format, check_type, check_size); #endif #endif } current_buffer = buffer; check_fbo(current_buffer); // check if a depth attachment should be created if(depth_type != DEPTH_TYPE::NONE) { // apparently opencl/opengl depth texture sharing only works with a float format #if !defined(A2E_INFERRED_RENDERING_CL) GLenum depth_internel_format = GL_DEPTH_COMPONENT24; GLenum depth_storage_type = GL_UNSIGNED_INT; #else GLenum depth_internel_format = GL_DEPTH_COMPONENT32F; GLenum depth_storage_type = GL_FLOAT; #endif GLenum depth_format = GL_DEPTH_COMPONENT; GLenum depth_attachment_type = GL_DEPTH_ATTACHMENT; if(stencil_type == STENCIL_TYPE::STENCIL_8) { #if !defined(A2E_INFERRED_RENDERING_CL) depth_internel_format = GL_DEPTH24_STENCIL8; depth_storage_type = GL_UNSIGNED_INT_24_8; #else depth_internel_format = GL_DEPTH32F_STENCIL8; depth_storage_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; #endif depth_format = GL_DEPTH_STENCIL; depth_attachment_type = GL_DEPTH_STENCIL_ATTACHMENT; } buffer->depth_attachment_type = depth_attachment_type; switch(buffer->anti_aliasing[0]) { case TEXTURE_ANTI_ALIASING::NONE: case TEXTURE_ANTI_ALIASING::SSAA_2: case TEXTURE_ANTI_ALIASING::SSAA_4: case TEXTURE_ANTI_ALIASING::FXAA: case TEXTURE_ANTI_ALIASING::SSAA_4_3_FXAA: case TEXTURE_ANTI_ALIASING::SSAA_2_FXAA: if(depth_type == DEPTH_TYPE::RENDERBUFFER) { glGenRenderbuffers(1, &buffer->depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer); glRenderbufferStorage(GL_RENDERBUFFER, depth_internel_format, (GLsizei)width, (GLsizei)height); } else if(depth_type == DEPTH_TYPE::TEXTURE_2D) { glGenTextures(1, &buffer->depth_buffer); glBindTexture(GL_TEXTURE_2D, buffer->depth_buffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); glTexImage2D(GL_TEXTURE_2D, 0, texman::convert_internal_format((GLint)depth_internel_format), (GLsizei)width, (GLsizei)height, 0, depth_format, depth_storage_type, nullptr); glFramebufferTexture2D(GL_FRAMEBUFFER, depth_attachment_type, GL_TEXTURE_2D, buffer->depth_buffer, 0); } check_fbo(current_buffer); break; case TEXTURE_ANTI_ALIASING::MSAA_2: case TEXTURE_ANTI_ALIASING::MSAA_4: case TEXTURE_ANTI_ALIASING::MSAA_8: case TEXTURE_ANTI_ALIASING::MSAA_16: case TEXTURE_ANTI_ALIASING::MSAA_32: case TEXTURE_ANTI_ALIASING::MSAA_64: { buffer->samples = get_sample_count(buffer->anti_aliasing[0]); glGenFramebuffers((GLsizei)attachment_count, &buffer->resolve_buffer[0]); for(size_t i = 0; i < attachment_count; i++) { glBindFramebuffer(GL_FRAMEBUFFER, buffer->resolve_buffer[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum)(GL_COLOR_ATTACHMENT0+i), target[i], buffer->tex[i], 0); } check_fbo(current_buffer); glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id); glGenRenderbuffers(1, &buffer->color_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->color_buffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, (GLsizei)buffer->samples, (GLenum)internal_format[0], (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer->color_buffer); check_fbo(current_buffer); if(depth_type == DEPTH_TYPE::RENDERBUFFER) { glGenRenderbuffers(1, &buffer->depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, (GLsizei)buffer->samples, depth_internel_format, (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, depth_attachment_type, GL_RENDERBUFFER, buffer->depth_buffer); } #if !defined(FLOOR_IOS) else if(depth_type == DEPTH_TYPE::TEXTURE_2D) { glGenTextures(1, &buffer->depth_buffer); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, buffer->depth_buffer); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, (GLsizei)buffer->samples, texman::convert_internal_format((GLint)depth_internel_format), (GLsizei)width, (GLsizei)height, false); glFramebufferTexture2D(GL_FRAMEBUFFER, depth_attachment_type, GL_TEXTURE_2D_MULTISAMPLE, buffer->depth_buffer, 0); } #endif check_fbo(current_buffer); } break; #if !defined(FLOOR_IOS) && 0 // TODO: fix or remove this case TEXTURE_ANTI_ALIASING::CSAA_8: case TEXTURE_ANTI_ALIASING::CSAA_8Q: case TEXTURE_ANTI_ALIASING::CSAA_16: case TEXTURE_ANTI_ALIASING::CSAA_16Q: case TEXTURE_ANTI_ALIASING::CSAA_32: case TEXTURE_ANTI_ALIASING::CSAA_32Q: { int color_samples, coverage_samples; switch(buffer->anti_aliasing[0]) { case TEXTURE_ANTI_ALIASING::CSAA_8: color_samples = 4; coverage_samples = 8; break; case TEXTURE_ANTI_ALIASING::CSAA_8Q: color_samples = 8; coverage_samples = 8; break; case TEXTURE_ANTI_ALIASING::CSAA_16: color_samples = 4; coverage_samples = 16; break; case TEXTURE_ANTI_ALIASING::CSAA_16Q: color_samples = 8; coverage_samples = 16; break; case TEXTURE_ANTI_ALIASING::CSAA_32: // TODO: ratio? case TEXTURE_ANTI_ALIASING::CSAA_32Q: // TODO: ratio? default: color_samples = 4; coverage_samples = 8; break; } glGenRenderbuffers(1, &buffer->depth_buffer); glGenRenderbuffers(1, &buffer->color_buffer); glGenFramebuffers(1, &buffer->resolve_buffer[0]); glBindFramebuffer(GL_FRAMEBUFFER, buffer->resolve_buffer[0]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer->tex[0], 0); check_fbo(current_buffer); glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id); glBindRenderbuffer(GL_RENDERBUFFER, buffer->color_buffer); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, coverage_samples, color_samples, (GLenum)internal_format[0], (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer->color_buffer); check_fbo(current_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, coverage_samples, color_samples, depth_internel_format, (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, depth_attachment_type, GL_RENDERBUFFER, buffer->depth_buffer); check_fbo(current_buffer); } break; #else case TEXTURE_ANTI_ALIASING::CSAA_8: case TEXTURE_ANTI_ALIASING::CSAA_8Q: case TEXTURE_ANTI_ALIASING::CSAA_16: case TEXTURE_ANTI_ALIASING::CSAA_16Q: case TEXTURE_ANTI_ALIASING::CSAA_32: case TEXTURE_ANTI_ALIASING::CSAA_32Q: log_error("CSAA not supported right now"); break; #endif } } glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0); return buffer; }
int main(int argc, char **argv) { // init global vars initSharedMem(); // register exit callback atexit(exitCB); // init GLUT and GL initGLUT(argc, argv); initGL(); // create a texture object glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); 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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 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_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); // get OpenGL info glInfo glInfo; glInfo.getInfo(); //glInfo.printSelf(); #ifdef _WIN32 // check if FBO is supported by your video card if(glInfo.isExtensionSupported("GL_ARB_framebuffer_object")) { // get pointers to GL functions glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"); glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers"); glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"); glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus"); glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)wglGetProcAddress("glGetFramebufferAttachmentParameteriv"); glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmap"); glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)wglGetProcAddress("glFramebufferTexture1D"); glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"); glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)wglGetProcAddress("glFramebufferTexture3D"); glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)wglGetProcAddress("glFramebufferTextureLayer"); glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer"); glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)wglGetProcAddress("glIsFramebuffer"); glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)wglGetProcAddress("glBlitFramebuffer"); glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffers"); glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers"); glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbuffer"); glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorage"); glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)wglGetProcAddress("glRenderbufferStorageMultisample"); glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)wglGetProcAddress("glGetRenderbufferParameteriv"); glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)wglGetProcAddress("glIsRenderbuffer"); // check once again FBO extension if(glGenFramebuffers && glDeleteFramebuffers && glBindFramebuffer && glCheckFramebufferStatus && glGetFramebufferAttachmentParameteriv && glGenerateMipmap && glFramebufferTexture1D && glFramebufferTexture2D && glFramebufferTexture3D && glFramebufferTextureLayer && glFramebufferRenderbuffer && glIsFramebuffer && glBlitFramebuffer && glGenRenderbuffers && glDeleteRenderbuffers && glBindRenderbuffer && glRenderbufferStorage && glRenderbufferStorageMultisample && glGetRenderbufferParameteriv && glIsRenderbuffer) { fboSupported = fboUsed = true; std::cout << "Video card supports GL_ARB_framebuffer_object." << std::endl; } else { fboSupported = fboUsed = false; std::cout << "Video card does NOT support GL_ARB_framebuffer_object." << std::endl; } } // check EXT_swap_control is supported if(glInfo.isExtensionSupported("WGL_EXT_swap_control")) { // get pointers to WGL functions wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); if(wglSwapIntervalEXT && wglGetSwapIntervalEXT) { // disable v-sync wglSwapIntervalEXT(0); std::cout << "Video card supports WGL_EXT_swap_control." << std::endl; } } #else // for linux, do not need to get function pointers, it is up-to-date if(glInfo.isExtensionSupported("GL_ARB_framebuffer_object")) { fboSupported = fboUsed = true; std::cout << "Video card supports GL_ARB_framebuffer_object." << std::endl; } else { fboSupported = fboUsed = false; std::cout << "Video card does NOT support GL_ARB_framebuffer_object." << std::endl; } #endif if(fboSupported) { // create a MSAA framebuffer object // NOTE: All attachment images must have the same # of samples. // Ohterwise, the framebuffer status will not be completed. glGenFramebuffers(1, &fboMsaaId); glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId); // create a MSAA renderbuffer object to store color info glGenRenderbuffers(1, &rboColorId); glBindRenderbuffer(GL_RENDERBUFFER, rboColorId); glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaCount, GL_RGB8, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // create a MSAA renderbuffer object to store depth info // NOTE: A depth renderable image should be attached the FBO for depth test. // If we don't attach a depth renderable image to the FBO, then // the rendering output will be corrupted because of missing depth test. // If you also need stencil test for your rendering, then you must // attach additional image to the stencil attachement point, too. glGenRenderbuffers(1, &rboDepthId); glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId); glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaCount, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // attach msaa RBOs to FBO attachment points glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId); // create a normal (no MSAA) FBO to hold a render-to-texture glGenFramebuffers(1, &fboId); glBindFramebuffer(GL_FRAMEBUFFER, fboId); glGenRenderbuffers(1, &rboId); glBindRenderbuffer(GL_RENDERBUFFER, rboId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // attach a texture to FBO color attachement point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); // attach a rbo to FBO depth attachement point glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId); //@@ disable color buffer if you don't attach any color buffer image, //@@ for example, rendering the depth buffer only to a texture. //@@ Otherwise, glCheckFramebufferStatus will not be complete. //glDrawBuffer(GL_NONE); //glReadBuffer(GL_NONE); // check FBO status printFramebufferInfo(fboMsaaId); bool status = checkFramebufferStatus(fboMsaaId); if(!status) fboUsed = false; glBindFramebuffer(GL_FRAMEBUFFER, 0); } // start timer, the elapsed time will be used for rotating the teapot timer.start(); // the last GLUT call (LOOP) // window will be shown and display callback is triggered by events // NOTE: this call never return main(). glutMainLoop(); /* Start GLUT event-processing loop */ return 0; }
void InitGLES(void) { GLint linked; GLuint vertexShader; GLuint fragmentShader; assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0); assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0); assert((program = glCreateProgram()) != 0); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &linked); if (!linked) { GLint infoLen = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char *infoLog = malloc(infoLen); glGetProgramInfoLog(program, infoLen, NULL, infoLog); fprintf(stderr, "Error linking program:\n%s\n", infoLog); free(infoLog); } glDeleteProgram(program); exit(1); } //* GLuint fbid; glGenFramebuffers(1, &fbid); glBindFramebuffer(GL_FRAMEBUFFER, fbid); GLuint texid; glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #ifdef _OGLES_30_ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TARGET_SIZE, TARGET_SIZE, 0, GL_RGBA, GL_FLOAT, NULL); #endif #ifdef _OGLES_20_ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TARGET_SIZE, TARGET_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #endif 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, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texid, 0); GLuint rbid; glGenRenderbuffers(1, &rbid); glBindRenderbuffer(GL_RENDERBUFFER, rbid); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TARGET_SIZE, TARGET_SIZE); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbid); CheckFrameBufferStatus(); //*/ glClearColor(0, 0, 0, 0); glViewport(0, 0, TARGET_SIZE, TARGET_SIZE); glEnable(GL_DEPTH_TEST); glUseProgram(program); }
int main(int argc, char *argv[]) { auto t_start = std::chrono::high_resolution_clock::now(); GLfloat directionx, directiony, directionz; directionx = 0.0f; directiony = 0.0f; directionz = 1.0f; GLboolean quit = GL_FALSE; GLenum errorValue; // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { std::cerr << "SDL video initialization failed! Error: " << SDL_GetError() << std::endl; quit = GL_TRUE; SDL_Delay(5000); } SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_Window* window = SDL_CreateWindow("OpenGL tutorial", 100, 100, width, height, SDL_WINDOW_OPENGL); SDL_GLContext context = SDL_GL_CreateContext(window); // Initialize GLEW glewExperimental = GL_TRUE; glewInit(); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after GLEW init: " << errorValue << std::endl; } // Create Vertex Array Objects, don't bind yet /* VAOs are used to store all of the links between the vertex attributes and VBOs with raw vertex data. Since VBOs are just containers for the raw data that the graphics card reads and manipulates, the meaning and usage of the data has to be specified for each VBO & shader program. This might be quite cumbersome, if many shader programs are used, since the layout of the attributes would have to be specified every time. This is wheree VAOs come in: they can be used to store the links between VBO and the specified attributes. This way, a new VAO can be bound for each different shader program, which can then be changed easily at will by just calling glUseProgram(shaderProg1);. The graphics card then knows how to use the raw data in the VBO, since its usage and meaning has been specified beforehand and the links between VBOs and attributes has been saved to the VAO. As soon as VAO has been bound, all glVertexAttribPointer calls store the information to that VAO. */ GLuint vaoCube, vaoQuad; glGenVertexArrays(1, &vaoCube); glGenVertexArrays(1, &vaoQuad); // Create a Vertex Buffer Objects and upload vertex data /* VBOs are used to upload the vertex data to the graphics card. glGenBuffers(); creates a VBO, which can then be made active by binding it with glBindBuffer();. When the VBO has been set as active by binding it, the vertex data can be loaded to it with glBufferData();. Note that VBO/OpenGL doesn't know what the data means or is used for, it's just raw data. The usage of the data has to be specified, meaning which indices in the data correspond to which attribute (pos, color, texcoord, etc.). */ GLuint vboCube, vboQuad; glGenBuffers(1, &vboCube); glGenBuffers(1, &vboQuad); glBindBuffer(GL_ARRAY_BUFFER, vboCube); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, vboQuad); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after VBOs: " << errorValue << std::endl; } // Generate shader programs GLuint sceneVertexShader, sceneFragmentShader, sceneShaderProgram; createShaderprogram(sceneVertexSource, sceneFragmentSource, sceneVertexShader, sceneFragmentShader, sceneShaderProgram); GLuint screenVertexShader, screenFragmentShader, screenShaderProgram; createShaderprogram(screenVertexSource, screenFragmentSource, screenVertexShader, screenFragmentShader, screenShaderProgram); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after generating shader programs: " << errorValue << std::endl; } // Specify the layout of the vertex data (bind vertex arrays) /* Since OpenGL doesn't know how the attributes of the vertices are specified in the arrays containing the vertex information (position, color, texture coordinates), they need to be specified by the user. Each attribute also saves the VBO that's been bound to the current GL_ARRAY_BUFFER. This means different VBOs can be used for each attribute if so desired. Only calls after a VAO has been bound will "stick" to it. As soon as VAO has been bound, all glVertexAttribPointer calls store the information to that VAO. See more complete explanation of VAO above. */ glBindVertexArray(vaoCube); glBindBuffer(GL_ARRAY_BUFFER, vboCube); specifySceneVertexAttributes(sceneShaderProgram); glBindVertexArray(vaoQuad); glBindBuffer(GL_ARRAY_BUFFER, vboQuad); specifyScreenVertexAttributes(screenShaderProgram); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after specifying the layout of vertex data: " << errorValue << std::endl; } // Load textures GLuint texKitten = loadTexture("sample.png"); GLuint texPuppy = loadTexture("sample2.png"); glUseProgram(sceneShaderProgram); glUniform1i(glGetUniformLocation(sceneShaderProgram, "texKitten"), 0); glUniform1i(glGetUniformLocation(sceneShaderProgram, "texPuppy"), 1); glUseProgram(screenShaderProgram); glUniform1i(glGetUniformLocation(screenShaderProgram, "texFramebuffer"), 0); GLint uniModel = glGetUniformLocation(sceneShaderProgram, "model"); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after loading textures: " << errorValue << std::endl; } // Create frame buffer GLuint frameBuffer; glGenFramebuffers(1, &frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after creating a frame buffer: " << errorValue << std::endl; } // Create texture to hold color buffer GLuint texColorBuffer; glGenTextures(1, &texColorBuffer); glBindTexture(GL_TEXTURE_2D, texColorBuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, 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, texColorBuffer, 0); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after color buffer texture creation: " << errorValue << std::endl; } // Create Renderbuffer Object to hold depth and stencil buffers GLuint rboDepthStencil; glGenRenderbuffers(1, &rboDepthStencil); glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil); // Error checking errorValue = glGetError(); if (errorValue != 0) { std::cerr << "GL_Error after RBO: " << errorValue << std::endl; } /* Set up projection: View matrix: First vector gives the position of the camera Second vector gives the point where the camera is centered or looking at Third vector defines "up", here up is the z-axis, xy-plane is the "ground" */ glm::mat4 view = glm::lookAt( glm::vec3(2.5f, 2.5f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f) ); glUseProgram(sceneShaderProgram); GLint uniView = glGetUniformLocation(sceneShaderProgram, "view"); glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view)); // Projection matrix glm::mat4 proj = glm::perspective(glm::radians(45.0f), GLfloat(width) / GLfloat(height), 1.0f, 10.0f); GLint uniProj = glGetUniformLocation(sceneShaderProgram, "proj"); glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj)); GLint uniColor = glGetUniformLocation(sceneShaderProgram, "overrideColor"); // Final error check will write errors (if any are encountered at this point) to file GLint status, status2, status3, status4, OpenGLError; OpenGLError = glGetError(); GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); glGetShaderiv(sceneVertexShader, GL_COMPILE_STATUS, &status); glGetShaderiv(sceneFragmentShader, GL_COMPILE_STATUS, &status2); glGetShaderiv(screenVertexShader, GL_COMPILE_STATUS, &status3); glGetShaderiv(screenFragmentShader, GL_COMPILE_STATUS, &status4); if ( OpenGLError != 0 || status == 0 || status2 == 0 || status3 == 0 || status4 == 0 || frameBufferStatus != GL_FRAMEBUFFER_COMPLETE) { char buffer1[512], buffer2[512], buffer3[512], buffer4[512]; glGetShaderInfoLog(sceneVertexShader, 512, NULL, buffer1); glGetShaderInfoLog(sceneFragmentShader, 512, NULL, buffer2); glGetShaderInfoLog(screenVertexShader, 512, NULL, buffer3); glGetShaderInfoLog(screenFragmentShader, 512, NULL, buffer4); std::ofstream errorOutput; GLchar* errorOutFilename = "shader_errors.txt"; errorOutput.open(errorOutFilename); errorOutput << "GL_Error: " << OpenGLError << "\n Scene vertex shader status: " << status << "\n Scene vertex shader log: " << buffer1 << "\n Scene fragment shader status: " << status2 << "\n Scene fragment shader log: " << buffer2 << "\n Screen vertex shader status: " << status3 << "\n Screen vertex shader log: " << buffer3 << "\n Screen fragment shader status: " << status4 << "\n Screen fragment shader log: " << buffer4 << "\n Frame buffer status: " << frameBufferStatus << "\n OpenGL version: " << glGetString(GL_VERSION); errorOutput.close(); std::cerr << "An error has occured with shaders or frame buffer! See " << errorOutFilename << " for more info!\n Terminating program in 10s!" << std::endl; SDL_Delay(10000); quit = GL_TRUE; } SDL_Event e; while (!quit) { while (SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { quit = GL_TRUE; } else if (e.type == SDL_KEYDOWN) { switch (e.key.keysym.sym) { case SDLK_RETURN: directionx = 1.0f; directiony = 0.0f; directionz = 0.0f; break; case SDLK_SPACE: directionx = 0.0f; directiony = 1.0f; directionz = 0.0f; break; case SDLK_LCTRL: directionx = 0.0f; directiony = 0.0f; directionz = 1.0f; default: directionx = 0.0f; directiony = 0.0f; directionz = 1.0f; break; } } } // Bind framebuffer and draw 3D scene glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); glBindVertexArray(vaoCube); glEnable(GL_DEPTH_TEST); glUseProgram(sceneShaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texKitten); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texPuppy); // Clear screen to greenish glClearColor(0.15f, 0.7f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Calculate transformation auto t_now = std::chrono::high_resolution_clock::now(); float time = std::chrono::duration_cast<std::chrono::duration<float>>(t_now - t_start).count(); glm::mat4 model; model = glm::rotate(model, time * glm::radians(180.f), glm::vec3(directionx, directiony, directionz)); glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model)); // Draw cube glDrawArrays(GL_TRIANGLES, 0, 36); glEnable(GL_STENCIL_TEST); // Draw floor glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to 1 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilMask(0xFF); // Write to stencil buffer glDepthMask(GL_FALSE); // Don't write to depth buffer glClear(GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default) glDrawArrays(GL_TRIANGLES, 36, 6); // Draw cube reflection glStencilFunc(GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1 glStencilMask(0x00); // Don't write anything to stencil buffer glDepthMask(GL_TRUE); // Write to depth buffer model = glm::scale(glm::translate(model, glm::vec3(0, 0, -1)), glm::vec3(1, 1, -1)); glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model)); glUniform3f(uniColor, 0.3f, 0.3f, 0.3f); glDrawArrays(GL_TRIANGLES, 0, 36); glUniform3f(uniColor, 1.0f, 1.0f, 1.0f); glDisable(GL_STENCIL_TEST); // Bind default framebuffer and draw contents of our framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindVertexArray(vaoQuad); glDisable(GL_DEPTH_TEST); glUseProgram(screenShaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texColorBuffer); glDrawArrays(GL_TRIANGLES, 0, 6); // Swap buffers SDL_GL_SwapWindow(window); } glDeleteRenderbuffers(1, &rboDepthStencil); glDeleteTextures(1, &texColorBuffer); glDeleteFramebuffers(1, &frameBuffer); glDeleteTextures(1, &texKitten); glDeleteTextures(1, &texPuppy); glDeleteProgram(screenShaderProgram); glDeleteShader(screenFragmentShader); glDeleteShader(screenVertexShader); glDeleteProgram(sceneShaderProgram); glDeleteShader(sceneFragmentShader); glDeleteShader(sceneVertexShader); glDeleteBuffers(1, &vboCube); glDeleteBuffers(1, &vboQuad); glDeleteVertexArrays(1, &vaoCube); glDeleteVertexArrays(1, &vaoQuad); SDL_GL_DeleteContext(context); SDL_Quit(); return 0; }
void RendererGlut::bind_buffers() const { glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); glBindRenderbuffer(GL_RENDERBUFFER, rbo_id_); }
/* Page 203 */ static bool test_bindrenderbuffer() { glBindRenderbuffer(GL_RENDERBUFFER, 600); return piglit_check_gl_error(GL_INVALID_OPERATION); }
/*!**************************************************************************** @Function InitView @Return bool true if no error occured @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLES2Bloom::InitView() { CPVRTString ErrorStr; /* Initialize VBO data */ if(!LoadVbos(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } /* Load textures */ if(!LoadTextures(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } /* Load and compile the shaders & link programs */ if(!LoadShaders(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } // Check to see if the GL_EXT_discard_framebuffer extension is supported m_bDiscard = CPVRTgles2Ext::IsGLExtensionSupported("GL_EXT_discard_framebuffer"); if(m_bDiscard) { m_Extensions.LoadExtensions(); m_bDiscard = m_Extensions.glDiscardFramebufferEXT != 0; } /* Initialize Print3D */ bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n"); return false; } /* Get the currently bound frame buffer object. On most platforms this just gives 0. */ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // create a new depth render buffer glGenRenderbuffers(1, &m_uiDepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_uiDepthBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_i32TexSize, m_i32TexSize); /* Set OpenGL ES render states needed for this training course */ glGenFramebuffers(2, m_uiBlurFramebufferObjects); for (unsigned int i=0; i < 2; i++) { glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[i]); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // The first render target needs a depth buffer, as we have to draw "blooming" 3d objects into it if (i==0) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_uiDepthBuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_uiBlurTextures[i], 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { PVRShellSet(prefExitMessage, "ERROR: Frame buffer not set up correctly\n"); return false; } } glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo); return true; }
GLUSboolean init(GLUSvoid) { GLUSshape backgroundSphere; GLUSshape wavefront; // 6 sides of diffuse and specular; all roughness levels of specular. GLUShdrimage image[6 * NUMBER_ROUGHNESS + 6]; // The look up table (LUT) is stored in a raw binary file. GLUSbinaryfile rawimage; GLUStextfile vertexSource; GLUStextfile fragmentSource; GLchar buffer[27] = "doge2/doge2_POS_X_00_s.hdr"; GLint i, k, m; // glusLoadTextFile("../Example33/shader/brdf.vert.glsl", &vertexSource); glusLoadTextFile("../Example33/shader/brdf.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_modelProgram, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); g_viewProjectionMatrixModelLocation = glGetUniformLocation(g_modelProgram.program, "u_viewProjectionMatrix"); g_modelMatrixModelLocation = glGetUniformLocation(g_modelProgram.program, "u_modelMatrix"); g_normalMatrixModelLocation = glGetUniformLocation(g_modelProgram.program, "u_normalMatrix"); g_eyeModelLocation = glGetUniformLocation(g_modelProgram.program, "u_eye"); g_textureSpecularModelLocation = glGetUniformLocation(g_modelProgram.program, "u_textureSpecular"); g_textureDiffuseModelLocation = glGetUniformLocation(g_modelProgram.program, "u_textureDiffuse"); g_textureLUTModelLocation = glGetUniformLocation(g_modelProgram.program, "u_textureLUT"); g_colorMaterialModelLocation = glGetUniformLocation(g_modelProgram.program, "u_colorMaterial"); g_roughnessMaterialModelLocation = glGetUniformLocation(g_modelProgram.program, "u_roughnessMaterial"); g_roughnessScaleModelLocation = glGetUniformLocation(g_modelProgram.program, "u_roughnessScale"); g_R0MaterialModelLocation = glGetUniformLocation(g_modelProgram.program, "u_R0Material"); g_vertexModelLocation = glGetAttribLocation(g_modelProgram.program, "a_vertex"); g_normalModelLocation = glGetAttribLocation(g_modelProgram.program, "a_normal"); // glusLoadTextFile("../Example33/shader/fullscreen.vert.glsl", &vertexSource); glusLoadTextFile("../Example33/shader/fullscreen.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_fullscreenProgram, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); // g_framebufferTextureFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_framebufferTexture"); g_msaaSamplesFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_msaaSamples"); g_exposureFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_exposure"); g_gammaFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_gamma"); // // glusLoadTextFile("../Example33/shader/background.vert.glsl", &vertexSource); glusLoadTextFile("../Example33/shader/background.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_backgroundProgram, (const GLUSchar**)&vertexSource.text, 0, 0, 0, (const GLUSchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); // g_viewProjectionMatrixBackgroundLocation = glGetUniformLocation(g_backgroundProgram.program, "u_viewProjectionMatrix"); g_textureBackgroundLocation = glGetUniformLocation(g_backgroundProgram.program, "u_texture"); g_vertexBackgroundLocation = glGetAttribLocation(g_backgroundProgram.program, "a_vertex"); // // Setting up the full screen frame buffer. // glGenTextures(1, &g_fullscreenTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, g_fullscreenTexture); // Create MSAA texture. glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, MSAA_SAMPLES, GL_RGB32F, SCREEN_WIDTH, SCREEN_HEIGHT, GL_TRUE); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); // No need to access the depth buffer, so a render buffer is sufficient. glGenRenderbuffers(1, &g_fullscreenDepthRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, g_fullscreenDepthRenderbuffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_SAMPLES, GL_DEPTH_COMPONENT, SCREEN_WIDTH, SCREEN_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // glGenFramebuffers(1, &g_fullscreenFBO); glBindFramebuffer(GL_FRAMEBUFFER, g_fullscreenFBO); // Attach the color buffer ... glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, g_fullscreenTexture, 0); // ... and the depth buffer. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_fullscreenDepthRenderbuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("GL_FRAMEBUFFER_COMPLETE error 0x%x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); return GLUS_FALSE; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // // // for (i = 0; i < 2; i++) { if (i == 0) { buffer[21] = 's'; } else { buffer[21] = 'd'; } for (k = 0; k < NUMBER_ROUGHNESS; k++) { if (i == 1 && k > 0) { continue; } buffer[18] = '0' + k / 10; buffer[19] = '0' + k % 10; for (m = 0; m < 6; m++) { if (m % 2 == 0) { buffer[12] = 'P'; buffer[13] = 'O'; buffer[14] = 'S'; } else { buffer[12] = 'N'; buffer[13] = 'E'; buffer[14] = 'G'; } switch (m) { case 0: case 1: buffer[16] = 'X'; break; case 2: case 3: buffer[16] = 'Y'; break; case 4: case 5: buffer[16] = 'Z'; break; } printf("Loading '%s' ...", buffer); if (!glusLoadHdrImage(buffer, &image[i*NUMBER_ROUGHNESS*6 + k*6 + m])) { printf(" error!\n"); continue; } printf(" done.\n"); } } } glGenTextures(1, &g_texture[0]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, g_texture[0]); glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGB32F, image[0].width, image[0].height, 6*NUMBER_ROUGHNESS, 0, GL_RGB, GL_FLOAT, 0); glusLogPrintError(GLUS_LOG_INFO, "glTexImage3D()"); for (i = 0; i < NUMBER_ROUGHNESS; i++) { for (k = 0; k < 6; k++) { glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 6*i + k, image[i*6 + k].width, image[i*6 + k].height, 1, image[i*6 + k].format, GL_FLOAT, image[i*6 + k].data); glusLogPrintError(GLUS_LOG_INFO, "glTexSubImage3D() %d %d", i, k); } } glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); // glGenTextures(1, &g_texture[1]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, g_texture[1]); for (i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, image[i + 6*NUMBER_ROUGHNESS].format, image[i + 6*NUMBER_ROUGHNESS].width, image[i + 6*NUMBER_ROUGHNESS].height, 0, image[i + 6*NUMBER_ROUGHNESS].format, GL_FLOAT, image[i + 6*NUMBER_ROUGHNESS].data); glusLogPrintError(GLUS_LOG_INFO, "glTexImage2D() %d", i); } glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); // printf("Loading 'doge2/EnvironmentBRDF_1024.data' ..."); if (!glusLoadBinaryFile("doge2/EnvironmentBRDF_1024.data", &rawimage)) { printf(" error!\n"); } else { printf(" done.\n"); } glGenTextures(1, &g_texture[2]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, g_texture[2]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, 1024, 1024, 0, GL_RG, GL_FLOAT, (GLfloat*)rawimage.binary); glusLogPrintError(GLUS_LOG_INFO, "glTexImage2D()"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); glBindTexture(GL_TEXTURE_2D, 0); glusDestroyBinaryFile(&rawimage); // for (i = 0; i < 2; i++) { for (k = 0; k < NUMBER_ROUGHNESS; k++) { if (i == 1 && k > 0) { continue; } for (m = 0; m < 6; m++) { glusDestroyHdrImage(&image[i*NUMBER_ROUGHNESS*6 + k*6 + m]); } } } // glusCreateSpheref(&backgroundSphere, 500.0f, 32); g_numberIndicesBackground = backgroundSphere.numberIndices; glGenBuffers(1, &g_verticesBackgroundVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesBackgroundVBO); glBufferData(GL_ARRAY_BUFFER, backgroundSphere.numberVertices * 4 * sizeof(GLfloat), (GLfloat*)backgroundSphere.vertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &g_indicesBackgroundVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesBackgroundVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, backgroundSphere.numberIndices * sizeof(GLuint), (GLuint*)backgroundSphere.indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glusDestroyShapef(&backgroundSphere); // // // Use a helper function to load an wavefront object file. glusLoadObjFile("venusm.obj", &wavefront); g_numberVerticesModel = wavefront.numberVertices; glGenBuffers(1, &g_verticesModelVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesModelVBO); glBufferData(GL_ARRAY_BUFFER, wavefront.numberVertices * 4 * sizeof(GLfloat), (GLfloat*)wavefront.vertices, GL_STATIC_DRAW); glGenBuffers(1, &g_normalsModelVBO); glBindBuffer(GL_ARRAY_BUFFER, g_normalsModelVBO); glBufferData(GL_ARRAY_BUFFER, wavefront.numberVertices * 3 * sizeof(GLfloat), (GLfloat*)wavefront.normals, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glusDestroyShapef(&wavefront); // glUseProgram(g_modelProgram.program); glUniform4fv(g_eyeModelLocation, 1, g_eye); glUniform1i(g_textureSpecularModelLocation, 0); glUniform1i(g_textureDiffuseModelLocation, 1); glUniform1i(g_textureLUTModelLocation, 2); glUniform1f(g_roughnessScaleModelLocation, (GLfloat)(NUMBER_ROUGHNESS - 1)); glGenVertexArrays(1, &g_modelVAO); glBindVertexArray(g_modelVAO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesModelVBO); glVertexAttribPointer(g_vertexModelLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexModelLocation); glBindBuffer(GL_ARRAY_BUFFER, g_normalsModelVBO); glVertexAttribPointer(g_normalModelLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_normalModelLocation); // glUseProgram(g_fullscreenProgram.program); glUniform1i(g_framebufferTextureFullscreenLocation, 0); glUniform1i(g_msaaSamplesFullscreenLocation, MSAA_SAMPLES); glGenVertexArrays(1, &g_fullscreenVAO); glBindVertexArray(g_fullscreenVAO); // glUseProgram(g_backgroundProgram.program); glUniform1i(g_textureBackgroundLocation, 0); glGenVertexArrays(1, &g_backgroundVAO); glBindVertexArray(g_backgroundVAO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesBackgroundVBO); glVertexAttribPointer(g_vertexBackgroundLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexBackgroundLocation); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesBackgroundVBO); // glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_CULL_FACE); return GLUS_TRUE; }
GLUSvoid terminate(GLUSvoid) { glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); if (g_texture[0]) { glDeleteTextures(1, &g_texture[0]); g_texture[0] = 0; } glBindTexture(GL_TEXTURE_CUBE_MAP, 0); if (g_texture[1]) { glDeleteTextures(1, &g_texture[1]); g_texture[1] = 0; } glBindTexture(GL_TEXTURE_2D, 0); if (g_texture[2]) { glDeleteTextures(1, &g_texture[2]); g_texture[2] = 0; } // glBindBuffer(GL_ARRAY_BUFFER, 0); if (g_verticesModelVBO) { glDeleteBuffers(1, &g_verticesModelVBO); g_verticesModelVBO = 0; } if (g_normalsModelVBO) { glDeleteBuffers(1, &g_normalsModelVBO); g_normalsModelVBO = 0; } if (g_verticesBackgroundVBO) { glDeleteBuffers(1, &g_verticesBackgroundVBO); g_verticesBackgroundVBO = 0; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (g_indicesBackgroundVBO) { glDeleteBuffers(1, &g_indicesBackgroundVBO); g_indicesBackgroundVBO = 0; } glBindVertexArray(0); if (g_modelVAO) { glDeleteVertexArrays(1, &g_modelVAO); g_modelVAO = 0; } if (g_backgroundVAO) { glDeleteVertexArrays(1, &g_backgroundVAO); g_backgroundVAO = 0; } if (g_fullscreenVAO) { glDeleteVertexArrays(1, &g_fullscreenVAO); g_fullscreenVAO = 0; } glUseProgram(0); glusDestroyProgram(&g_modelProgram); glusDestroyProgram(&g_backgroundProgram); glusDestroyProgram(&g_fullscreenProgram); // glBindTexture(GL_TEXTURE_2D, 0); if (g_fullscreenTexture) { glDeleteTextures(1, &g_fullscreenTexture); g_fullscreenTexture = 0; } glBindRenderbuffer(GL_RENDERBUFFER, 0); if (g_fullscreenDepthRenderbuffer) { glDeleteRenderbuffers(1, &g_fullscreenDepthRenderbuffer); g_fullscreenDepthRenderbuffer = 0; } glBindFramebuffer(GL_FRAMEBUFFER, 0); if (g_fullscreenFBO) { glDeleteFramebuffers(1, &g_fullscreenFBO); g_fullscreenFBO = 0; } }
int main(int argc, char* argv[]) { // Get an OSVR client context to use to access the devices // that we need. osvr::clientkit::ClientContext context( "com.osvr.renderManager.openGLExample"); // Construct button devices and connect them to a callback // that will set the "quit" variable to true when it is // pressed. Use button "1" on the left-hand or // right-hand controller. osvr::clientkit::Interface leftButton1 = context.getInterface("/controller/left/1"); leftButton1.registerCallback(&myButtonCallback, &quit); osvr::clientkit::Interface rightButton1 = context.getInterface("/controller/right/1"); rightButton1.registerCallback(&myButtonCallback, &quit); // Use SDL to open a window and then get an OpenGL context for us. // Note: This window is not the one that will be used for rendering // the OSVR display, but one that will be cleared to a slowly-changing // constant color so we can see that we're able to render to both // contexts. if (!osvr::renderkit::SDLInitQuit()) { std::cerr << "Could not initialize SDL" << std::endl; return 100; } SDL_Window *myWindow = SDL_CreateWindow( "Test window, not used", 30, 30, 300, 100, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN); if (myWindow == nullptr) { std::cerr << "SDL window open failed: Could not get window" << std::endl; return 101; } SDL_GLContext myGLContext; myGLContext = SDL_GL_CreateContext(myWindow); if (myGLContext == 0) { std::cerr << "RenderManagerOpenGL::addOpenGLContext: Could not get " "OpenGL context" << std::endl; return 102; } // Open OpenGL and set up the context for rendering to // an HMD. Do this using the OSVR RenderManager interface, // which maps to the nVidia or other vendor direct mode // to reduce the latency. osvr::renderkit::RenderManager* render = osvr::renderkit::createRenderManager(context.get(), "OpenGL"); if ((render == nullptr) || (!render->doingOkay())) { std::cerr << "Could not create RenderManager" << std::endl; return 1; } // Set up a handler to cause us to exit cleanly. #ifdef _WIN32 SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); #endif // Open the display and make sure this worked. osvr::renderkit::RenderManager::OpenResults ret = render->OpenDisplay(); if (ret.status == osvr::renderkit::RenderManager::OpenStatus::FAILURE) { std::cerr << "Could not open display" << std::endl; delete render; return 2; } // Set up the rendering state we need. if (!SetupRendering(ret.library)) { return 3; } // Do a call to get the information we need to construct our // color and depth render-to-texture buffers. std::vector<osvr::renderkit::RenderInfo> renderInfo; context.update(); renderInfo = render->GetRenderInfo(); std::vector<osvr::renderkit::RenderBuffer> colorBuffers; std::vector<GLuint> depthBuffers; //< Depth/stencil buffers to render into // Initialize the textures with our window's context open, // so that they will be associated with it. SDL_GL_MakeCurrent(myWindow, myGLContext); // Construct the buffers we're going to need for our render-to-texture // code. GLuint frameBuffer; //< Groups a color buffer and a depth buffer glGenFramebuffers(1, &frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); for (size_t i = 0; i < renderInfo.size(); i++) { // The color buffer for this eye. We need to put this into // a generic structure for the Present function, but we only need // to fill in the OpenGL portion. // Note that this must be used to generate a RenderBuffer, not just // a texture, if we want to be able to present it to be rendered // via Direct3D for DirectMode. This is selected based on the // config file value, so we want to be sure to use the more general // case. // Note that this texture format must be RGBA and unsigned byte, // so that we can present it to Direct3D for DirectMode GLuint colorBufferName = 0; glGenTextures(1, &colorBufferName); osvr::renderkit::RenderBuffer rb; rb.OpenGL = new osvr::renderkit::RenderBufferOpenGL; rb.OpenGL->colorBufferName = colorBufferName; colorBuffers.push_back(rb); // "Bind" the newly created texture : all future texture // functions will modify this texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, colorBufferName); // Determine the appropriate size for the frame buffer to be used for // this eye. int width = static_cast<int>(renderInfo[i].viewport.width); int height = static_cast<int>(renderInfo[i].viewport.height); // Give an empty image to OpenGL ( the last "0" means "empty" ) // Note that whether or not the second GL_RGBA is turned into // GL_BGRA, the first one should remain GL_RGBA -- it is specifying // the size. If the second is changed to GL_RGB or GL_BGR, then // the first should become GL_RGB. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // Bilinear filtering 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); // The depth buffer GLuint depthrenderbuffer; glGenRenderbuffers(1, &depthrenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); depthBuffers.push_back(depthrenderbuffer); } // Register our constructed buffers so that we can use them for // presentation. if (!render->RegisterRenderBuffers(colorBuffers)) { std::cerr << "RegisterRenderBuffers() returned false, cannot continue" << std::endl; quit = true; } // Continue rendering until it is time to quit. while (!quit) { // Update the context so we get our callbacks called and // update tracker state. context.update(); renderInfo = render->GetRenderInfo(); // Render into each buffer using the specified information. for (size_t i = 0; i < renderInfo.size(); i++) { RenderView(renderInfo[i], frameBuffer, colorBuffers[i].OpenGL->colorBufferName, depthBuffers[i]); } // Send the rendered results to the screen if (!render->PresentRenderBuffers(colorBuffers, renderInfo)) { std::cerr << "PresentRenderBuffers() returned false, maybe because " "it was asked to quit" << std::endl; quit = true; } // Draw something in our window, just looping the background color // Render to the standard framebuffer in our own window // Because we bind a different frame buffer in our draw routine, we // need to put this back here. SDL_GL_MakeCurrent(myWindow, myGLContext); glBindFramebuffer(GL_FRAMEBUFFER, 0); static GLfloat bg = 0; glViewport(static_cast<GLint>(0), static_cast<GLint>(0), static_cast<GLint>(300), static_cast<GLint>(100)); glClearColor(bg, bg, bg, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(myWindow); bg += 0.003f; if (bg > 1) { bg = 0; } } // Clean up after ourselves. glDeleteFramebuffers(1, &frameBuffer); for (size_t i = 0; i < renderInfo.size(); i++) { glDeleteTextures(1, &colorBuffers[i].OpenGL->colorBufferName); delete colorBuffers[i].OpenGL; glDeleteRenderbuffers(1, &depthBuffers[i]); } // Close the Renderer interface cleanly. delete render; return 0; }
CubeMap:: CubeMap(GLsizei w, GLsizei h): width(w), height(h), handle(0), textureHandle(0) { //Create buffers glGenFramebuffers(1, &handle); glBindFramebuffer(GL_FRAMEBUFFER, handle); //Make texture for our frame buffers to store stuff in glActiveTexture(GL_TEXTURE10); glGenTextures(1, &textureHandle); glBindTexture(GL_TEXTURE_CUBE_MAP, textureHandle);//GL_TEXTURE_CUBE_MAP //Set some texture parameters glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT); GLuint depthrenderbuffer; glGenRenderbuffers(1, &depthrenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width,height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); /* * 1. The texture target. We are actually saying here what part of the cube map we are loading. * 2. Level of detail - used for mipmapping. SIcne we are not mipmapping anything, we set to 0. * 3. Format to store image on graphics card * 4. width * 5. height * 6. border? * 7. Format in which image is stored in RAM: We pick GL_RGB because that is the format our PNG were stored in. * 8. Data type our image is stored in - We used unsigneds. * 9. Pointer to actual data. */ unsigned char* data; data = loadTextureFromPNG("textures/skybox/terrain_positive_x.png", width, height); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); data = loadTextureFromPNG("textures/skybox/terrain_positive_y.png", width, height); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); data = loadTextureFromPNG("textures/skybox/terrain_positive_z.png", width, height); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); data = loadTextureFromPNG("textures/skybox/terrain_negative_x.png", width, height); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); data = loadTextureFromPNG("textures/skybox/terrain_negative_y.png", width, height); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); data = loadTextureFromPNG("textures/skybox/terrain_negative_z.png", width, height); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { switch (status) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: //throw RuntimeError("Incomplete framebuffer attachment."); cout << "[ERROR]: Incomplete framebuffer attachment." << endl; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: //throw RuntimeError("No color attachment in draw buffer."); cout << "[ERROR]: No color attachment in draw buffer." << endl; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: // throw RuntimeError("No color attachment in read buffer."); cout << "[ERROR]: No color attachment in read buffer." << endl; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: //throw RuntimeError("Framebuffer is missing an attachment."); cout << "[ERROR]: Framebuffer is missing an attachment." << endl; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: //throw RuntimeError("The framebuffer different size multisamples."); cout << "[ERROR]: The framebuffer different size multisamples." << endl; case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: //throw RuntimeError("Not all framebuffer attachments are layered."); cout << "[ERROR]: Not all framebuffer attachments are layered." << endl; case GL_FRAMEBUFFER_UNSUPPORTED: //throw RuntimeError("The framebuffer configuration is unsupported."); cout << "[ERROR]: The framebuffer configuration is unsupported." << endl; default: //throw RuntimeError("Unknown framebuffer error."); cout << "[ERROR]: Unknown framebuffer errort." << endl; } exit(-1); } unbind(); }
GLUSboolean init(GLUSvoid) { GLUStextfile vertexSource; GLUStextfile fragmentSource; GLUStgaimage image; GLUSshape plane; // glusMatrix4x4LookAtf(g_viewMatrix, g_camera.eye[0], g_camera.eye[1], g_camera.eye[2], g_camera.center[0], g_camera.center[1], g_camera.center[2], g_camera.up[0], g_camera.up[1], g_camera.up[2]); // if (!initWavefront(g_viewMatrix, &g_light)) { return GLUS_FALSE; } // glusFileLoadText("../Example19_ES/shader/basic_proj.vert.glsl", &vertexSource); glusFileLoadText("../Example19_ES/shader/texture_multi_proj.frag.glsl", &fragmentSource); glusProgramBuildFromSource(&g_program, (const GLUSchar**) &vertexSource.text, (const GLUSchar**) &fragmentSource.text); glusFileDestroyText(&vertexSource); glusFileDestroyText(&fragmentSource); // // Retrieve the uniform locations in the program. g_viewProjectionMatrixLocation = glGetUniformLocation(g_program.program, "u_viewProjectionMatrix"); g_viewProjectionBiasTextureMatrixLocation = glGetUniformLocation(g_program.program, "u_viewProjectionBiasTextureMatrix"); g_modelMatrixLocation = glGetUniformLocation(g_program.program, "u_modelMatrix"); g_normalMatrixLocation = glGetUniformLocation(g_program.program, "u_normalMatrix"); g_lightDirectionLocation = glGetUniformLocation(g_program.program, "u_lightDirection"); g_repeatLocation = glGetUniformLocation(g_program.program, "u_repeat"); g_textureLocation = glGetUniformLocation(g_program.program, "u_texture"); g_mirrorTextureLocation = glGetUniformLocation(g_program.program, "u_mirrorTexture"); // Retrieve the attribute locations in the program. g_vertexLocation = glGetAttribLocation(g_program.program, "a_vertex"); g_normalLocation = glGetAttribLocation(g_program.program, "a_normal"); g_texCoordLocation = glGetAttribLocation(g_program.program, "a_texCoord"); // // Texture set up. glusImageLoadTga("ice.tga", &image); glGenTextures(1, &g_texture); glBindTexture(GL_TEXTURE_2D, g_texture); glTexImage2D(GL_TEXTURE_2D, 0, image.format, image.width, image.height, 0, image.format, GL_UNSIGNED_BYTE, image.data); // Mipmap generation is now included in OpenGL 3 and above glGenerateMipmap(GL_TEXTURE_2D); // Trilinear filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); // // Setting up the offscreen frame buffer. // glGenTextures(1, &g_mirrorTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, g_mirrorTexture); glTexImage2D(GL_TEXTURE_2D, 0, GLUS_RGB, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GLUS_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); glBindTexture(GL_TEXTURE_2D, 0); // glGenRenderbuffers(1, &g_depthMirrorTexture); glBindRenderbuffer(GL_RENDERBUFFER, g_depthMirrorTexture); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // glGenFramebuffers(1, &g_fboMirrorTexture); glBindFramebuffer(GL_FRAMEBUFFER, g_fboMirrorTexture); // Attach the color buffer ... glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_mirrorTexture, 0); // ... and the depth buffer, glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_depthMirrorTexture); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("GL_FRAMEBUFFER_COMPLETE error 0x%x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); return GLUS_FALSE; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // // // glusShapeCreatePlanef(&plane, 3.0f); g_numberIndicesSphere = plane.numberIndices; glGenBuffers(1, &g_verticesVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 4 * sizeof(GLfloat), (GLfloat*) plane.vertices, GL_STATIC_DRAW); glGenBuffers(1, &g_normalsVBO); glBindBuffer(GL_ARRAY_BUFFER, g_normalsVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 3 * sizeof(GLfloat), (GLfloat*) plane.normals, GL_STATIC_DRAW); glGenBuffers(1, &g_texCoordsVBO); glBindBuffer(GL_ARRAY_BUFFER, g_texCoordsVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 2 * sizeof(GLfloat), (GLfloat*) plane.texCoords, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &g_indicesVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, plane.numberIndices * sizeof(GLuint), (GLuint*) plane.indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glusShapeDestroyf(&plane); // glUseProgram(g_program.program); glGenVertexArrays(1, &g_vao); glBindVertexArray(g_vao); glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO); glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexLocation); glBindBuffer(GL_ARRAY_BUFFER, g_normalsVBO); glVertexAttribPointer(g_normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_normalLocation); glBindBuffer(GL_ARRAY_BUFFER, g_texCoordsVBO); glVertexAttribPointer(g_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_texCoordLocation); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesVBO); // glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, g_texture); glUniform1i(g_textureLocation, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, g_mirrorTexture); glUniform1i(g_mirrorTextureLocation, 1); // How many times the surface texture is repeated. glUniform1f(g_repeatLocation, 6.0f); // glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepthf(1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); return GLUS_TRUE; }
int main() { EmscriptenWebGLContextAttributes attrs; emscripten_webgl_init_context_attributes(&attrs); attrs.enableExtensionsByDefault = true; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(0, &attrs); emscripten_webgl_make_context_current(context); // Test what the return values of GL_IMPLEMENTATION_COLOR_READ_TYPE and GL_IMPLEMENTATION_COLOR_READ_FORMAT are. GLint type = -1, format = -1; glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type); printf("GL_IMPLEMENTATION_COLOR_READ_TYPE for FBO 0: 0x%x\n", type); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format); printf("GL_IMPLEMENTATION_COLOR_READ_FORMAT for FBO 0: 0x%x\n", format); // Try glReadPixels() in that format. unsigned char data[16]; glReadPixels(0, 0, 1, 1, format, type, &data); assert(glGetError() == 0 && "glReadPixels of FBO 0 in implementation defined format failed"); // Try glReadPixels() in the format that is mandated to work by the spec. glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data); assert(glGetError() == 0 && "glReadPixels of FBO 0 in GL_RGBA+GL_UNSIGNED_BYTE format failed"); // Test the same with a floating point render target bound. GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint rb; glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 512, 512); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type); printf("GL_IMPLEMENTATION_COLOR_READ_TYPE for FBO with float renderbuffer: 0x%x\n", type); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format); printf("GL_IMPLEMENTATION_COLOR_READ_FORMAT for FBO with float renderbuffer: 0x%x\n", format); // Try glReadPixels() in that format. if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { printf("Oops, WebGL implementation returns an implementation defined color type(==GL_UNSIGNED_BYTE) & format(==GL_RGBA) that should " "not be possible to be used to sample WebGL floating point color renderbuffer according to WEBGL_color_buffer_float.\n"); } while (glGetError() != 0); glReadPixels(0, 0, 1, 1, format, type, &data); if (glGetError() != 0) printf("glReadPixels of FBO with floating point color renderbuffer in implementation defined format failed"); // Try glReadPixels() in the format that is mandated to work by the spec. WEBGL_color_buffer_float says // that GL_RGBA and GL_UNSIGNED_BYTE no longer work but instead GL_RGBA and GL_FLOAT must be used. glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, &data); assert(glGetError() == 0 && "glReadPixels of FBO with floating point color renderbuffer in GL_RGBA+GL_FLOAT format failed"); #ifdef REPORT_RESULT int result = 0; REPORT_RESULT(); #endif }
RBO &RBO::bind() { glBindRenderbuffer(GL_RENDERBUFFER, rboID); return *this; }
int main() { GLsizei multiSamples = 8; GLFWwindow* window = initWindow(); if (window == nullptr) { std::cout << "Unable to initialize window." << std::endl; return -1; } // Start the timer GLfloat deltaTime, lastFrame, currentFrame; lastFrame = 0.0f; currentFrame = 0.0f; // Setup the viewport; GLfloat screenWidth = 800, screenHeight = 600; glViewport(0, 0, screenWidth, screenHeight); // Setup Camera Camera cam = initCamera(); glfwSetWindowUserPointer(window, &cam); // Load Models Model planet = Model("./Models/planet/planet.obj"); Model asteroid = Model("./Models/rock/rock.obj"); // Load and Compile Shaders GLuint program = compileShaders("../OpenGL3-3/shaders/advanced/instance/basic.vert.glsl", "../OpenGL3-3/shaders/advanced/instance/basic.frag.glsl"); GLuint modelShader = compileShaders("../OpenGL3-3/shaders/newModel/model.vert.glsl", "../OpenGL3-3/shaders/newModel/model.frag.glsl"); GLuint instancedModelShader = compileShaders("../OpenGL3-3/shaders/newModel/imodel.vert.glsl", "../OpenGL3-3/shaders/newModel/model.frag.glsl"); GLuint frameBufferShader = compileShaders("../OpenGL3-3/shaders/advanced/fbo.vert.glsl", "../OpenGL3-3/shaders/advanced/fbo.frag.glsl"); // Setup MVP model glm::mat4 model, view, proj; view = cam.GetViewMatrix(); proj = glm::perspective(glm::radians(45.0f), (float)screenWidth / (float)screenHeight, 0.1f, 1000.0f); #pragma region quad GLfloat quadVertices[] = { // Positions // Colors -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 0.05f, 0.05f, 0.0f, 1.0f, 1.0f }; glm::vec2 translations[100]; int index = 0; GLfloat offset = 0.1f; for (GLint y = -10; y < 10; y += 2) { for (GLint x = -10; x < 10; x += 2) { glm::vec2 translation; translation.x = (GLfloat)x / 10.0f + offset; translation.y = (GLfloat)y / 10.0f + offset; translations[index++] = translation; } } GLfloat fboQuad[] = { -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, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f }; #pragma endregion GLuint VBO, VAO, instanceVBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &instanceVBO); glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 100, &translations[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // Create the Framebuffer GLuint FBO; glGenFramebuffers(1, &FBO); glBindFramebuffer(GL_FRAMEBUFFER, FBO); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, multiSamples, GL_RGB, screenWidth, screenHeight, GL_TRUE);// , GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture, 0); GLuint sampleRBO; glGenRenderbuffers(1, &sampleRBO); glBindRenderbuffer(GL_RENDERBUFFER, sampleRBO); glRenderbufferStorageMultisample(GL_RENDERBUFFER, multiSamples, GL_DEPTH24_STENCIL8, screenWidth, screenHeight); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, sampleRBO); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "FRAMEBUFFER INCOMPLETE!" << std::endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); GLuint regularFBO; glGenFramebuffers(1, ®ularFBO); glBindFramebuffer(GL_FRAMEBUFFER, regularFBO); GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "FRAMEBUFFER 2 INCOMPLETE!" << std::endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); GLuint fboVAO, fboVBO; glGenVertexArrays(1, &fboVAO); glGenBuffers(1, &fboVBO); glBindVertexArray(fboVAO); glBindBuffer(GL_ARRAY_BUFFER, fboVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(fboQuad), fboQuad, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2*sizeof(GLfloat))); glBindVertexArray(0); glBindVertexArray(VAO); { glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLvoid*)(sizeof(GLfloat) * 2)); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribDivisor(2, 1); } glBindVertexArray(0); std::cout << sizeof(glm::mat4) << std::endl; const int amount = 100000; glm::mat4* modelMats; modelMats = new glm::mat4[amount]; srand(glfwGetTime()); GLfloat radius = 150.0f; offset = 25.0f; for (GLuint i = 0; i < amount; i++) { glm::mat4 model; GLfloat angle = (GLfloat)i / (GLfloat)amount * 360.0f; GLfloat displacement = (rand() % (GLint)(2 * offset)) / 100.0f - offset; GLfloat x = sin(angle) * radius + displacement; displacement = (rand() % (GLint)(2 * offset * 100)) / 100.0f - offset; GLfloat y = displacement * 0.4f; displacement = (rand() % (GLint)(2 * offset * 100)) / 100.0f - offset; GLfloat z = cos(angle) * radius + displacement; model = glm::translate(model, glm::vec3(x, y, z)); GLfloat scale = (rand() % 20) / 100.0f + 0.05f; model = glm::scale(model, glm::vec3(scale)); GLfloat rotAngle = (rand() % 360); model = glm::rotate(model, rotAngle, glm::vec3(0.4f, 0.6f, 0.8f)); modelMats[i] = model; } for (GLuint i = 0; i < asteroid.meshes.size(); i++) { GLuint VAO = asteroid.meshes[i].VAO; GLuint buffer; glBindVertexArray(VAO); glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMats[0], GL_STATIC_DRAW); GLsizei vec4Size = sizeof(glm::vec4); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)0); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(vec4Size)); glEnableVertexAttribArray(5); glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(2 * vec4Size)); glEnableVertexAttribArray(6); glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(3 * vec4Size)); glVertexAttribDivisor(3, 1); glVertexAttribDivisor(4, 1); glVertexAttribDivisor(5, 1); glVertexAttribDivisor(6, 1); glBindVertexArray(0); } glUseProgram(modelShader); glUniformMatrix4fv(glGetUniformLocation(modelShader, "projection"), 1, GL_FALSE, glm::value_ptr(proj)); glUseProgram(instancedModelShader); glUniformMatrix4fv(glGetUniformLocation(instancedModelShader, "projection"), 1, GL_FALSE, glm::value_ptr(proj)); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glBindFramebuffer(GL_FRAMEBUFFER, FBO); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); handleMovement(window, deltaTime); glUseProgram(instancedModelShader); glUniformMatrix4fv(glGetUniformLocation(instancedModelShader, "view"), 1, GL_FALSE, glm::value_ptr(cam.GetViewMatrix())); glUseProgram(modelShader); glUniformMatrix4fv(glGetUniformLocation(modelShader, "view"), 1, GL_FALSE, glm::value_ptr(cam.GetViewMatrix())); glm::mat4 model; model = glm::translate(model, glm::vec3(0.0f, -5.0f, 0.0f)); model = glm::scale(model, glm::vec3(4.0f)); glUniformMatrix4fv(glGetUniformLocation(modelShader, "model"), 1, GL_FALSE, glm::value_ptr(model)); planet.draw(modelShader); glUseProgram(instancedModelShader); glBindTexture(GL_TEXTURE_2D, asteroid.textures_loaded[0].id); for (GLuint i = 0; i < asteroid.meshes.size(); i++) { glBindVertexArray(asteroid.meshes[i].VAO); glDrawElementsInstanced(GL_TRIANGLES, asteroid.meshes[i].vertices.size(), GL_UNSIGNED_INT, 0, amount); glBindVertexArray(0); } glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, regularFBO); glBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glUseProgram(frameBufferShader); glBindVertexArray(fboVAO); glBindTexture(GL_TEXTURE_2D, tex); //glUniform1i(glGetUniformLocation(frameBufferShader, "myTexture"), 0); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); glfwSwapBuffers(window); } glfwTerminate(); return 0; }
RBO &RBO::unbind() { glBindRenderbuffer(GL_RENDERBUFFER, 0); return *this; }
bool Framebuffer::init(unsigned int width, unsigned int height, unsigned int layerNumber) { // todo clear all if allready initilized _width = width; _height = height; _layerNumber = layerNumber; glGenFramebuffers(1, &_handle); glBindFramebuffer(GL_FRAMEBUFFER, _handle); _layers = new unsigned int[_layerNumber]; glGenTextures(_layerNumber, _layers); for (unsigned int i = 0; i < _layerNumber; ++i) { _layerNames.push_back("layer" + std::to_string(i)); glBindTexture(GL_TEXTURE_2D, _layers[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum)(GL_COLOR_ATTACHMENT0 + i), GL_TEXTURE_2D, _layers[i], 0); } glBindTexture(GL_TEXTURE_2D, 0); glGenRenderbuffers(1, &_depth); glBindRenderbuffer(GL_RENDERBUFFER, _depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, _width, _height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth); glBindRenderbuffer(GL_RENDERBUFFER, 0); if (!checkStatus()) return false; glBindFramebuffer(GL_FRAMEBUFFER, 0); // x,y vertex positions float ss_quad_pos[] = { -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0 }; // per-vertex texture coordinates float ss_quad_st[] = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0 }; unsigned int indice[] = {0,1,2,3,4,5}; _vbo.init(6, &indice[0]); _vbo.addAttribute(OpenGLTools::Attribute(sizeof(float) * 2, 2, GL_FLOAT)); _vbo.addAttribute(OpenGLTools::Attribute(sizeof(float) * 2, 2, GL_FLOAT)); _vbo.setBuffer(0, reinterpret_cast<byte *>(&ss_quad_pos)); _vbo.setBuffer(1, reinterpret_cast<byte *>(&ss_quad_st)); return true; }
void Effects::setup(int w, int h) { width = w; height = h; cracks.setup(w,h); // create fbo glGenFramebuffers(1, &fbo_handle); eglGetError(); glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle); // create texture. glGenTextures(1, &fbo_tex); eglGetError(); glActiveTexture(GL_TEXTURE0); eglGetError(); glBindTexture(GL_TEXTURE_2D, fbo_tex); eglGetError(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); eglGetError(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); eglGetError(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); eglGetError(); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0); eglGetError(); glGenRenderbuffers(1, &fbo_depth); eglGetError(); // render buffer glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); eglGetError(); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); eglGetError(); GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, drawbufs); glBindFramebuffer(GL_FRAMEBUFFER, 0); if(!shader.load("effects/effects")) { printf("Error loading effects shader.\n"); } vertices[0].setPos(-1, -1, 0); vertices[1].setPos(1, -1, 0); vertices[2].setPos(1, 1, 0); vertices[3].setPos(-1, 1, 0); float mw = 1; float mh = 1; vertices[0].setTex(0, 0); vertices[1].setTex(mw, 0); vertices[2].setTex(mw, mh); vertices[3].setTex(0, mh); glGenVertexArraysAPPLE(1, &vao); eglGetError(); glBindVertexArrayAPPLE(vao); eglGetError(); GLint pos_attrib = glGetAttribLocation(shader.getProgram(), "pos"); GLint tex_attrib = glGetAttribLocation(shader.getProgram(), "tex"); glEnableVertexAttribArray(pos_attrib); glEnableVertexAttribArray(tex_attrib); glGenBuffers(1, &vbo); eglGetError(); glBindBuffer(GL_ARRAY_BUFFER, vbo); eglGetError(); glBufferData( GL_ARRAY_BUFFER ,sizeof(Vertex) * 4 ,vertices[0].pos ,GL_STATIC_DRAW ); eglGetError(); glVertexAttribPointer( pos_attrib ,3 ,GL_FLOAT ,GL_FALSE ,sizeof(Vertex) ,offsetof(Vertex, pos) ); glVertexAttribPointer( tex_attrib ,2 ,GL_FLOAT ,GL_FALSE ,sizeof(Vertex) ,(GLvoid*)offsetof(Vertex, tex) ); calcCenter(); unbind(); flip(false); mirror(false); crack(false); }
bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat eFormat, GLuint uDepthStencilFormat) { CCASSERT(eFormat != Texture2D::PixelFormat::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, &_oldFBO); // textures must be power of two squared unsigned int powW = 0; unsigned int powH = 0; if (Configuration::getInstance()->supportsNPOT()) { powW = w; powH = h; } else { powW = ccNextPOT(w); powH = ccNextPOT(h); } int dataLen = (int)(powW * powH * 4); data = malloc(dataLen); CC_BREAK_IF(! data); memset(data, 0, dataLen); _pixelFormat = eFormat; _texture = new 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 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 (uDepthStencilFormat != 0) { //create and attach depth buffer glGenRenderbuffers(1, &_depthRenderBufffer); glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBufffer); glRenderbufferStorage(GL_RENDERBUFFER, uDepthStencilFormat, (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 (uDepthStencilFormat == 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->setScaleY(-1); _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); bRet = true; } while (0); CC_SAFE_FREE(data); return bRet; }
/*!**************************************************************************** @Function InitView @Return bool true if no error occured @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLES2RenderToTexture::InitView() { // Find the largest square power of two texture that fits into the viewport m_i32TexSize = 1; int iSize = PVRT_MIN(PVRShellGet(prefWidth), PVRShellGet(prefHeight)); while (m_i32TexSize * 2 < iSize) m_i32TexSize *= 2; srand(PVRShellGetTime()); m_ui32Framenum = rand() % 5000; // Get the initial time m_ui32Time = PVRShellGetTime(); /* Initialize VBO data and load textures */ LoadVbos(); LoadTextures(); /* Load and compile the shaders & link programs */ CPVRTString ErrorStr; if (!LoadShaders(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } // Set the sampler2D uniforms to corresponding texture units glUniform1i(glGetUniformLocation(m_ShaderProgram.uiId, "sTexture"), 0); /* Initialize Print3D */ // Is the screen rotated? bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n"); return false; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); /* Create two handles for a frame buffer object. */ glGenFramebuffers(2, m_auiFbo); m_i32CurrentFbo = 1; /* Get the currently bound frame buffer object. On most platforms this just gives 0. */ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo); /* Attach the renderable objects (e.g. textures) to the frame buffer object now as they will stay attached to the frame buffer object even when it is not bound. */ // We have two FBOs so we're doing the same for each for(int i = 0; i < 2; ++i) { /* Firstly, to do anything with a frame buffer object we need to bind it. In the case below we are binding our frame buffer object to the frame buffer. */ glBindFramebuffer(GL_FRAMEBUFFER, m_auiFbo[i]); /* To render to a texture we need to attach it texture to the frame buffer object. GL_COLOR_ATTACHMENT0 tells it to attach the texture to the colour buffer, the 0 on the end refers to the colour buffer we want to attach it to as a frame buffer object can have more than one colour buffer. */ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_auiTexture[i], 0); // Clear the color buffer for this FBO glClear(GL_COLOR_BUFFER_BIT); /* Create and bind a depth buffer to the frame buffer object. A depth buffer isn't needed for this training course but will likely be required for most uses of frame buffer objects so its attachment is being demonstrated here. */ // Generate and bind the handle for the render buffer (which will become our depth buffer) glGenRenderbuffers(1, &m_auiDepthBuffer[i]); glBindRenderbuffer(GL_RENDERBUFFER, m_auiDepthBuffer[i]); /* Currently it is unknown to GL that we want our new render buffer to be a depth buffer. glRenderbufferStorage will fix this and in this case will allocate a depth buffer of m_i32TexSize by m_i32TexSize. */ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_i32TexSize, m_i32TexSize); // Now we have our depth buffer attach it to our frame buffer object. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_auiDepthBuffer[i]); } /* Unbind the frame buffer object so rendering returns back to the backbuffer. */ glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo); // Use a nice bright blue as clear colour glClearColor(0.6f, 0.8f, 1.0f, 1.0f); return true; }
CubeTextureFBO::CubeTextureFBO(unsigned int size, int format, GLuint targets, bool storeDepth) { this->size = size; this->store_depths = storeDepth; const GLenum faces[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; texture.resize(targets); // Initialize Texture glGenTextures(targets, &texture[0]); for (size_t i = 0; i < targets; i++) { glBindTexture(GL_TEXTURE_CUBE_MAP, texture[i]); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); for (size_t j = 0; j < 6; j++) { glTexImage2D(faces[j], 0, format, size, size, 0, GL_RGBA, GL_FLOAT, NULL); } } if(!storeDepth) { //Create depth bufferGLuint rboId; glGenRenderbuffers(1, &depth); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size); glBindRenderbuffer(GL_RENDERBUFFER, 0); } else { glGenTextures(targets, &depth); glBindTexture(GL_TEXTURE_CUBE_MAP, depth); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); for (size_t j = 0; j < 6; j++) { glTexImage2D(faces[j], 0, GL_DEPTH_COMPONENT24, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); } } // Create FBO and attach buffers glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (uint i = 0; i < targets; i++) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, texture[i], 0); } if (!storeDepth) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, depth, 0); } CHECK_GL_ERRORS(); CHECK_GL_FBO_COMPLETENESS(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, 0); }
static enum piglit_result exec_test(struct test_info *info, int sample_count) { GLuint fb, tex, rb; GLint result; struct attachment_info *att; GLint maxColorSamples, maxDepthSamples; glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorSamples); glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthSamples); glGenFramebuffers(1, &fb); glBindFramebuffer(GL_FRAMEBUFFER, fb); printf("Testing fbo completeness for config '%s'\n", info->name); for (att=info->attachments; att->target; att++) { int attachment_sample_count = att->multisample ? sample_count : 0; printf(" Att target=%s att=%s samples=%d dims=%d,%d,%d fixed=%d\n", piglit_get_gl_enum_name(att->target), piglit_get_gl_enum_name(att->attachment), attachment_sample_count, SURFACE_WIDTH, SURFACE_HEIGHT, att->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ? SURFACE_DEPTH : 1, att->fixedsamplelocations); switch (att->target) { case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: if (att->attachment == GL_DEPTH_ATTACHMENT && sample_count > maxDepthSamples) return PIGLIT_SKIP; if ((att->attachment == GL_COLOR_ATTACHMENT0 || att->attachment == GL_COLOR_ATTACHMENT1) && sample_count > maxColorSamples) return PIGLIT_SKIP; } switch (att->target) { case GL_TEXTURE_2D_MULTISAMPLE: glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, attachment_sample_count, choose_format(att), SURFACE_WIDTH, SURFACE_HEIGHT, att->fixedsamplelocations); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; glFramebufferTexture2D(GL_FRAMEBUFFER, att->attachment, att->target, tex, 0); break; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex); glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, attachment_sample_count, choose_format(att), SURFACE_WIDTH, SURFACE_HEIGHT, SURFACE_DEPTH, att->fixedsamplelocations); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; glFramebufferTextureLayer(GL_FRAMEBUFFER, att->attachment, tex, 0, att->layer); break; case GL_RENDERBUFFER: /* RENDERBUFFER has fixedsamplelocations implicitly */ assert(att->fixedsamplelocations); glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); if (att->multisample) { glRenderbufferStorageMultisample(GL_RENDERBUFFER, attachment_sample_count, choose_format(att), SURFACE_WIDTH, SURFACE_HEIGHT); } else { /* non-MSAA renderbuffer */ glRenderbufferStorage(GL_RENDERBUFFER, choose_format(att), SURFACE_WIDTH, SURFACE_HEIGHT); } glFramebufferRenderbuffer(GL_FRAMEBUFFER, att->attachment, att->target, rb); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; break; default: assert(!"Unsupported target"); } } result = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (result != info->expected) { printf("glCheckFramebufferStatus: expected %s, got %s\n", piglit_get_gl_enum_name(info->expected), piglit_get_gl_enum_name(result)); return PIGLIT_FAIL; } if (result == GL_FRAMEBUFFER_COMPLETE && info->attachments->multisample) return check_sample_positions(sample_count); return PIGLIT_PASS; }
void renderbuffer::activate() const { renderbuffer_internal *i = get<renderbuffer_internal>(); glBindRenderbuffer(GL_RENDERBUFFER, i->id); }
static FboDesc CreateSurfaces(GLsizei width, GLsizei height, int numComponents, int numTargets) { FboDesc surface; glGenFramebuffers(1, &surface.FboHandle); glBindFramebuffer(GL_FRAMEBUFFER, surface.FboHandle); for (int attachment = 0; attachment < numTargets; ++attachment) { GLuint textureHandle; glGenTextures(1, &textureHandle); glBindTexture(GL_TEXTURE_2D, textureHandle); 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); surface.TextureHandle[attachment] = textureHandle; switch (numComponents) { case 1: glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, 0); break; case 2: glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, width, height, 0, GL_RG, GL_FLOAT, 0); break; case 3: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, 0); break; case 4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); break; default: pezFatal("Illegal slab format."); } pezCheck(GL_NO_ERROR == glGetError(), "Unable to create FBO texture"); // glTexImage2DMultisample // GL_TEXTURE_2D_MULTISAMPLE // glRenderbufferStorageMultisample GLuint colorbuffer; glGenRenderbuffers(1, &colorbuffer); glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachment, GL_TEXTURE_2D, textureHandle, 0); pezCheck(GL_NO_ERROR == glGetError(), "Unable to attach color buffer"); } // Create a depth texture: glGenTextures(1, &surface.DepthTexture); glBindTexture(GL_TEXTURE_2D, surface.DepthTexture); 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0); pezCheck(GL_NO_ERROR == glGetError(), "Unable to create depth texture"); // Create a FBO and attach the depth texture: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, surface.DepthTexture, 0); pezCheck(GL_NO_ERROR == glGetError(), "Unable to attach depth texture"); pezCheck(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER), "Unable to create FBO."); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, 0); return surface; }
RenderingEngine2::RenderingEngine2() { glGenRenderbuffers(1, &m_renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer); }
bool RenderTargetTexture::Init(RenderTarget::Properties* props) { m_properties = *static_cast<RenderTargetTextureProperties*>(props); Clear(); // generate frame buffer glGenFramebuffers(1, &m_fb); // create color texture if (m_color_texture) safe_delete(m_color_texture); m_color_texture = new Texture2D; m_color_texture->Create(m_properties.m_texture_width, m_properties.m_texture_height, ImageModule::IMAGE_FORMAT_RGBA8, 0, false); // if multisample // generate render buffers glGenRenderbuffers(1, &m_depth_rb); glGenRenderbuffers(1, &m_color_rb); // generate resolve frame buffer glGenFramebuffers(1, &m_resolve_fb); // tune resolve frame buffer glBindFramebuffer(GL_FRAMEBUFFER, m_resolve_fb); // bind color texture glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture->GetCode(), 0); Check(); // tune render frame buffer glBindFramebuffer(GL_FRAMEBUFFER, m_fb); // tune color render buffer glBindRenderbuffer(GL_RENDERBUFFER, m_color_rb); int max_samples; glGetIntegerv(GL_MAX_SAMPLES, &max_samples); // for csaa some extra staff needed // create a regular MSAA color buffer glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_RGBA8, m_color_texture->GetWidth(), m_color_texture->GetHeight()); // check the number of samples glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &max_samples); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_rb); Check(); // tune depth render buffer glBindRenderbuffer(GL_RENDERBUFFER, m_depth_rb); // for csaa another method should be used // create a regular MSAA depth buffer glRenderbufferStorageMultisample(GL_RENDERBUFFER, max_samples, GL_DEPTH_COMPONENT24, m_color_texture->GetWidth(), m_color_texture->GetHeight()); // attach depth buffer to frame buffer glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth_rb); Check(); glBindFramebuffer(GL_FRAMEBUFFER, 0); return true; }
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples, bool mipmap) { QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); fbo_guard.setContext(ctx); bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx))) return; size = sz; target = texture_target; // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); fbo_guard.setId(fbo); glDevice.setFBO(q, attachment); QT_CHECK_GLERROR(); // init texture if (samples == 0) { glGenTextures(1, &texture); glBindTexture(target, texture); glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) glGenerateMipmap(GL_TEXTURE_2D); #ifndef QT_OPENGL_ES glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #else glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texture, 0); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); glBindTexture(target, 0); color_buffer = 0; } else { mipmap = false; GLint maxSamples; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); glGenRenderbuffers(1, &color_buffer); glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); if (glRenderbufferStorageMultisampleEXT && samples > 0) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internal_format, size.width(), size.height()); } else { samples = 0; glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format, size.width(), size.height()); } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); if (valid) glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); } // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer // might not be supported while separate buffers are, according to QTBUG-12861. if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); stencil_buffer = depth_buffer; glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); stencil_buffer = depth_buffer = 0; } } if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil || (attachment == QGLFramebufferObject::Depth))) { glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); depth_buffer = 0; } } if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { glGenRenderbuffers(1, &stencil_buffer); Q_ASSERT(!glIsRenderbuffer(stencil_buffer)); glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer); Q_ASSERT(glIsRenderbuffer(stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_STENCIL_INDEX8_EXT, size.width(), size.height()); #else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_STENCIL_INDEX, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, size.width(), size.height()); #else glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, size.width(), size.height()); #endif } glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &stencil_buffer); stencil_buffer = 0; } } // The FBO might have become valid after removing the depth or stencil buffer. valid = checkFramebufferStatus(); if (depth_buffer && stencil_buffer) { fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; } else if (depth_buffer) { fbo_attachment = QGLFramebufferObject::Depth; } else { fbo_attachment = QGLFramebufferObject::NoAttachment; } glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); if (!valid) { if (color_buffer) glDeleteRenderbuffers(1, &color_buffer); else glDeleteTextures(1, &texture); if (depth_buffer) glDeleteRenderbuffers(1, &depth_buffer); if (stencil_buffer && depth_buffer != stencil_buffer) glDeleteRenderbuffers(1, &stencil_buffer); glDeleteFramebuffers(1, &fbo); fbo_guard.setId(0); } QT_CHECK_GLERROR(); format.setTextureTarget(target); format.setSamples(int(samples)); format.setAttachment(fbo_attachment); format.setInternalTextureFormat(internal_format); format.setMipmap(mipmap); }
GLUSuint initWaterTexture(GLUSfloat waterPlaneLength) { GLfloat projectionMatrixWaterTexture[16]; GLfloat modelViewMatrixWaterTexture[16]; GLUSshape plane; GLUStextfile vertexSource; GLUStextfile fragmentSource; glusFileLoadText("../Example15/shader/WaterTexture.vert.glsl", &vertexSource); glusFileLoadText("../Example15/shader/WaterTexture.frag.glsl", &fragmentSource); glusProgramBuildFromSource(&g_programWaterTexture, (const GLUSchar**) &vertexSource.text, 0, 0, 0, (const GLUSchar**) &fragmentSource.text); glusFileDestroyText(&vertexSource); glusFileDestroyText(&fragmentSource); // g_projectionMatrixWaterTextureLocation = glGetUniformLocation(g_programWaterTexture.program, "u_projectionMatrix"); g_modelViewMatrixWaterTextureLocation = glGetUniformLocation(g_programWaterTexture.program, "u_modelViewMatrix"); g_waterPlaneLengthWaterTextureLocation = glGetUniformLocation(g_programWaterTexture.program, "u_waterPlaneLength"); g_passedTimeWaterTextureLocation = glGetUniformLocation(g_programWaterTexture.program, "u_passedTime"); g_waveParametersWaterTextureLocation = glGetUniformLocation(g_programWaterTexture.program, "u_waveParameters"); g_waveDirectionsWaterTextureLocation = glGetUniformLocation(g_programWaterTexture.program, "u_waveDirections"); g_vertexWaterTextureLocation = glGetAttribLocation(g_programWaterTexture.program, "a_vertex"); g_texCoordWaterTextureLocation = glGetAttribLocation(g_programWaterTexture.program, "a_texCoord"); // glGenTextures(1, &g_mirrorTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, g_mirrorTexture); glTexImage2D(GL_TEXTURE_2D, 0, GLUS_RGB, TEXTURE_SIZE, TEXTURE_SIZE, 0, GLUS_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); // glGenRenderbuffers(1, &g_depthMirrorTexture); glBindRenderbuffer(GL_RENDERBUFFER, g_depthMirrorTexture); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_SIZE, TEXTURE_SIZE); glBindRenderbuffer(GL_RENDERBUFFER, 0); // glGenFramebuffers(1, &g_fboWaterTexture); glBindFramebuffer(GL_FRAMEBUFFER, g_fboWaterTexture); // Attach the color buffer ... glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_mirrorTexture, 0); // ... and the depth buffer, glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_depthMirrorTexture); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("GL_FRAMEBUFFER_COMPLETE error 0x%x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); return GLUS_FALSE; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // glBindVertexArray(0); // glusShapeCreatePlanef(&plane, TEXTURE_SIZE / 2.0f); g_numberIndicesWaterTexture = plane.numberIndices; glGenBuffers(1, &g_verticesWaterTextureVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesWaterTextureVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 4 * sizeof(GLfloat), (GLfloat*) plane.vertices, GL_STATIC_DRAW); glGenBuffers(1, &g_texCoordsWaterTextureVBO); glBindBuffer(GL_ARRAY_BUFFER, g_texCoordsWaterTextureVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 2 * sizeof(GLfloat), (GLfloat*) plane.texCoords, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &g_indicesWaterTextureVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesWaterTextureVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, plane.numberIndices * sizeof(GLuint), (GLuint*) plane.indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glusShapeDestroyf(&plane); // glUseProgram(g_programWaterTexture.program); glusMatrix4x4LookAtf(modelViewMatrixWaterTexture, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); glUniformMatrix4fv(g_modelViewMatrixWaterTextureLocation, 1, GL_FALSE, modelViewMatrixWaterTexture); glusMatrix4x4Orthof(projectionMatrixWaterTexture, -(GLfloat) TEXTURE_SIZE / 2, (GLfloat) TEXTURE_SIZE / 2, -(GLfloat) TEXTURE_SIZE / 2, (GLfloat) TEXTURE_SIZE / 2, 1.0f, 100.0f); glUniformMatrix4fv(g_projectionMatrixWaterTextureLocation, 1, GL_FALSE, projectionMatrixWaterTexture); glUniform1f(g_waterPlaneLengthWaterTextureLocation, waterPlaneLength); // glGenVertexArrays(1, &g_vaoWaterTexture); glBindVertexArray(g_vaoWaterTexture); glBindBuffer(GL_ARRAY_BUFFER, g_verticesWaterTextureVBO); glVertexAttribPointer(g_vertexWaterTextureLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexWaterTextureLocation); glBindBuffer(GL_ARRAY_BUFFER, g_texCoordsWaterTextureVBO); glVertexAttribPointer(g_texCoordWaterTextureLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_texCoordWaterTextureLocation); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesWaterTextureVBO); // glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); return g_mirrorTexture; }