void R_EXT_FramebufferCleanup ( void ) { int i = 0; framebuffer_t *fbo = framebuffers; texture_t *texture = textures; for ( i=0; i<numFramebuffers; i++, fbo++ ) { if ( !fbo->id ) continue; glDeleteFramebuffersEXT( 1, &fbo->id ); CheckGLErrors( __FILE__, __LINE__ ); } for ( i=0; i<numTextures; i++, texture++ ) { if ( !texture->id ) continue; glDeleteTextures( 1, &texture->id ); CheckGLErrors( __FILE__, __LINE__ ); } glDeleteRenderbuffersEXT( numRenderbuffers, renderbuffers ); currentReadFramebuffer = currentWriteFramebuffer = NULL; numFramebuffers = numTextures = numRenderbuffers = 0; memset( framebuffers, 0, sizeof( framebuffers ) ); memset( textures, 0, sizeof( textures ) ); memset( renderbuffers, 0, sizeof( renderbuffers ) ); }
void VolumeController::setViewPortSize( const unsigned int width, const unsigned int height ) { if( 0 == m_fbo ) return; glBindFramebuffer( GL_FRAMEBUFFER, m_fbo ); glDeleteRenderbuffers( 1, &m_fbo_depth_buffer ); delete m_fbo_color_texture; delete m_fbo_node_list_texture_0; /*delete m_fbo_node_list_texture_1; delete m_fbo_node_list_texture_2;*/ // TODO: is this really handled automatically (ie, are these unbound from fbo when deleted?) glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0 ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0 ); /*glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, 0, 0 ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, 0, 0 );*/ // create depth buffer glGenRenderbuffers( 1, &m_fbo_depth_buffer ); glBindRenderbuffer( GL_RENDERBUFFER, m_fbo_depth_buffer ); glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height ); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_fbo_depth_buffer ); CheckGLErrors(); // create color texture m_fbo_color_texture = new NodeListTexture( width, height ); m_fbo_color_texture->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fbo_color_texture->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL ); CheckGLErrors(); // create node list textures m_fbo_node_list_texture_0 = new NodeListTexture( width, height ); m_fbo_node_list_texture_0->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_fbo_node_list_texture_0->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL ); /*m_fbo_node_list_texture_1 = new NodeListTexture( width, height ); m_fbo_node_list_texture_1->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, m_fbo_node_list_texture_1->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL ); m_fbo_node_list_texture_2 = new NodeListTexture( width, height ); m_fbo_node_list_texture_2->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, m_fbo_node_list_texture_2->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL );*/ // make sure fbo is complete GLenum status = 0; assert( GL_FRAMEBUFFER_COMPLETE == ( status = glCheckFramebufferStatus( GL_FRAMEBUFFER ) ) ); // release frame buffer glBindFramebuffer( GL_FRAMEBUFFER, NULL ); }
unsigned int R_EXT_CreateRenderbuffer( unsigned int width, unsigned int height, internalFormat_t internalFormat ) { unsigned int renderbufferId = 0; if ( numRenderbuffers >= MAX_RENDERBUFFERS ) { Com_Error( ERR_DROP, "Exceeded maximum number of renderbuffers\n" ); return 0; } glGenRenderbuffersEXT (1, &renderbufferId); if ( renderbufferId == 0 ) { Com_Error( ERR_DROP, "Failed to create renderbuffer with internal ID %d.\n", numRenderbuffers ); return 0; } glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, renderbufferId ); glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, R_EXT_GetGLInternalFormat( internalFormat ), width, height ); renderbuffers[numRenderbuffers] = renderbufferId; numRenderbuffers++; CheckGLErrors( __FILE__, __LINE__ ); return renderbufferId; }
void R_EXT_AttachStencilRenderbufferToFramebuffer( framebuffer_t *framebuffer, unsigned int renderbufferId ) { glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbufferId ); framebuffer->stencilTexture = renderbufferId; CheckGLErrors( __FILE__, __LINE__ ); }
void R_EXT_AttachDepthTextureToFramebuffer( framebuffer_t *framebuffer, const texture_t *texture ) { glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, R_EXT_GetGLTextureTarget( texture->target ), texture->id, 0 ); framebuffer->depthTexture = texture->id; CheckGLErrors( __FILE__, __LINE__ ); }
void R_EXT_AttachDepthRenderbufferToFramebuffer( framebuffer_t *framebuffer, unsigned int renderbufferId ) { glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbufferId ); framebuffer->depthTexture = renderbufferId; CheckGLErrors( __FILE__, __LINE__ ); }
framebuffer_t *R_EXT_CreateFramebuffer( void ) { framebuffer_t *fbo = NULL; if ( numFramebuffers >= MAX_FRAMEBUFFERS ) { Com_Error( ERR_DROP, "Maximum number of framebuffers exeeded.\n" ); return NULL; } fbo = &framebuffers[numFramebuffers]; glGenFramebuffersEXT (1, &fbo->id); if ( !fbo->id ) { Com_Error( ERR_DROP, "Failed to create framebuffer with internal ID %d.\n", numFramebuffers ); return NULL; } numFramebuffers++; CheckGLErrors( __FILE__, __LINE__ ); return fbo; }
bool GLSaveScreenshotPPM(const char* filename) { // These are important to get screen captures to work correctly glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLint vp[4]; glGetIntegerv(GL_VIEWPORT,vp); int x=vp[0]; int y=vp[1]; int width = vp[2]; int height = vp[3]; unsigned char* data = new unsigned char[width*height*3]; glReadBuffer(GL_BACK); glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,data); bool errors = CheckGLErrors("SaveScreenshot",false); if(errors) { delete [] data; return false; } flipRGBImage(data,width,height); bool res = WritePPM_RGB_Binary(data,width,height,filename); delete [] data; return res; }
void VolumeController::createFBO() { // TODO: fix hard-coded size int width = 10; int height = 10; // create fbo glGenFramebuffers( 1, &m_fbo ); glBindFramebuffer( GL_FRAMEBUFFER, m_fbo ); CheckGLErrors(); // create depth buffer glGenRenderbuffers( 1, &m_fbo_depth_buffer ); glBindRenderbuffer( GL_RENDERBUFFER, m_fbo_depth_buffer ); glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height ); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_fbo_depth_buffer ); CheckGLErrors(); // create color texture m_fbo_color_texture = new NodeListTexture( width, height ); m_fbo_color_texture->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fbo_color_texture->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL ); CheckGLErrors(); // create node list textures m_fbo_node_list_texture_0 = new NodeListTexture( width, height ); m_fbo_node_list_texture_0->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_fbo_node_list_texture_0->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL ); /*m_fbo_node_list_texture_1 = new NodeListTexture( width, height ); m_fbo_node_list_texture_1->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, m_fbo_node_list_texture_1->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL ); m_fbo_node_list_texture_2 = new NodeListTexture( width, height ); m_fbo_node_list_texture_2->bind(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, m_fbo_node_list_texture_2->getId(), 0 ); glBindTexture( GL_TEXTURE_2D, NULL );*/ CheckGLErrors(); // make sure fbo is complete GLenum status = 0; assert( GL_FRAMEBUFFER_COMPLETE == ( status = glCheckFramebufferStatus( GL_FRAMEBUFFER ) ) ); // release frame buffer glBindFramebuffer( GL_FRAMEBUFFER, NULL ); }
void R_EXT_BindFramebuffer( const framebuffer_t *framebuffer ) { if ( currentReadFramebuffer != framebuffer || currentWriteFramebuffer != framebuffer ) { glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, framebuffer->id ); currentReadFramebuffer = framebuffer; currentWriteFramebuffer = framebuffer; } CheckGLErrors( __FILE__, __LINE__ ); }
void R_EXT_BindDefaultFramebuffer( void ) { if ( currentReadFramebuffer || currentWriteFramebuffer ) { glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); currentReadFramebuffer = NULL; currentWriteFramebuffer = NULL; } CheckGLErrors( __FILE__, __LINE__ ); }
void NodePoolTexture::replaceData( const void* data, const uivec3& start, const uivec3& size ) { // make sure we're updating the right texture bind(); // replace the texels glTexSubImage3D( GL_TEXTURE_3D, 0, start[ 0 ], start[ 1 ], start[ 2 ], size[ 0 ], size[ 1 ], size[ 2 ], GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, data ); // look for gl errors CheckGLErrors(); }
void R_EXT_AttachColorTextureToFramebuffer( framebuffer_t *framebuffer, const texture_t *texture, unsigned int slot ) { if ( slot >= MAX_FBO_COLOR_TEXTURES ) { trap->Print( "Invalid slot number given (%d), valid range is 0 - %d.\n", slot, MAX_FBO_COLOR_TEXTURES - 1 ); return; } glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + slot, R_EXT_GetGLTextureTarget( texture->target ), texture->id, 0 ); framebuffer->colorTextures[slot] = texture; CheckGLErrors( __FILE__, __LINE__ ); }
void NodePoolTexture::replaceNode( const void* data, const uivec3& start ) { // make sure we're updating the right texture bind(); // setup pbo glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pbo ); void* pbo_mem = glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY ); assert( pbo_mem ); memcpy( pbo_mem, data, NODE_SIZE ); glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER ); CheckGLErrors(); // replace the texels glTexSubImage3D( GL_TEXTURE_3D, 0, start[ 0 ], start[ 1 ], start[ 2 ], 1, 1, 1, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, 0 ); // clear pbo glBindBuffer( GL_PIXEL_UNPACK_BUFFER, NULL ); // look for gl errors CheckGLErrors(); }
void NodePoolTexture::initialize( const unsigned char* data ) { // create the texture glGenTextures( 1, &m_id ); glBindTexture( GL_TEXTURE_3D, m_id ); glTexImage3D( GL_TEXTURE_3D, 0, GL_LUMINANCE_ALPHA32UI_EXT, m_size_x, m_size_y, m_size_z, 0, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, data ); // create pbo glGenBuffers( 1, &m_pbo ); glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pbo ); glBufferData( GL_PIXEL_UNPACK_BUFFER, 8 * 2 * sizeof( int ), NULL, GL_DYNAMIC_DRAW ); glBindBuffer( GL_PIXEL_UNPACK_BUFFER, NULL ); // check for opengl errors CheckGLErrors(); }
texture_t *R_EXT_CreateBlankTexture( unsigned int width, unsigned int height, internalFormat_t internalFormat ) { unsigned int textureId = 0; unsigned int glTexTarget = 0; texture_t *texture = NULL; if ( numTextures >= MAX_TEXTURES ) { Com_Error( ERR_DROP, "Exceeded maximum number of textures\n" ); return NULL; } glGenTextures( 1, &textureId ); if ( !textureId ) { Com_Error( ERR_DROP, "Failed to create texture with internal ID %d.\n", numTextures ); return NULL; } texture = &textures[numTextures]; texture->id = textureId; texture->target = TT_POT; //IsPowerOfTwo (width) && IsPowerOfTwo (height) ? TT_POT : TT_NPOT; texture->width = width; texture->height = height; glTexTarget = R_EXT_GetGLTextureTarget( texture->target ); glBindTexture( glTexTarget, textureId ); glTexParameteri( glTexTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( glTexTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( glTexTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( glTexTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexImage2D( glTexTarget, 0, R_EXT_GetGLInternalFormat( internalFormat ), width, height, 0, R_EXT_GetGLFormat( internalFormat ), R_EXT_GetDataTypeForFormat( internalFormat ), NULL ); glBindTexture( glTexTarget, 0 ); numTextures++; CheckGLErrors( __FILE__, __LINE__ ); return texture; }
texture_t *R_EXT_CreateTexture( unsigned int width, unsigned int height, internalFormat_t internalFormat, unsigned int minFilter, unsigned int magFilter ) { unsigned int textureId = 0; unsigned int glTexTarget = 0; texture_t* texture = NULL; if ( numTextures >= MAX_TEXTURES ) { trap->Print ("Exceeded maximum number of textures.\n"); return NULL; } glGenTextures (1, &textureId); if ( textureId == 0 ) { trap->Print ("Failed to create texture with internal ID %d.\n", numTextures); return NULL; } texture = &textures[numTextures]; texture->id = textureId; texture->target = TT_POT; texture->width = width; texture->height = height; glTexTarget = R_EXT_GetGLTextureTarget (texture->target); glBindTexture (glTexTarget, textureId); glTexParameteri (glTexTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (glTexTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (glTexTarget, GL_TEXTURE_MIN_FILTER, filterTable[minFilter]); glTexParameteri (glTexTarget, GL_TEXTURE_MAG_FILTER, filterTable[magFilter]); glTexImage2D (glTexTarget, 0, R_EXT_GetGLInternalFormat (internalFormat), width, height, 0, R_EXT_GetGLFormat (internalFormat), R_EXT_GetDataTypeForFormat (internalFormat), NULL); glBindTexture (glTexTarget, 0); numTextures++; CheckGLErrors (__FILE__, __LINE__); return texture; }
qboolean R_EXT_FramebufferInit( void ) { if ( !strstr( cgs.glconfig.extensions_string, "GL_EXT_framebuffer_object" ) || !strstr( cgs.glconfig.extensions_string, "GL_EXT_framebuffer_blit" ) ) { trap->Print( S_COLOR_RED "Framebuffer extension NOT loaded.\nRequired OpenGL extensions not available.\n" ); tr.postprocessing.loaded = qfalse; return qfalse; } // memset( framebuffers, 0, sizeof( framebuffers ) ); // memset( textures, 0, sizeof( textures ) ); // memset( renderbuffers, 0, sizeof( renderbuffers ) ); trap->Print( "Framebuffer extension loaded\n" ); CheckGLErrors( __FILE__, __LINE__ ); return qtrue; }
void NodeListTexture::initialize() { // TODO: does the texture need to be initialized? //// create empty data for the texture // delete data; //unsigned int* data = new unsigned int[ m_size_x * m_size_y * 4 ]; //for( unsigned int i = 0; i < m_size_x * m_size_y * 4; i++ ) { // data[ i ] = 0; //} void* data = NULL; // create the texture glGenTextures( 1, &m_id ); glBindTexture( GL_TEXTURE_2D, m_id ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA32UI_EXT, m_size_x, m_size_y, 0, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, (void*)data ); // check for opengl errors CheckGLErrors(); }
bool GLSaveScreenshot(const char* filename) { #if (defined WIN32 && defined GDI_AVAILABLE) // These are important to get screen captures to work correctly glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLint vp[4]; glGetIntegerv(GL_VIEWPORT,vp); int x=vp[0]; int y=vp[1]; int width = vp[2]; int height = vp[3]; //row-major array, bottom corner is first row Image image; image.initialize(width,height,Image::R8G8B8); //glReadBuffer(GL_FRONT); glReadBuffer(GL_BACK); glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,image.data); bool errors = CheckGLErrors("SaveScreenshot",false); if(errors) return false; //printf("Flipping RGB image...\n"); flipRGBImage(image.data,width,height); //printf("Done, now exporting...\n"); return ExportImageGDIPlus(filename,image); //printf("Done, saving screenshot.\n"); /* ImageOperator op(image); ImageOperator op2; op2.initialize(640,480); op.stretchBlitBilinear(op2); Image image2; op2.output(image2,Image::R8G8B8); ExportImageGDIPlus(filename,image2); */ #else fprintf(stderr,"Warning, saving screenshot in PPM format...\n"); return GLSaveScreenshotPPM(filename); #endif }
void R_EXT_BlitFramebuffer( const framebuffer_t *source, const framebuffer_t *destination, int sourceWidth, int sourceHeight, int destWidth, int destHeight, unsigned int bufferBits ) { if ( currentReadFramebuffer != source ) { glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, source ? source->id : 0 ); currentReadFramebuffer = source; } if ( currentWriteFramebuffer != destination ) { glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, destination ? destination->id : 0 ); currentWriteFramebuffer = destination; } glBlitFramebufferEXT( sourceWidth, sourceHeight, 0, 0, destWidth, destHeight, 0, 0, bufferBits, GL_NEAREST ); CheckGLErrors( __FILE__, __LINE__ ); }
void R_EXT_CheckFramebuffer( const framebuffer_t *framebuffer ) { unsigned int status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ); switch ( status ) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: trap->Print( "One or more framebuffer attachment points are not complete.\n" ); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: trap->Print( "One or more attached images have different dimensions.\n" ); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: trap->Print( "Invalid framebuffer attachment object type used.\n" ); break; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: trap->Print( "More than one internal format was used in the color attachments.\n" ); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: trap->Print( "Missing a read buffer.\n" ); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: trap->Print( "No images were attached to the framebuffer.\n" ); break; case GL_FRAMEBUFFER_COMPLETE_EXT: break; } //Raz: Maybe Com_Error from here to unload cgame before crashing if ( status != GL_FRAMEBUFFER_COMPLETE_EXT ) trap->Print( "Creation of framebuffer %d could not be completed.\n", framebuffer->id ); CheckGLErrors( __FILE__, __LINE__ ); }
void GradientLayer::Render(const RenderCtx &ctx) const { if(mGradient->HasTransparency()) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } sShader->Bind(); GradientLayerMesh mesh(mRect,mAxisStart,mAxisEnd,mGradient); Vec3 *vertices = (Vec3*)alloca(mesh.GetNumVertices() * sizeof(Vec3)); for(int i = 0;i < mesh.GetNumVertices();i++) { vertices[i] = ctx.LocalToDevice(mesh.GetVertex(i)); } glBindBuffer(GL_ARRAY_BUFFER,0); CheckGLErrors(); glVertexAttribPointer(0, 3, GL_FLOAT, 0, 0,(const float*)vertices); CheckGLErrors(); glEnableVertexAttribArray(0); CheckGLErrors(); glVertexAttribPointer(1, 4, GL_FLOAT, 0, 0, (const float*)mesh.GetColors()); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0,mesh.GetNumVertices()); CheckGLErrors(); glDisableVertexAttribArray(0); CheckGLErrors(); glDisableVertexAttribArray(1); CheckGLErrors(); if(mGradient->HasTransparency()) { glDisable(GL_BLEND); } }
// TODO: gl call lists? void VolumeController::render() { double fov = m_renderer->getCamera()->getFOV(); double distance = m_renderer->getHeight() / 2.0 / tan( fov * M_PI / 180.0 ); m_shader.setDistanceToMaxLOD( static_cast< float >( distance ) ); // enable depth to occlude bounding box lines glEnable( GL_DEPTH_TEST ); // setup blending glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // only draw back faces glEnable( GL_CULL_FACE ); glCullFace( GL_FRONT ); // setup fbo and mrt glBindFramebuffer( GL_FRAMEBUFFER, m_fbo ); GLenum buffer_list[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; // clear all buffers to black glDrawBuffers( 2, buffer_list ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // clear color buffer to that nice red color // TODO: why doesn't this work glDrawBuffers( 1, buffer_list ); //glClearColor( 0.8f, 0.2f, 0.2f, 1.0f ); glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT ); // draw to all buffers glDrawBuffers( 2, buffer_list ); { // draw the actual box // load shader glUseProgram( m_shader.getShaderId() ); // setup textures glEnable( GL_TEXTURE_3D ); glActiveTexture( GL_TEXTURE1 ); m_node_tree_controller->getNodePoolTexture()->bind(); glActiveTexture( GL_TEXTURE0 ); m_node_tree_controller->getBlockPoolTexture()->bind(); glBegin( GL_QUADS ); // z = 0 glTexCoord3f( 0.0f, 0.0f, 0.0f ); glVertex3d( m_corner1[ 0 ], m_corner1[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 0.0f, 1.0f, 0.0f ); glVertex3d( m_corner1[ 0 ], m_corner2[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 1.0f, 1.0f, 0.0f ); glVertex3d( m_corner2[ 0 ], m_corner2[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 1.0f, 0.0f, 0.0f ); glVertex3d( m_corner2[ 0 ], m_corner1[ 1 ], m_corner1[ 2 ] ); // z = 1 glTexCoord3f( 0.0f, 0.0f, 1.0f ); glVertex3d( m_corner1[ 0 ], m_corner1[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 1.0f, 0.0f, 1.0f ); glVertex3d( m_corner2[ 0 ], m_corner1[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 1.0f, 1.0f, 1.0f ); glVertex3d( m_corner2[ 0 ], m_corner2[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 0.0f, 1.0f, 1.0f ); glVertex3d( m_corner1[ 0 ], m_corner2[ 1 ], m_corner2[ 2 ] ); // x = 0 glTexCoord3f( 0.0f, 0.0f, 0.0f ); glVertex3d( m_corner1[ 0 ], m_corner1[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 0.0f, 0.0f, 1.0f ); glVertex3d( m_corner1[ 0 ], m_corner1[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 0.0f, 1.0f, 1.0f ); glVertex3d( m_corner1[ 0 ], m_corner2[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 0.0f, 1.0f, 0.0f ); glVertex3d( m_corner1[ 0 ], m_corner2[ 1 ], m_corner1[ 2 ] ); // x = 1 glTexCoord3f( 1.0f, 0.0f, 0.0f ); glVertex3d( m_corner2[ 0 ], m_corner1[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 1.0f, 1.0f, 0.0f ); glVertex3d( m_corner2[ 0 ], m_corner2[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 1.0f, 1.0f, 1.0f ); glVertex3d( m_corner2[ 0 ], m_corner2[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 1.0f, 0.0f, 1.0f ); glVertex3d( m_corner2[ 0 ], m_corner1[ 1 ], m_corner2[ 2 ] ); // y = 0 glTexCoord3f( 0.0f, 0.0f, 0.0f ); glVertex3d( m_corner1[ 0 ], m_corner1[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 1.0f, 0.0f, 0.0f ); glVertex3d( m_corner2[ 0 ], m_corner1[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 1.0f, 0.0f, 1.0f ); glVertex3d( m_corner2[ 0 ], m_corner1[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 0.0f, 0.0f, 1.0f ); glVertex3d( m_corner1[ 0 ], m_corner1[ 1 ], m_corner2[ 2 ] ); // y = 1 glTexCoord3f( 0.0f, 1.0f, 0.0f ); glVertex3d( m_corner1[ 0 ], m_corner2[ 1 ], m_corner1[ 2 ] ); glTexCoord3f( 0.0f, 1.0f, 1.0f ); glVertex3d( m_corner1[ 0 ], m_corner2[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 1.0f, 1.0f, 1.0f ); glVertex3d( m_corner2[ 0 ], m_corner2[ 1 ], m_corner2[ 2 ] ); glTexCoord3f( 1.0f, 1.0f, 0.0f ); glVertex3d( m_corner2[ 0 ], m_corner2[ 1 ], m_corner1[ 2 ] ); glEnd(); // restore texture state glUseProgram( NULL ); glDisable( GL_TEXTURE_3D ); } // draw block bounding boxes if( m_show_volume_grid ) { drawBlockWireframeBoxes(); } // restore state glBindFramebuffer( GL_FRAMEBUFFER, NULL ); glDrawBuffer( GL_BACK ); // draw from the fbo texture glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); glEnable( GL_TEXTURE_2D ); glActiveTexture( GL_TEXTURE0 ); m_fbo_color_texture->bind(); glUseProgram( m_compaction_shader.getShaderId() ); glPushMatrix(); { // draw screen-aligned quad glBegin( GL_QUADS ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, -1.0f ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, 1.0f, -1.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, -1.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, -1.0f, -1.0f ); glEnd(); } glPopMatrix(); glUseProgram( NULL ); glDisable( GL_TEXTURE_2D ); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); glDisable( GL_BLEND ); glDisable( GL_CULL_FACE ); glDisable( GL_DEPTH_TEST ); // TODO: compact list into single texture m_node_tree_controller->updateNodes( m_fbo_node_list_texture_0 ); /*m_node_tree_controller->updateNodes( m_fbo_node_list_texture_1 ); m_node_tree_controller->updateNodes( m_fbo_node_list_texture_2 );*/ CheckGLErrors(); }
void Texture2D::Init(ImagePullStream &stream) { mTex = 0; uint8_t *scanline = 0; uint8_t *extendedScanline = 0; try { mWidth = stream.GetWidth(); mHeight = stream.GetHeight(); glGenTextures(1,&mTex); CheckGLErrors(); glBindTexture(GL_TEXTURE_2D,mTex); CheckGLErrors(); int format; switch(stream.GetNumChannels()) { case 1: format = GL_LUMINANCE; break; case 3: format = GL_RGBA; break; case 4: format = GL_RGBA; break; default: throw Exception("Unsupported number of channels."); } glTexImage2D(GL_TEXTURE_2D,0,format,mWidth,mHeight,0,format,GL_UNSIGNED_BYTE,0); CheckGLErrors(); scanline = new uint8_t[mWidth * stream.GetNumChannels()]; if(stream.GetNumChannels() == 3) { extendedScanline = new uint8_t[mWidth * 4]; for(int y = 0;y < mHeight;y++) { stream.StreamScanline(scanline); uint8_t *readPtr = scanline; uint8_t *writePtr = extendedScanline; for(int x = 0;x < mWidth;x++) { for(int i = 0;i < 3;i++) *(writePtr++) = *(readPtr++); *(writePtr++) = 0xff; } glTexSubImage2D(GL_TEXTURE_2D,0,0,y,mWidth,1,format,GL_UNSIGNED_BYTE,extendedScanline); CheckGLErrors(); } } else { for(int y = 0;y < mHeight;y++) { stream.StreamScanline(scanline); glTexSubImage2D(GL_TEXTURE_2D,0,0,y,mWidth,1,format,GL_UNSIGNED_BYTE,scanline); CheckGLErrors(); } } glGenerateMipmap(GL_TEXTURE_2D); CheckGLErrors(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); CheckGLErrors(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); CheckGLErrors(); delete [] scanline; delete [] extendedScanline; } catch(...) { if(mTex) glDeleteTextures(1, &mTex); delete [] scanline; delete [] extendedScanline; throw; } }
void DrawContext::Draw(int viewport_width, int viewport_height, std::vector<Renderer*>* prenderers) { viewport_width_ = viewport_width; viewport_height_ = viewport_height; cur_camera_ = scene_->GetDefaultDrawGroup()->GetCamera(); // Clear the drawing area glClearColor(clear_color_.redF(), clear_color_.greenF(), clear_color_.blueF(), clear_color_.alphaF()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); std::vector<Renderer*>& renderers = *prenderers; // Setup the fixed-function pipeline. PrepareFixedFunctionPipeline(); // Inform the renderers that drawing is about to begin for (Renderer* renderer : renderers) { if (renderer->Enabled()) { glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_POLYGON_STIPPLE_BIT | GL_POLYGON_BIT | GL_LINE_BIT | GL_FOG_BIT | GL_LIGHTING_BIT); glMatrixMode(GL_MODELVIEW); glPushMatrix(); renderer->RenderBegin(); CheckGLErrors(renderer->Name()); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } } // Set some OpenGL state to a known configuration gl_two_sided_ = false; glDisable(GL_CULL_FACE); gl_depth_test_ = true; glEnable(GL_DEPTH_TEST); gl_depth_func_ = GL_LESS; glDepthFunc(gl_depth_func_); gl_depth_write_ = true; glDepthMask(GL_TRUE); gl_color_write_ = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_point_size_ = 1; glPointSize(gl_point_size_); gl_line_width_ = 1; glLineWidth(gl_line_width_); gl_blend_ = false; glDisable(GL_BLEND); gl_sfactor_ = GL_ONE; gl_dfactor_ = GL_ZERO; glBlendFunc(gl_sfactor_, gl_dfactor_); // Draw nodes, ordered first by draw group. for (DrawGroup* dgroup : draw_groups_) { DrawDrawGroup(dgroup); } // Setup the fixed-function pipeline again. PrepareFixedFunctionPipeline(); // Notify renderers that drawing has finished for (Renderer* renderer : renderers) { if (renderer->Enabled()) { glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_POLYGON_STIPPLE_BIT | GL_POLYGON_BIT | GL_LINE_BIT | GL_FOG_BIT | GL_LIGHTING_BIT); glMatrixMode(GL_MODELVIEW); glPushMatrix(); renderer->RenderEnd(); CheckGLErrors(renderer->Name()); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } } cur_camera_ = nullptr; }