/* MapPreviewCanvas::createImage * Draws the map in an image * TODO: Factorize code with normal draw() and showMap() functions. * TODO: Find a way to generate an arbitrary-sized image through * tiled rendering. *******************************************************************/ void MapPreviewCanvas::createImage(ArchiveEntry& ae, int width, int height) { // Find extents of map mep_vertex_t m_min(999999.0, 999999.0); mep_vertex_t m_max(-999999.0, -999999.0); for (unsigned a = 0; a < verts.size(); a++) { if (verts[a].x < m_min.x) m_min.x = verts[a].x; if (verts[a].x > m_max.x) m_max.x = verts[a].x; if (verts[a].y < m_min.y) m_min.y = verts[a].y; if (verts[a].y > m_max.y) m_max.y = verts[a].y; } double mapwidth = m_max.x - m_min.x; double mapheight = m_max.y - m_min.y; if (width == 0) width = -5; if (height == 0) height = -5; if (width < 0) width = mapwidth / abs(width); if (height < 0) height = mapheight / abs(height); // Setup colours wxColour wxc; wxc.Set(map_image_col_background); rgba_t col_save_background(wxc.Red(), wxc.Green(), wxc.Blue(), 255); wxc.Set(map_image_col_line_1s); rgba_t col_save_line_1s(wxc.Red(), wxc.Green(), wxc.Blue(), 255); wxc.Set(map_image_col_line_2s); rgba_t col_save_line_2s(wxc.Red(), wxc.Green(), wxc.Blue(), 255); wxc.Set(map_image_col_line_special); rgba_t col_save_line_special(wxc.Red(), wxc.Green(), wxc.Blue(), 255); wxc.Set(map_image_col_line_macro); rgba_t col_save_line_macro(wxc.Red(), wxc.Green(), wxc.Blue(), 255); col_save_background.a = map_image_alpha_background; // Setup OpenGL rigmarole GLuint texID, fboID; if (GLEW_ARB_framebuffer_object) { glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); // We don't use mipmaps, but OpenGL will refuse to attach // the texture to the framebuffer if they are not present glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffersEXT(1, &fboID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texID, 0); GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); } glViewport(0, 0, width, height); // Setup the screen projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, 0, height, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Clear glClearColor(((double)col_save_background.r)/255.f, ((double)col_save_background.g)/255.f, ((double)col_save_background.b)/255.f, ((double)col_save_background.a)/255.f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Translate to inside of pixel (otherwise inaccuracies can occur on certain gl implementations) if (OpenGL::accuracyTweak()) glTranslatef(0.375f, 0.375f, 0); // Zoom/offset to show full map // Offset to center of map offset_x = m_min.x + (mapwidth * 0.5); offset_y = m_min.y + (mapheight * 0.5); // Zoom to fit whole map double x_scale = ((double)width) / mapwidth; double y_scale = ((double)height) / mapheight; zoom = MIN(x_scale, y_scale); zoom *= 0.95; // Translate to middle of canvas glTranslated(width>>1, height>>1, 0); // Zoom glScaled(zoom, zoom, 1); // Translate to offset glTranslated(-offset_x, -offset_y, 0); // Setup drawing glDisable(GL_TEXTURE_2D); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glLineWidth(map_image_thickness); glEnable(GL_LINE_SMOOTH); // Draw lines for (unsigned a = 0; a < lines.size(); a++) { mep_line_t line = lines[a]; // Check ends if (line.v1 >= verts.size() || line.v2 >= verts.size()) continue; // Get vertices mep_vertex_t v1 = verts[lines[a].v1]; mep_vertex_t v2 = verts[lines[a].v2]; // Set colour if (line.special) OpenGL::setColour(col_save_line_special); else if (line.macro) OpenGL::setColour(col_save_line_macro); else if (line.twosided) OpenGL::setColour(col_save_line_2s); else OpenGL::setColour(col_save_line_1s); // Draw line glBegin(GL_LINES); glVertex2d(v1.x, v1.y); glVertex2d(v2.x, v2.y); glEnd(); } glLineWidth(1.0f); glDisable(GL_LINE_SMOOTH); uint8_t* ImageBuffer = new uint8_t[width * height * 4]; glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ImageBuffer); if (GLEW_ARB_framebuffer_object) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteTextures( 1, &texID ); glDeleteFramebuffersEXT( 1, &fboID ); } SImage img; img.setImageData(ImageBuffer, width, height, RGBA); img.mirror(true); MemChunk mc; SIFormat::getFormat("png")->saveImage(img, mc); ae.importMemChunk(mc); }
void WaterSurface::init() { // init textures & buffers //textureManager->loadTexture(...); dudv_ID = textureManager->loadTexture(WATER_DUDV_MAP, "water_dudvmap", 3, false, GL_REPEAT, GL_LINEAR); glGenTextures(1, &cb_refl_ID); glBindTexture(GL_TEXTURE_2D, cb_refl_ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_WinWidth, g_WinHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glGenTextures(1, &db_refl_ID ); glBindTexture(GL_TEXTURE_2D, db_refl_ID ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, g_WinWidth, g_WinHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glGenFramebuffersEXT(1, &fb_refl_ID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_refl_ID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, cb_refl_ID, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, db_refl_ID, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glGenTextures(1, &cb_refr_ID); glBindTexture(GL_TEXTURE_2D, cb_refr_ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_WinWidth, g_WinHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glGenTextures(1, &db_refr_ID ); glBindTexture(GL_TEXTURE_2D, db_refr_ID ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, g_WinWidth, g_WinHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glGenFramebuffersEXT(1, &fb_refr_ID); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_refr_ID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, cb_refr_ID, 0); //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, color_tex1_id, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, db_refr_ID, 0); assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)==GL_FRAMEBUFFER_COMPLETE_EXT); assert( glGetError() == GL_NO_ERROR ); // init shaders... int shaderID = shaderManager->loadShader("Water", WATER_VS_FILENAME, WATER_FS_FILENAME); shader = shaderManager->getShader(shaderID); water_reflection_loc = shader->getLocation("water_reflection"); water_refraction_loc = shader->getLocation("water_refraction"); water_depth_loc = shader->getLocation("water_depthmap"); shader->linkTexture(textureManager->getTexture(dudv_ID)); }
void DiGLFBOManager::DetectFBOFormats() { // Try all formats, and report which ones work as target GLuint fb = 0, tid = 0; GLint old_drawbuffer = 0, old_readbuffer = 0; GLenum target = GL_TEXTURE_2D; glGetIntegerv(GL_DRAW_BUFFER, &old_drawbuffer); glGetIntegerv(GL_READ_BUFFER, &old_readbuffer); for (uint32 x = 0; x < PIXEL_FORMAT_MAX; ++x) { mProps[x].valid = false; GLenum fmt = DiGLTypeMappings::GLInternalFormatMapping[(DiPixelFormat)x]; if (fmt == GL_NONE && x != 0) continue; if (DiPixelBox::IsCompressedFormat((DiPixelFormat)x)) continue; // Buggy ATI cards *crash* on non-RGB(A) formats int depths[4]; DiPixelBox::GetBitDepths((DiPixelFormat)x, depths); if (fmt != GL_NONE && mATIMode && (!depths[0] || !depths[1] || !depths[2])) continue; // Create and attach framebuffer glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); if (fmt != GL_NONE) { // Create and attach texture glGenTextures(1, &tid); glBindTexture(target, tid); // Set some default parameters so it won't fail on NVidia cards if (GLEW_VERSION_1_2) glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0); 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); glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, tid, 0); } else { // Draw to nowhere -- stencil/depth only glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } // Check status GLuint status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Ignore status in case of fmt==GL_NONE, because no implementation will accept // a buffer without *any* attachment. Buffers with only stencil and depth attachment // might still be supported, so we must continue probing. if (fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE_EXT) { mProps[x].valid = true; // For each depth/stencil formats for (size_t depth = 0; depth < DEPTHFORMAT_COUNT; ++depth) { if (depthFormats[depth] != GL_DEPTH24_STENCIL8_EXT) { // General depth/stencil combination for (size_t stencil = 0; stencil < STENCILFORMAT_COUNT; ++stencil) { if (TryFormat(depthFormats[depth], stencilFormats[stencil])) { /// Add mode to allowed modes FormatProperties::Mode mode; mode.depth = depth; mode.stencil = stencil; mProps[x].modes.push_back(mode); } } } else { if (TryPackedFormat(depthFormats[depth])) { /// Add mode to allowed modes FormatProperties::Mode mode; mode.depth = depth; mode.stencil = 0; mProps[x].modes.push_back(mode); } } } } // Delete texture and framebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDeleteFramebuffersEXT(1, &fb); // Workaround for NVIDIA / Linux 169.21 driver problem // see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25 glFinish(); if (fmt != GL_NONE) glDeleteTextures(1, &tid); } // It seems a bug in nVidia driver: glBindFramebufferEXT should restore // draw and read buffers, but in some unclear circumstances it won't. glDrawBuffer(old_drawbuffer); glReadBuffer(old_readbuffer); for (size_t x = 0; x < PIXEL_FORMAT_MAX; ++x) { if (mProps[x].valid) { DI_INFO("Valid format for FBO targets: %s", DiPixelBox::GetPixelTypeName((DiPixelFormat)x).c_str()); } } }
enum piglit_result piglit_display(void) { static const char *frag_src = "!!ARBfp1.0\n" "TEX result.color, fragment.texcoord[0], texture[0], 2D;\n" "END"; static const struct { int x; int y; float color[3]; } expected[] = { { 64, 240, {0.1f, 0.1f, 0.1f}}, { 192, 240, {0.3f, 0.3f, 0.3f}}, { 320, 240, {0.5f, 0.5f, 0.5f}}, { 448, 240, {0.7f, 0.7f, 0.7f}}, { 576, 240, {0.9f, 0.9f, 0.9f}}, }; GLuint fbo, frag, db_tex, cb_tex; GLboolean pass = GL_TRUE; char *tex_data; unsigned int i; frag = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB, frag_src); glGenFramebuffersEXT(1, &fbo); glGenTextures(1, &cb_tex); glGenTextures(1, &db_tex); tex_data = calloc(piglit_width * piglit_height, 4); glBindTexture(GL_TEXTURE_2D, db_tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, piglit_width, piglit_height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, tex_data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, cb_tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, piglit_width, piglit_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, tex_data); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); free(tex_data); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, db_tex, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, cb_tex, 0); check_fbo_status(); glViewport(0, 0, piglit_width, piglit_height); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); glDepthMask(GL_TRUE); /* Draw with the texture to make sure a sampler view is created for * it before it's used as depth buffer by the FBO. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); glBindTexture(GL_TEXTURE_2D, db_tex); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag); glEnable(GL_FRAGMENT_PROGRAM_ARB); glEnable(GL_TEXTURE_2D); piglit_draw_rect_tex(-1.0f, -1.0f, 2.0f, 2.0f, 0.0f, 0.0f, 1.0f, 1.0f); /* Fill the depth buffer with a gradient. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); check_fbo_status(); glDisable(GL_FRAGMENT_PROGRAM_ARB); glDisable(GL_TEXTURE_2D); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClearDepth(0.5f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.0f, 1.0f, 1.0f); glBegin(GL_TRIANGLE_STRIP); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glEnd(); /* Draw the depth texture as greyscale to the backbuffer. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); glEnable(GL_FRAGMENT_PROGRAM_ARB); glEnable(GL_TEXTURE_2D); piglit_draw_rect_tex(-1.0f, -1.0f, 2.0f, 2.0f, 0.0f, 0.0f, 1.0f, 1.0f); for (i = 0; i < sizeof(expected) / sizeof(*expected); ++i) { pass &= piglit_probe_pixel_rgb(expected[i].x, expected[i].y, expected[i].color); } piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void GPUVolRTV2::enable_renderbuffers() { glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer); }
bool BMDOpenGLOutput::Start() { IDeckLinkDisplayModeIterator* pDLDisplayModeIterator; IDeckLinkDisplayMode* pDLDisplayMode = NULL; // Get first avaliable video mode for Output if (pDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) == S_OK) { if (pDLDisplayModeIterator->Next(&pDLDisplayMode) != S_OK) { QMessageBox::critical(NULL,"DeckLink error.", "Cannot find video mode."); pDLDisplayModeIterator->Release(); return false; } pDLDisplayModeIterator->Release(); } uiFrameWidth = pDLDisplayMode->GetWidth(); uiFrameHeight = pDLDisplayMode->GetHeight(); pDLDisplayMode->GetFrameRate(&frameDuration, &frameTimescale); uiFPS = ((frameTimescale + (frameDuration-1)) / frameDuration); if (pDLOutput->EnableVideoOutput(pDLDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK) return false; // Flip frame vertical, because OpenGL rendering starts from left bottom corner if (pDLOutput->CreateVideoFrame(uiFrameWidth, uiFrameHeight, uiFrameWidth*4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &pDLVideoFrame) != S_OK) return false; uiTotalFrames = 0; ResetFrame(); SetPreroll(); pContext->makeCurrent(); pGLScene->InitScene(); glGenFramebuffersEXT(1, &idFrameBuf); glGenRenderbuffersEXT(1, &idColorBuf); glGenRenderbuffersEXT(1, &idDepthBuf); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, idFrameBuf); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, idColorBuf); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, uiFrameWidth, uiFrameHeight); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, idDepthBuf); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, uiFrameWidth, uiFrameHeight); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, idColorBuf); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, idDepthBuf); glStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (glStatus != GL_FRAMEBUFFER_COMPLETE_EXT) { QMessageBox::critical(NULL,"OpenGL initialization error.", "Cannot initialize framebuffer."); return false; } pFrameBuf = (char*)malloc(pDLVideoFrame->GetRowBytes() * uiFrameHeight); UpdateScene(); pDLOutput->StartScheduledPlayback(0, 100, 1.0); return true; }
void FrameBufferObject::bind() { EQ_TS_THREAD( _thread ); EQASSERT( _fboID ); EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID )); }
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels) { const int w = GPU_texture_width(ofs->color); const int h = GPU_texture_height(ofs->color); if (GPU_texture_target(ofs->color) == GL_TEXTURE_2D_MULTISAMPLE) { /* For a multi-sample texture, * we need to create an intermediate buffer to blit to, * before its copied using 'glReadPixels' */ /* not needed since 'ofs' needs to be bound to the framebuffer already */ // #define USE_FBO_CTX_SWITCH GLuint fbo_blit = 0; GLuint tex_blit = 0; GLenum status; /* create texture for new 'fbo_blit' */ glGenTextures(1, &tex_blit); if (!tex_blit) { goto finally; } glBindTexture(GL_TEXTURE_2D, tex_blit); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, type, 0); #ifdef USE_FBO_CTX_SWITCH /* read from multi-sample buffer */ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, ofs->color->fb->object); glFramebufferTexture2DEXT( GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + ofs->color->fb_attachment, GL_TEXTURE_2D_MULTISAMPLE, ofs->color->bindcode, 0); status = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { goto finally; } #endif /* write into new single-sample buffer */ glGenFramebuffersEXT(1, &fbo_blit); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo_blit); glFramebufferTexture2DEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex_blit, 0); status = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { goto finally; } /* perform the copy */ glBlitFramebufferEXT(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); /* read the results */ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fbo_blit); glReadPixels(0, 0, w, h, GL_RGBA, type, pixels); #ifdef USE_FBO_CTX_SWITCH /* restore the original frame-bufer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ofs->color->fb->object); #undef USE_FBO_CTX_SWITCH #endif finally: /* cleanup */ if (tex_blit) { glDeleteTextures(1, &tex_blit); } if (fbo_blit) { glDeleteFramebuffersEXT(1, &fbo_blit); } GPU_ASSERT_NO_GL_ERRORS("Read Multi-Sample Pixels"); } else { glReadPixels(0, 0, w, h, GL_RGBA, type, pixels); } }
bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, size_t bufferSize) { if (bufferSize != static_cast<size_t>(4 * width() * height())) return false; makeContextCurrent(); #ifdef RENDER_TO_DEBUGGING_WINDOW SwapBuffers(m_canvasDC); #else // Earlier versions of this code used the GPU to flip the // framebuffer vertically before reading it back for compositing // via software. This code was quite complicated, used a lot of // GPU memory, and didn't provide an obvious speedup. Since this // vertical flip is only a temporary solution anyway until Chrome // is fully GPU composited, it wasn't worth the complexity. bool mustRestoreFBO; if (m_attributes.antialias) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); mustRestoreFBO = true; } else { if (m_boundFBO != m_fbo) { mustRestoreFBO = true; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } } GLint packAlignment = 4; bool mustRestorePackAlignment = false; glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); if (packAlignment > 4) { glPixelStorei(GL_PACK_ALIGNMENT, 4); mustRestorePackAlignment = true; } #if PLATFORM(SKIA) glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); #elif PLATFORM(CG) glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); #else #error Must port to your platform #endif if (mustRestorePackAlignment) glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); if (mustRestoreFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); #ifdef FLIP_FRAMEBUFFER_VERTICALLY if (pixels) flipVertically(pixels, m_cachedWidth, m_cachedHeight); #endif #endif // RENDER_TO_DEBUGGING_WINDOW return true; }
void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) { #ifdef RENDER_TO_DEBUGGING_WINDOW SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height, SWP_NOMOVE); ShowWindow(m_canvasWindow, SW_SHOW); #endif m_cachedWidth = width; m_cachedHeight = height; makeContextCurrent(); #ifndef RENDER_TO_DEBUGGING_WINDOW #ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X GLenum target = GL_TEXTURE_RECTANGLE_ARB; #else GLenum target = GL_TEXTURE_2D; #endif if (!m_texture) { // Generate the texture object m_texture = createTextureObject(target); // Generate the framebuffer object glGenFramebuffersEXT(1, &m_fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); m_boundFBO = m_fbo; if (m_attributes.depth || m_attributes.stencil) glGenRenderbuffersEXT(1, &m_depthStencilBuffer); // Generate the multisample framebuffer object if (m_attributes.antialias) { glGenFramebuffersEXT(1, &m_multisampleFBO); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); m_boundFBO = m_multisampleFBO; glGenRenderbuffersEXT(1, &m_multisampleColorBuffer); if (m_attributes.depth || m_attributes.stencil) glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); } } GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; if (m_attributes.alpha) { internalColorFormat = GL_RGBA8; colorFormat = GL_RGBA; } else { internalColorFormat = GL_RGB8; colorFormat = GL_RGB; } if (m_attributes.stencil || m_attributes.depth) { // We don't allow the logic where stencil is required and depth is not. // See GraphicsContext3DInternal constructor. if (m_attributes.stencil && m_attributes.depth) internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; else internalDepthStencilFormat = GL_DEPTH_COMPONENT; } bool mustRestoreFBO = false; // Resize multisampling FBO if (m_attributes.antialias) { GLint maxSampleCount; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); GLint sampleCount = std::min(8, maxSampleCount); if (m_boundFBO != m_multisampleFBO) { mustRestoreFBO = true; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); } glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); if (m_attributes.stencil || m_attributes.depth) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); if (m_attributes.stencil) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); if (m_attributes.depth) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); } glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { printf("GraphicsContext3D: multisampling framebuffer was incomplete\n"); // FIXME: cleanup. notImplemented(); } } // Resize regular FBO if (m_boundFBO != m_fbo) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); mustRestoreFBO = true; } glBindTexture(target, m_texture); glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0); glBindTexture(target, 0); if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); if (m_attributes.stencil) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); if (m_attributes.depth) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { printf("WebGraphicsContext3DDefaultImpl: framebuffer was incomplete\n"); // FIXME: cleanup. notImplemented(); } if (mustRestoreFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); #endif // RENDER_TO_DEBUGGING_WINDOW #ifdef FLIP_FRAMEBUFFER_VERTICALLY if (m_scanline) { delete[] m_scanline; m_scanline = 0; } m_scanline = new unsigned char[width * 4]; #endif // FLIP_FRAMEBUFFER_VERTICALLY GLbitfield clearMask = GL_COLOR_BUFFER_BIT; if (m_attributes.stencil) clearMask |= GL_STENCIL_BUFFER_BIT; if (m_attributes.depth) clearMask |= GL_DEPTH_BUFFER_BIT; glClear(clearMask); }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; GLuint tex, fb; GLenum status; float fbo_white[] = {0.0, 0.0, 0.0, 1.0}; float fbo_black[] = {0.0, 0.0, 0.0, 0.0}; float fbo_gray[] = {0.0, 0.0, 0.0, 0.5}; float white[] = {1.0, 1.0, 1.0, 1.0}; float black[] = {0.0, 0.0, 0.0, 0.0}; float gray[] = {0.5, 0.5, 0.5, 0.5}; int fbo_width = 64; int fbo_height = 64; glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); glViewport(0, 0, fbo_width, fbo_height); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); 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_ALPHA, fbo_width, fbo_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); assert(glGetError() == 0); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status); piglit_report_result(PIGLIT_SKIP); } /* Clear to no alpha. */ glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glColor4f(0.0, 0.0, 0.0, 0.0); piglit_draw_rect(-1.0, -1.0, 0.5, 2.0); glColor4f(0.0, 0.0, 0.0, 1.0); piglit_draw_rect(-0.5, -1.0, 0.5, 2.0); glColor4f(0.0, 0.0, 0.0, 0.5); piglit_draw_rect(0.0, -1.0, 0.5, 2.0); glEnable(GL_BLEND); glBlendFunc(GL_DST_ALPHA, GL_ZERO); glColor4f(0.0, 0.0, 0.0, 1.0); piglit_draw_rect(0.0, -1.0, 0.5, 2.0); glDisable(GL_BLEND); glColor4f(0.0, 0.0, 0.0, 0.5); piglit_draw_rect(0.5, -1.0, 0.5, 2.0); glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_SRC_ALPHA); glColor4f(0.0, 0.0, 0.0, 1.0); piglit_draw_rect(0.5, -1.0, 0.5, 2.0); glDisable(GL_BLEND); printf("Testing FBO result.\n"); pass = piglit_probe_pixel_rgba(fbo_width * 1 / 8, 0, fbo_black) && pass; pass = piglit_probe_pixel_rgba(fbo_width * 3 / 8, 0, fbo_white) && pass; pass = piglit_probe_pixel_rgba(fbo_width * 5 / 8, 0, fbo_gray) && pass; pass = piglit_probe_pixel_rgba(fbo_width * 7 / 8, 0, fbo_gray) && pass; /* Draw the two textures to halves of the window. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glViewport(0, 0, piglit_width, piglit_height); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_ALPHA); glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); glBindTexture(GL_TEXTURE_2D, tex); piglit_draw_rect_tex(-1, -1, 2, 2, 0, 0, 1, 1); glDisable(GL_TEXTURE_2D); glDeleteTextures(1, &tex); glDeleteFramebuffersEXT(1, &fb); printf("Testing window result.\n"); pass = piglit_probe_pixel_rgba(piglit_width * 1 / 8, 0, black) && pass; pass = piglit_probe_pixel_rgba(piglit_width * 3 / 8, 0, white) && pass; pass = piglit_probe_pixel_rgba(piglit_width * 5 / 8, 0, gray) && pass; pass = piglit_probe_pixel_rgba(piglit_width * 7 / 8, 0, gray) && pass; glutSwapBuffers(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void GLFrameBufferObject::bind() { // Bind it to FBO const GLuint fb = mMultisampleFB ? mMultisampleFB : mFB; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); }
void GLFrameBufferObject::initialise() { // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); mManager->releaseRenderBuffer(mMultisampleColourBuffer); // First buffer must be bound if(!mColour[0].buffer) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attachment 0 must have surface attached", "GLFrameBufferObject::initialise"); } // If we're doing multisampling, then we need another FBO which contains a // renderbuffer which is set up to multisample, and we'll blit it to the final // FBO afterwards to perform the multisample resolve. In that case, the // mMultisampleFB is bound during rendering and is the one with a depth/stencil // Store basic stats uint32 width = mColour[0].buffer->getWidth(); uint32 height = mColour[0].buffer->getHeight(); GLuint format = mColour[0].buffer->getGLFormat(); ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets(); // Bind simple buffer to add colour attachments glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB); // Bind all attachment points to frame buffer for(unsigned int x=0; x<maxSupportedMRTs; ++x) { if(mColour[x].buffer) { if(mColour[x].buffer->getWidth() != width || mColour[x].buffer->getHeight() != height) { StringStream ss; ss << "Attachment " << x << " has incompatible size "; ss << mColour[x].buffer->getWidth() << "x" << mColour[x].buffer->getHeight(); ss << ". It must be of the same as the size of surface 0, "; ss << width << "x" << height; ss << "."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLFrameBufferObject::initialise"); } if(mColour[x].buffer->getGLFormat() != format) { StringStream ss; ss << "Attachment " << x << " has incompatible format."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLFrameBufferObject::initialise"); } mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT+x, mColour[x].zoffset); } else { // Detach glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+x, GL_RENDERBUFFER_EXT, 0); } } // Now deal with depth / stencil if (mMultisampleFB) { // Bind multisample buffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB); // Create AA render buffer (colour) // note, this can be shared too because we blit it to the final FBO // right after the render is finished mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); // Attach it, because we won't be attaching below and non-multisample has // actually been attached to other FBO mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT, mMultisampleColourBuffer.zoffset); // depth & stencil will be dealt with below } // Depth buffer is not handled here anymore. // See GLFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() // Do glDrawBuffer calls GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; GLsizei n=0; for(unsigned int x=0; x<OGRE_MAX_MULTIPLE_RENDER_TARGETS; ++x) { // Fill attached colour buffers if(mColour[x].buffer) { bufs[x] = GL_COLOR_ATTACHMENT0_EXT + x; // Keep highest used buffer + 1 n = x+1; } else { bufs[x] = GL_NONE; } } if(glDrawBuffers) { // Drawbuffer extension supported, use it glDrawBuffers(n, bufs); } else { // In this case, the capabilities will not show more than 1 simultaneaous render target. glDrawBuffer(bufs[0]); } if (mMultisampleFB) { // we need a read buffer because we'll be blitting to mFB glReadBuffer(bufs[0]); } else { // No read buffer, by default, if we want to read anyway we must not forget to set this. glReadBuffer(GL_NONE); } // Check status GLuint status; status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Bind main buffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); switch(status) { case GL_FRAMEBUFFER_COMPLETE_EXT: // All is good break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "All framebuffer formats with this texture internal format unsupported", "GLFrameBufferObject::initialise"); default: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Framebuffer incomplete or other FBO status error", "GLFrameBufferObject::initialise"); } }
virtual void bindFBO(GLuint framebuffer) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); }
enum piglit_result piglit_display(void) { enum piglit_result res; GLuint fb, rb; GLint stencil_size; GLenum status; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); /* Create the FBO. */ glGenRenderbuffersEXT(1, &rb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, f.iformat, BUF_SIZE, BUF_SIZE); glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_STENCIL_SIZE_EXT, &stencil_size); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, rb); glViewport(0, 0, BUF_SIZE, BUF_SIZE); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { printf("FBO incomplete status 0x%X\n", status); piglit_report_result(PIGLIT_SKIP); } mask = (1 << stencil_size) - 1; switch (test) { case CLEAR: puts("Testing glClear(stencil)."); res = test_clear(); break; case READPIXELS: puts("Testing glReadPixels(stencil)."); res = test_readpixels(); break; case DRAWPIXELS: puts("Testing glDrawPixels(stencil)."); res = test_drawpixels(); break; case COPYPIXELS: case BLIT: puts(test == BLIT ? "Testing glBlitFramebuffer(stencil)." : "Testing glCopyPixels(stencil)."); res = test_copy(); break; default: assert(0); } /* Cleanup. */ glDeleteFramebuffersEXT(1, &fb); glDeleteRenderbuffersEXT(1, &rb); glutSwapBuffers(); assert(glGetError() == 0); return res; }
/** * Stop rendering to this texture. */ void DepthRenderTexture::stop(){ // Stop acquiring and unbind the FBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glPopAttrib(); }
void GPU_framebuffer_blur( GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex) { const float scaleh[2] = {1.0f / GPU_texture_width(blurtex), 0.0f}; const float scalev[2] = {0.0f, 1.0f / GPU_texture_height(tex)}; GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR); int scale_uniform, texture_source_uniform; if (!blur_shader) return; scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU"); texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource"); /* Blurring horizontally */ /* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid * pushing unnecessary matrices onto the OpenGL stack. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); /* avoid warnings from texture binding */ GG.currentfb = blurfb->object; GPU_shader_bind(blur_shader); GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh); GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex); glViewport(0, 0, GPU_texture_width(blurtex), GPU_texture_height(blurtex)); /* Preparing to draw quad */ glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); GPU_texture_bind(tex, 0); /* Drawing quad */ glBegin(GL_QUADS); glTexCoord2d(0, 0); glVertex2f(1, 1); glTexCoord2d(1, 0); glVertex2f(-1, 1); glTexCoord2d(1, 1); glVertex2f(-1, -1); glTexCoord2d(0, 1); glVertex2f(1, -1); glEnd(); /* Blurring vertically */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); GG.currentfb = fb->object; glViewport(0, 0, GPU_texture_width(tex), GPU_texture_height(tex)); GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev); GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex); GPU_texture_bind(blurtex, 0); glBegin(GL_QUADS); glTexCoord2d(0, 0); glVertex2f(1, 1); glTexCoord2d(1, 0); glVertex2f(-1, 1); glTexCoord2d(1, 1); glVertex2f(-1, -1); glTexCoord2d(0, 1); glVertex2f(1, -1); glEnd(); GPU_shader_unbind(); }
////////////////////////////////////////////////////////////////////////// // This is the routine where we create the data being output by the Virtual // Camera device. // Modified as per red5 to allow for dropped frames and reset of time stamps // // http://comSender.googlecode.com/svn/trunk/ // ////////////////////////////////////////////////////////////////////////// HRESULT CVCamStream::FillBuffer(IMediaSample *pms) { unsigned char *buffer; unsigned char *src; unsigned char *dst; unsigned char red, grn, blu; unsigned int i, imagesize, width, height; long l, lDataLen; HRESULT hr=S_OK;; BYTE *pData; HGLRC glCtx; float dim[4]; // for saving the viewport dimensions VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) m_mt.Format(); // If graph is inactive stop cueing samples if(!m_pParent->IsActive()) { return S_FALSE; } // first get the timing right // create some working info REFERENCE_TIME rtNow, rtDelta, rtDelta2=0; // delta for dropped, delta 2 for sleep. REFERENCE_TIME avgFrameTime = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame; // Simple method - avoids "stuttering" in yawcam but VLC fails ! /* rtNow = m_rtLastTime; m_rtLastTime += avgFrameTime; pms->SetTime(&rtNow, &m_rtLastTime); pms->SetSyncPoint(TRUE); */ // What Time is it REALLY ??? m_pParent->GetSyncSource(&m_pClock); m_pClock->GetTime(&refSync1); if(m_pClock) m_pClock->Release(); if(NumFrames <= 1) { // initiate values refStart = refSync1; // FirstFrame No Drop. refSync2 = 0; } // Set the timestamps that will govern playback frame rate. // The current time is the sample's start rtNow = m_rtLastTime; m_rtLastTime = avgFrameTime + m_rtLastTime; // IAMDropppedFrame. We only have avgFrameTime to generate image. // Find generated stream time and compare to real elapsed time rtDelta=((refSync1-refStart)-(((NumFrames)*avgFrameTime)-avgFrameTime)); if(rtDelta-refSync2 < 0) { //we are early rtDelta2=rtDelta-refSync2; if( abs(rtDelta2/10000)>=1) Sleep(abs(rtDelta2/10000)); } // endif (rtDelta-refSync2 < 0) else if(rtDelta/avgFrameTime>NumDroppedFrames) { // new dropped frame NumDroppedFrames = rtDelta/avgFrameTime; // Figure new RT for sleeping refSync2 = NumDroppedFrames*avgFrameTime; // Our time stamping needs adjustment. // Find total real stream time from start time rtNow = refSync1-refStart; m_rtLastTime = rtNow+avgFrameTime; pms->SetDiscontinuity(true); } // end else if(rtDelta/avgFrameTime>NumDroppedFrames) // The SetTime method sets the stream times when this sample should begin and finish. hr = pms->SetTime(&rtNow, &m_rtLastTime); // Set true on every sample for uncompressed frames hr = pms->SetSyncPoint(true); // ============== END OF INITIAL TIMING ============ // Check access to the sample's data buffer pms->GetPointer(&pData); if(pData == NULL) { return NOERROR; } // Get the current frame size for texture transfers imagesize = (unsigned int)pvi->bmiHeader.biSizeImage; width = (unsigned int)pvi->bmiHeader.biWidth; height = (unsigned int)pvi->bmiHeader.biHeight; if(width == 0 || height == 0) { return NOERROR; } // don't do anything if disconnected because it will already have connected // previously and something has changed. It can only disconnect after it has connected. if(!bDisconnected) { // This also initialises OpenGL and Glew - bInitialized is set if all is OK if(!bInitialized) { if(OpenReceiver() == NOERROR) { bInitialized = true; bDisconnected = false; if(!bMemoryMode) { InitTexture(g_Width, g_Height); // the size of the camera window } } else { bInitialized = false; bDisconnected = true; } return NOERROR; } // check gl context again glCtx = wglGetCurrentContext(); if(glCtx == NULL) { receiver.ReleaseReceiver(); bInitialized = false; bDisconnected = true; // don't try again return NOERROR; } // Check that a texture Sender has not changed size // If connected, sizes should be OK, but check again unsigned int size = (unsigned int)pms->GetSize(); imagesize = width*height*3; // also retrieved above if(size != imagesize) { receiver.ReleaseReceiver(); bInitialized = false; bDisconnected = true; // don't try again return NOERROR; } // // everything matches so go ahead with the shared texture read if(!bDisconnected) { if(bMemoryMode) { // // Memoryshare instead of interop texture share // // A memoryshare sender cannot change from startup like a texture sender // so the global width and height are always the same as the camera width and height // // Read the bitmap from shared memory into a local buffer buffer = (unsigned char *)malloc(g_Width*g_Height*3); if(buffer) { // Format for Receiveimage in memoryshare mode is GL_RGB // because there is no texture to receive if(receiver.ReceiveImage(SharedMemoryName, senderWidth, senderHeight, buffer, GL_RGB)) { // first check that the image size has not changed if(senderWidth == g_Width && senderHeight == g_Height) { // all is OK - flip the data for correct orientation and change pixel format FlipVertical(buffer, g_Width, g_Height); dst = (unsigned char *)pData; src = buffer; for(i=0; i<g_Width*g_Height; i++) { red = *src++; grn = *src++; blu = *src++; *dst++ = blu; *dst++ = grn; *dst++ = red; } } else { // Sender has changed the image size // no way presently to deal with it so deinit receiver.ReleaseReceiver(); bMemoryMode = false; // it will go to a static image from now on bDisconnected = true; // and not try again } // end image size check } // received OK free((void *)buffer); } // endif buffer OK NumFrames++; return NOERROR; } else if(receiver.ReceiveTexture(SharedMemoryName, senderWidth, senderHeight)) { // // ======= RENDER THE SHARED TEXTURE INVERTED TO A LOCAL TEXTURE VIA FBO ========== // // The shared texture can be a different size to the local texture because this is // rendering and not copying. The local texture is always the same size as the filter. // glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); glPushAttrib(GL_TRANSFORM_BIT); glGetFloatv(GL_VIEWPORT, dim); glViewport(0, 0, g_Width, g_Height); // size of the camera window glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // reset the current matrix back to its default state glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // Attach the local texture (desination) to the color buffer in our frame buffer // and draw into it with the shared texture glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_fbo); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_fbo_texture, 0); receiver.DrawSharedTexture(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); glViewport(dim[0], dim[1], dim[2], dim[3]); glMatrixMode(GL_TEXTURE); glPopMatrix(); // now read the local texture into the sample's data buffer because the sizes match glBindTexture(GL_TEXTURE_2D, g_fbo_texture); glEnable(GL_TEXTURE_2D); glGetTexImage(GL_TEXTURE_2D, 0, GL_BGR, GL_UNSIGNED_BYTE, (void *)pData); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); // LJ DEBUG for flip test // FlipVertical(pData, g_Width, g_Height); NumFrames++; return NOERROR; } // endif received OK else { receiver.ReleaseReceiver(); bInitialized = false; bDisconnected = true; // don't try again } // endif received texture OK } // endif texture mode } // endif not disconnected // drop through to default static image if it did not work pms->GetPointer(&pData); lDataLen = pms->GetSize(); for(l = 0; l <lDataLen; ++l) pData[l] = rand(); NumFrames++; return NOERROR; } // FillBuffer
GLDepthRenderTarget::GLDepthRenderTarget(int w, int h, int l):GLRenderTarget() { GLuint shadowMapTexture=0; GLuint rboId=0; width = w; height = h; if(!gl_ext_framebuffer.integer) return; if(!GLEW_ARB_texture_non_power_of_two) { width = round2(width); height = round2(height); texS = w/(float)width; texT = h/(float)height; } glGenTextures(1, &shadowMapTexture); if(l && gl_ext_texture_array.integer) { Console_Printf(" Generate DEPTH ARRAY FBO %dx%dx%d. ", w, h, l); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapTexture); glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL ); glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, width, height, l, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D_ARRAY, 0); glGenFramebuffersEXT(1, &fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId); glGenRenderbuffersEXT(1, &rboId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); // attach a renderbuffer to depth attachment point glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); // attach a texture to FBO depth attachment point // Big: actually we set the target when we go to use it //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D/*_ARRAY*/, shadowMapTexture, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } else if(l==0 && GLEW_ARB_depth_texture) { Console_Printf(" Generate DEPTH FBO %dx%d. ", w, h); glBindTexture(GL_TEXTURE_2D, shadowMapTexture); 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 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL ); //glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE ); glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffersEXT(1, &fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId); glGenRenderbuffersEXT(1, &rboId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); // attach a renderbuffer to depth attachment point glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId); // attach a texture to FBO depth attachment point // Big: actually we set the target when we go to use it //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadowMapTexture, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } #ifdef DEBUG GLSL_catchLastError("GLDepthRenderTarget::GLDepthRenderTarget"); #endif GL_CheckFBOStatus(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //now create a pass for when we go to use this thing passCount = 1; passes[0] = new GLMaterialPass(this); passes[0]->texmaps[0] = shadowMapTexture; passes[0]->texmap_num = 1; if(l && gl_ext_texture_array.integer) { passes[0]->multitexture = true; passes[0]->arrayTexture = true; } }
void piglit_init(int argc, char **argv) { GLuint tex, fb; GLenum status; int i, j, dim; piglit_require_GLSL(); piglit_require_extension("GL_EXT_framebuffer_object"); piglit_require_extension("GL_ARB_shader_texture_lod"); prog_tex = piglit_build_simple_program(NULL, sh_tex); prog_texgrad = piglit_build_simple_program(NULL, sh_texgrad); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; j++) { for (i = 0, dim = TEX_WIDTH; dim >0; i++, dim /= 2) { glTexImage2D(j, i, GL_RGBA, dim, dim, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } assert(glGetError() == 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glDisable(GL_TEXTURE_CUBE_MAP); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; j++) { for (i = 0, dim = TEX_WIDTH; dim >0; i++, dim /= 2) { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, j, tex, i); status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "FBO incomplete\n"); piglit_report_result(PIGLIT_SKIP); } glClearColor(colors[i][0], colors[i][1], colors[i][2], 0.0); glClear(GL_COLOR_BUFFER_BIT); assert(glGetError() == 0); } } glDeleteFramebuffersEXT(1, &fb); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-0.1, 0.1, -0.1, 0.1, 0.1, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(-0.5, -0.5, -1.2); glRotatef(68, 0, 1, 0); glScalef(2000, 1, 1); glEnable(GL_TEXTURE_CUBE_MAP); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); piglit_set_tolerance_for_bits(7, 7, 7, 7); printf("Left: textureCube, Right: textureCubeGradARB\n"); }
void FrameBufferObject::unbind() { EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 )); }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; GLuint tex0, tex1, fb; GLenum status; float white[] = {1, 1, 1, 1}; float green[] = {0, 1, 0, 0}; float blue[] = {0, 0, 1, 0}; const GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, }; piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); tex0 = attach_texture(0); tex1 = attach_texture(1); glDrawBuffersARB(2, attachments); status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status); piglit_report_result(PIGLIT_SKIP); } /* Clear to black */ glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* Mask only green in RT 0, blue in RT 1, then try to draw in white */ glColorMaskIndexedEXT(0, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); glColorMaskIndexedEXT(1, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); if (test_clear) { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); } else { glColor4fv(white); piglit_draw_rect(0, 0, piglit_width, piglit_height); } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); /* Draw the two textures to halves of the window. */ glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, tex0); piglit_draw_rect_tex(0, 0, piglit_width / 2, piglit_height, 0, 0, 1, 1); glBindTexture(GL_TEXTURE_2D, tex1); piglit_draw_rect_tex(piglit_width / 2, 0, piglit_width, piglit_height, 0, 0, 1, 1); glDisable(GL_TEXTURE_2D); glDeleteTextures(1, &tex0); glDeleteTextures(1, &tex1); glDeleteFramebuffersEXT(1, &fb); pass = pass && piglit_probe_rect_rgb(0, 0, piglit_width/2, piglit_height, green); pass = pass && piglit_probe_rect_rgb(piglit_width/2, 0, piglit_width/2, piglit_height, blue); piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
// ok let's start things up void GPUVolRTV2::init(DrawEnv *pEnv) { create_volumetexture(); load_vertex_program (vertexprog, "raycasting_shader.vp.cg"); load_fragment_program(fragmentprog,"raycasting_shader.fp.cg"); shaderprog = glCreateProgram(); glAttachShader(shaderprog, vertexprog); glAttachShader(shaderprog, fragmentprog); glLinkProgram(shaderprog); check_program_status(shaderprog); stepsizeLoc = glGetUniformLocation(shaderprog, "stepsize"); mvLoc = glGetUniformLocation(shaderprog, "ModelView"); mpLoc = glGetUniformLocation(shaderprog, "Proj"); texLoc = glGetUniformLocation(shaderprog, "tex"); volumeTexLoc = glGetUniformLocation(shaderprog, "volume_tex"); // Create the to FBO's one for the backside of the volumecube and one for the finalimage rendering glGenFramebuffersEXT(1, &framebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,framebuffer); glGenTextures(1, &backface_buffer); glBindTexture(GL_TEXTURE_2D, backface_buffer); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 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_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); // glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL); glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, pEnv->getPixelWidth(), pEnv->getPixelHeight(), 0, GL_RGBA, GL_FLOAT, NULL); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, backface_buffer, 0); glGenTextures(1, &final_image); glBindTexture(GL_TEXTURE_2D, final_image); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 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_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); // glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL); glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, pEnv->getPixelWidth(), pEnv->getPixelHeight(), 0, GL_RGBA, GL_FLOAT, NULL); glGenRenderbuffersEXT(1, &renderbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer); // glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, WINDOW_SIZE, WINDOW_SIZE); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, pEnv->getPixelWidth(), pEnv->getPixelHeight()); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); bInitialized = true; }
void piglit_init(int argc, char **argv) { GLint max_samples, sample_buffers, samples, rb_samples; GLuint rb, fb; GLenum status; bool pass = true; int i; piglit_require_extension("GL_EXT_framebuffer_multisample"); glGetIntegerv(GL_MAX_SAMPLES, &max_samples); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER, fb); glDrawBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0); for (i = 0; i < max_samples; i++) { glGenRenderbuffersEXT(1, &rb); glBindRenderbufferEXT(GL_RENDERBUFFER, rb); glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, max_samples, GL_RGBA, 1, 1); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "FBO incomplete\n"); piglit_report_result(PIGLIT_FAIL); } glGetRenderbufferParameterivEXT(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &rb_samples); glGetIntegerv(GL_SAMPLES, &samples); if (rb_samples != samples) { fprintf(stderr, "FBO reported GL_SAMPLES %d for " "rb samples %d\n", samples, rb_samples); pass = false; } glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers); if ((rb_samples != 0) != (sample_buffers == 1)) { fprintf(stderr, "FBO reported GL_SAMPLE_BUFFERS %d for " "rb samples %d\n", sample_buffers, samples); pass = false; } glDeleteRenderbuffersEXT(1, &rb); } glDeleteFramebuffersEXT(1, &fb); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void GPUVolRTV2::disable_renderbuffers() { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
enum piglit_result piglit_display(void) { static GLenum buffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT}; static const float red[] = {1.0f, 0.0f, 0.0f}; static const float green[] = {0.0f, 1.0f, 0.0f}; static const float blue[] = {0.0f, 0.0f, 1.0f}; static const struct { GLsizei buffer_count; const float *clear_color; const float *expected_0; const float *expected_1; } tests[] = { {2, red, red, red}, {1, green, green, red}, {2, blue, blue, blue}, }; int w = piglit_width; int h = piglit_height; GLuint fbo, tex[2]; unsigned i; glGenTextures(2, tex); glBindTexture(GL_TEXTURE_2D, tex[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); glBindTexture(GL_TEXTURE_2D, tex[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); glGenFramebuffersEXT(1, &fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex[0], 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, tex[1], 0); check_fbo_status(); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) { GLint buffer, expected_buffer; glDrawBuffersARB(tests[i].buffer_count, buffers); check_fbo_status(); glGetIntegerv(GL_DRAW_BUFFER1_ARB, &buffer); expected_buffer = tests[i].buffer_count < 2 ? GL_NONE : GL_COLOR_ATTACHMENT1_EXT; if (buffer != expected_buffer) { printf("Unexpected buffer %#x for DRAW_BUFFER1_ARB in test %u, expected %#x.\n", buffer, i, expected_buffer); piglit_report_result(PIGLIT_FAIL); } glClearColor(tests[i].clear_color[0], tests[i].clear_color[1], tests[i].clear_color[2], 1.0f); glClear(GL_COLOR_BUFFER_BIT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); if (!piglit_probe_pixel_rgb(w / 2, h / 2, tests[i].expected_0)) { printf("Probe failed for test %u, attachment 0.\n", i); piglit_report_result(PIGLIT_FAIL); } glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); if (!piglit_probe_pixel_rgb(w / 2, h / 2, tests[i].expected_1)) { printf("Probe failed for test %u, attachment 1.\n", i); piglit_report_result(PIGLIT_FAIL); } } if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); return PIGLIT_PASS; }
void DiGLFrameBuffer::Bind() { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBOId); }
PIGLIT_GL_TEST_CONFIG_END enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; int x, y; GLuint tex, fb; float blue[] = {1, 0, 0, 0}; float green[] = {0, 1, 0, 0}; bool draw_green; float *draw_colors[] = {blue, green}; float w_screen = 2.0f * TEX_WIDTH / piglit_width; float h_screen = 2.0f * TEX_HEIGHT / piglit_height; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); draw_green = true; for (y = 0; y <= piglit_height - TEX_HEIGHT; y += TEX_HEIGHT) { float y_screen = -1.0 + 2.0 * ((float)y / piglit_height); for (x = 0; x <= piglit_width - TEX_WIDTH; x += TEX_WIDTH) { float x_screen = -1.0 + 2.0 * ((float)x / piglit_width); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); glDisable(GL_TEXTURE_2D); glColor4fv(draw_colors[draw_green]); piglit_draw_rect(-1, -1, 2, 2); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); glEnable(GL_TEXTURE_2D); piglit_draw_rect_tex(x_screen, y_screen, w_screen, h_screen, 0, 0, 1, 1); draw_green = !draw_green; } /* Make it a checkerboard. */ draw_green = !draw_green; } glDeleteFramebuffersEXT(1, &fb); glDeleteTextures(1, &tex); draw_green = true; for (y = 0; y <= piglit_height - TEX_HEIGHT; y += TEX_HEIGHT) { for (x = 0; x <= piglit_width - TEX_WIDTH; x += TEX_WIDTH) { float *expected = draw_colors[draw_green]; pass = pass && piglit_probe_rect_rgb(x, y, TEX_WIDTH, TEX_HEIGHT, expected); draw_green = !draw_green; } draw_green = !draw_green; } piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void DiGLFrameBuffer::Init() { size_t width = mColorBuffer[0]->GetWidth(); size_t height = mColorBuffer[0]->GetHeight(); DiPixelFormat origFmt = mColorBuffer[0]->GetFormat(); uint32 maxSupportedMRTs = MAX_MRT; //TODO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBOId); // Bind all attachment points to frame buffer for (size_t x = 0; x < maxSupportedMRTs; ++x) { if (mColorBuffer[x]) { if (mColorBuffer[x]->GetWidth() != width || mColorBuffer[x]->GetHeight() != height) { DI_WARNING("All color buffers in a frame buffer object should exactly in same dimension"); return; } if (mColorBuffer[x]->GetFormat() != origFmt) { DI_WARNING("All color buffers in a frame buffer object should exactly in same format"); return; } DiGLTextureDrv* td = static_cast<DiGLTextureDrv*>(mColorBuffer[x]->GetTextureDriver()); td->BindToFrameBuffer(GL_COLOR_ATTACHMENT0_EXT + x, 0, 0); } else { glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + x, GL_RENDERBUFFER_EXT, 0); } } GLenum bufs[MAX_MRT]; GLsizei n = 0; for (size_t x = 0; x < MAX_MRT; ++x) { if (mColorBuffer[x]) { bufs[x] = GL_COLOR_ATTACHMENT0_EXT + x; // Keep highest used buffer + 1 n = x + 1; } else { bufs[x] = GL_NONE; } } if (glDrawBuffers) glDrawBuffers(n, bufs); else glDrawBuffer(bufs[0]); glReadBuffer(GL_NONE); GLuint result = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); switch (result) { case GL_FRAMEBUFFER_UNSUPPORTED_EXT: DI_WARNING("Unsupported frame buffer format."); break; case GL_FRAMEBUFFER_COMPLETE_EXT: break; default: DI_WARNING("Cannot init frame buffer object."); } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTFramebufferObject_nglBindFramebufferEXT(JNIEnv *env, jclass clazz, jint target, jint framebuffer, jlong function_pointer) { glBindFramebufferEXTPROC glBindFramebufferEXT = (glBindFramebufferEXTPROC)((intptr_t)function_pointer); glBindFramebufferEXT(target, framebuffer); }