CUIGameCustom::CUIGameCustom() :m_msgs_xml(NULL),m_ActorMenu(NULL),m_PdaMenu(NULL),m_window(NULL),UIMainIngameWnd(NULL),m_pMessagesWnd(NULL) { ShowGameIndicators (true); ShowCrosshair (true); }
bool ImageDrawingArea::on_expose_event( GdkEventExpose* /*event*/ ) { if ( m_pixBuf == NULL ) { return true; } Glib::Mutex::Lock lock(m_pixBufMutex); const int width = m_pixBuf->get_width(); const int height = m_pixBuf->get_height(); double validTextureWidth = 1.0; double validTextureHeight = 1.0; bool useTiledTextures = false; GLenum errorno; BeginGL(); SetImageSize( width, height ); int screenWidth = 0; int screenHeight = 0; get_window()->get_size( screenWidth, screenHeight ); // This makes sure that sampling for rendering doesn't occur on the border of pixels. const double halfPixelAdjustW = 0.25 / (double)screenWidth; const double halfPixelAdjustH = 0.25 / (double)screenHeight; glEnable( GL_TEXTURE_2D ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); // center the image glTranslated( -(m_scaleX - 1.0)/2.0 + halfPixelAdjustW, -(m_scaleY - 1.0)/2.0 + halfPixelAdjustH, 0.0); // apply mouse-drag shift glTranslated(m_shiftX, m_shiftY, 0.0); // scale the image glScaled(m_scaleX, m_scaleY, 0.0); // draw the image glBindTexture(GL_TEXTURE_2D, m_imageTextures[0]); #ifdef _WIN32 if (m_PBOSupported) { glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_PBO); errorno = glGetError(); if (errorno != GL_NO_ERROR) { m_PBOSupported = false; } else { glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, m_pixBuf->get_pixels(), GL_STREAM_DRAW_ARB); errorno = glGetError(); if (errorno != GL_NO_ERROR) { m_PBOSupported = false; } } } #endif glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_PBOSupported ? NULL : m_pixBuf->get_pixels() ); errorno = glGetError(); if (errorno != GL_NO_ERROR) { // Attempt to fall back and use a power-of-two sized texture. // This is for older cards that don't support more arbitrary // texture sizes. #ifdef _WIN32 if (m_PBOSupported) { // unbind PBO to use normal texture transfer glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0); } #endif const int textureWidth = GetMinimumPowerOfTwo(width); const int textureHeight = GetMinimumPowerOfTwo(height); validTextureWidth = (double)width / textureWidth; validTextureHeight = (double)height / textureHeight; glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL ); errorno = glGetError(); if (errorno != GL_NO_ERROR) { // The graphics doesn't seem to support this texture size. // Images must be split and then tiled. useTiledTextures = true; } else { glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_pixBuf->get_pixels() ); errorno = glGetError(); if ( errorno != GL_NO_ERROR) { // Error } } } if (useTiledTextures) { // // The image is split into multiple textures. // const int bytesPerPixel = 4; const int tileSize = 1024; int horizResidual = width % tileSize; int vertResidual = height % tileSize; int numHorizTextures = width / tileSize + (horizResidual > 0); int numVertTextures = height / tileSize + (vertResidual > 0); unsigned char *tileBuffer = new unsigned char[tileSize * tileSize * bytesPerPixel]; for (int tileY = 0; tileY < numVertTextures ; tileY++) { for (int tileX = 0; tileX < numHorizTextures; tileX++) { int subTexHeight = tileSize; if ( tileY == numVertTextures - 1 && vertResidual > 0) { subTexHeight = vertResidual; } int subTexWidth = tileSize; if (tileX == numHorizTextures - 1 && horizResidual > 0) { subTexWidth = horizResidual; } // copy image buffer to the tile for (int line = 0; line < subTexHeight; line++) { memcpy( tileBuffer + line * tileSize * bytesPerPixel, m_pixBuf->get_pixels() + ((line + tileSize * tileY) * width + tileSize * tileX) * bytesPerPixel, subTexWidth * bytesPerPixel); } const unsigned int texId = tileY * numHorizTextures + tileX; if (texId >= sk_maxNumTextures) { continue; } glBindTexture( GL_TEXTURE_2D, m_imageTextures[ texId] ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tileSize, tileSize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, tileBuffer ); const double validTileWidth = (double)subTexWidth/tileSize; const double validTileHeight = (double)subTexHeight/tileSize; const double x_begin = (double)tileSize / width * tileX; const double x_end = (double)tileSize / width * ( tileX + validTileWidth); const double y_begin = 1.0 - (double)tileSize / height * ( tileY + validTileHeight); const double y_end = 1.0 - (double)tileSize / height * tileY; glBegin( GL_QUADS ); glTexCoord2d(0.0, validTileHeight); glVertex2d(x_begin, y_begin); glTexCoord2d(validTileWidth, validTileHeight); glVertex2d(x_end, y_begin); glTexCoord2d(validTileWidth, 0.0); glVertex2d(x_end, y_end); glTexCoord2d(0.0, 0.0); glVertex2d(x_begin, y_end); glEnd(); } } delete [] tileBuffer; } else { // Just one texture glBegin( GL_QUADS ); glTexCoord2d(0.0, validTextureHeight); glVertex2d(0.0, 0.0); glTexCoord2d(validTextureWidth, validTextureHeight); glVertex2d(1.0, 0.0); glTexCoord2d(validTextureWidth, 0.0); glVertex2d(1.0, 1.0); glTexCoord2d(0.0, 0.0); glVertex2d(0.0, 1.0); glEnd(); } if ( m_showCrosshair ) { const double aspectRatio = (double)width/height; glTranslated(0.5, 0.5, 0.0); glScaled(1.0, aspectRatio, 0.0); ShowCrosshair(); } if (get_gl_window()->is_double_buffered()) { get_gl_window()->swap_buffers(); } else { glFlush(); } EndGL(); lock.release(); m_displayedFrameRate.NewFrame(); return true; }