Exemple #1
0
void OpenGLRenderer::bindFrameBufferTexture(Texture *texture) {
	if(!texture)
		return;
	OpenGLTexture *glTexture = (OpenGLTexture*)texture;
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glTexture->getFrameBufferID());
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
}
Exemple #2
0
/*************************************************************************
	Create a new Texture object and load a file into it.
*************************************************************************/
Texture* OpenGLRenderer::createTexture(const String& filename, const String& resourceGroup)
{
	OpenGLTexture* tex = (OpenGLTexture*)createTexture();
	tex->loadFromFile(filename, resourceGroup);

	return tex;
}
Exemple #3
0
/*************************************************************************
	Create a new texture with the given dimensions
*************************************************************************/
Texture* OpenGLRenderer::createTexture(float size)
{
	OpenGLTexture* tex = (OpenGLTexture*)createTexture();
	tex->setOGLTextureSize((uint)size);

	return tex;
}
Exemple #4
0
void OpenGLGraphics::SetPixel ( Uint32 _surfaceID, int x, int y, Uint32 _color )
{
    if ( _surfaceID == SCREEN_SURFACE_ID )
    {
        g_openGL->VertexArrayStatePrimitive ();
        g_openGL->DeactivateTextureRect ();
        glDisable ( GL_BLEND );
        ASSERT_OPENGL_ERRORS;
#ifndef TARGET_OS_WINDOWS
        m_vertexArray[0] = x;
        m_vertexArray[1] = y;
        _color |= FULL_ALPHA;
        g_openGL->ActivateColour ( _color );
        glDrawArrays ( GL_POINTS, 0, 1 );
#else
        glRasterPos2i ( x, y );
        ASSERT_OPENGL_ERRORS;
        glDrawPixels ( 1, 1, GL_RGBA, GL_UNSIGNED_INT, &_color );
        ASSERT_OPENGL_ERRORS;
#endif
        glEnable ( GL_BLEND );
        ASSERT_OPENGL_ERRORS;
    }
    else
    {
        ARCReleaseAssert ( m_textures.valid ( _surfaceID ) );
        OpenGLTexture *tex = m_textures.get ( _surfaceID );
        tex->SetPixel ( x, y, _color );
        tex->Damage();
    }
}
Exemple #5
0
Uint32 OpenGLGraphics::CreateSurface ( Uint32 _width, Uint32 _height, bool _isColorKeyed )
{
    OpenGLTexture *tex = new OpenGLTexture();
    tex->Create ( _width, _height, _isColorKeyed );

    Uint32 ret = m_textures.insert ( tex );

    return ret;
}
Exemple #6
0
void OpenGLRenderer::bindFrameBufferTexture(Texture *texture) {
	if(currentFrameBufferTexture) {
		previousFrameBufferTexture = currentFrameBufferTexture;
	}
	OpenGLTexture *glTexture = (OpenGLTexture*)texture;

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glTexture->getFrameBufferID());
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	currentFrameBufferTexture = texture;
}
Exemple #7
0
int OpenGLGraphics::FillRect ( Uint32 _surfaceID, SDL_Rect *_destRect, Uint32 _color )
{
    ARCReleaseAssert ( m_sdlScreen != NULL );

    if ( _color == m_colorKey )
        _color = m_colorKey & ZERO_ALPHA;

    if (_surfaceID == SCREEN_SURFACE_ID)
    {
        // fill a rectangle on screen
        g_openGL->ActivateColour ( _color );
        g_openGL->DeactivateTextureRect ();
        g_openGL->VertexArrayStatePrimitive ();

        if ( _destRect )
        {
            m_vertexArray[0] = _destRect->x;
            m_vertexArray[1] = _destRect->y;
            m_vertexArray[2] = _destRect->x + _destRect->w;
            m_vertexArray[3] = _destRect->y;
            m_vertexArray[4] = _destRect->x;
            m_vertexArray[5] = _destRect->y + _destRect->h;
            m_vertexArray[6] = _destRect->x + _destRect->w;
            m_vertexArray[7] = _destRect->y + _destRect->h;
        } else {
            m_vertexArray[0] = 0;
            m_vertexArray[1] = 0;
            m_vertexArray[2] = m_sdlScreen->m_sdlSurface->w;
            m_vertexArray[3] = 0;
            m_vertexArray[4] = 0;
            m_vertexArray[5] = m_sdlScreen->m_sdlSurface->h;
            m_vertexArray[6] = m_sdlScreen->m_sdlSurface->w;
            m_vertexArray[7] = m_sdlScreen->m_sdlSurface->h;
        }

        glDrawArrays ( GL_TRIANGLE_STRIP, 0, 4 );
        ASSERT_OPENGL_ERRORS;

        return 0;
    }
    else
    {
        ARCReleaseAssert ( m_textures.valid ( _surfaceID ) );
        OpenGLTexture *tex = m_textures.get ( _surfaceID );
        ARCReleaseAssert ( tex != NULL );

        int r = SDL_FillRect ( tex->m_sdlSurface, _destRect, _color );

        tex->Damage ();

        return r;
    }
}
Exemple #8
0
Image *OpenGLRenderer::renderBufferToImage(Texture *texture) {
    
	OpenGLTexture *glTexture = (OpenGLTexture*)texture;
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glTexture->getFrameBufferID());
    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    
	char *imageBuffer = (char*)malloc(texture->getWidth() * backingResolutionScaleX * texture->getHeight() * backingResolutionScaleY * 4);
	glReadPixels(0, 0, texture->getWidth() * backingResolutionScaleX, texture->getHeight() * backingResolutionScaleY, GL_RGBA, GL_UNSIGNED_BYTE, imageBuffer);
	Image *retImage = new Image(imageBuffer, texture->getWidth() * backingResolutionScaleX, texture->getHeight() * backingResolutionScaleY, Image::IMAGE_RGBA);
	free(imageBuffer);
    
    unbindFramebuffers();
	return retImage;
}
void OpenGLGraphics::render_overlay(CoreOverlay* overlay) {
    if (!overlay->visible()) {
        return;
    }
    
    float x = overlay->corner_x();
    float y = overlay->corner_y(); 
    
    // Now translate to the top-left corner of the overlay, and render
    // the text and background image
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glTranslatef(x, y, 0.0f);
    
    // Render the background as a single quad
    OpenGLTexture* background = static_cast<OpenGLTexture*>(overlay->background());
    if (background) {
        background->sampler(0);        
        glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(0.0f, 0.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex2f(overlay->width(), 0.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex2f(overlay->width(), overlay->height());
        glTexCoord2f(0.0f, 1.0f);
        glVertex2f(0.0f, overlay->height());    
        glEnd();
    }
    
    // Now render the text
    OpenGLFont* font = static_cast<OpenGLFont*>(overlay->font());
    if (!overlay->text().empty() && font) {
        glColor4fv(overlay->text_color());
        glPushMatrix();
        glTranslatef(0, (float)font->height(), 0);
        font->render(overlay->text());
        glPopMatrix();
    }
    
    // Render all the children
    for (Iterator<CoreOverlayPtr> i = overlay->children(); i; i++) {
        render_overlay(i->get());
    }
    
    glPopMatrix();
}
void PreparePresentationPassPrivate::constructTexture(OpenGLTexture &t, OpenGLInternalFormat f, int width, int height)
{
  t.create(OpenGLTexture::Texture2D);
  t.bind();
  t.setInternalFormat(f);
  t.setWrapMode(OpenGLTexture::DirectionS, OpenGLTexture::ClampToEdge);
  t.setWrapMode(OpenGLTexture::DirectionT, OpenGLTexture::ClampToEdge);
  t.setFilter(OpenGLTexture::Magnification, OpenGLTexture::Nearest);
  t.setFilter(OpenGLTexture::Minification, OpenGLTexture::Nearest);
  t.setSize(width, height);
  t.allocate();
  t.release();
}
void OpenGLGraphics::render_visible_quad_sets() {
	OpenGLTexture* texture = 0;

	glDisable(GL_LIGHTING);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);
	glEnable(GL_TEXTURE_2D);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor3f(1.0f, 1.0f, 1.0f);


	// Render all quad sets
	for (vector<CoreQuadSetPtr>::iterator i = quad_sets_.begin(); i != quad_sets_.end(); i++) {
		// Switch textures if necessary
		CoreQuadSet* quad_set = i->get();
		OpenGLTexture* next_texture = static_cast<OpenGLTexture*>(quad_set->texture());
		if (texture != next_texture) {
			texture = next_texture;
			texture->sampler(TS_DIFFUSE);
		}

		// Transform the modelview an dtexture matrics
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glMultMatrixf(quad_set->parent()->matrix());

		glBegin(GL_QUADS);
		for (size_t i = 0; i < quad_set->vertex_count(); i++) {
			const Vertex& v = quad_set->vertex_data()[i];
			glNormal3fv(v.normal);
			glTexCoord2fv(v.texcoord);
			glVertex3fv(v.position);
		}
		glEnd();

		// Set the matrix mode
		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();
	}

	glEnable(GL_LIGHTING);
	glEnable(GL_CULL_FACE);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);
	
}
Exemple #12
0
void OpenGLRenderer::setTexture(Texture *texture) {

	if(texture == NULL) {
		glActiveTexture(GL_TEXTURE0);		
		glDisable(GL_TEXTURE_2D);
		return;
	}
	
    glActiveTexture(GL_TEXTURE0);
    glEnable (GL_TEXTURE_2D);
            
    if(currentTexture != texture) {			
        OpenGLTexture *glTexture = (OpenGLTexture*)texture;
        glBindTexture (GL_TEXTURE_2D, glTexture->getTextureID());
    }
	
	currentTexture = texture;
}
	void OpenGLRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count)
	{
		OpenGLVertexBuffer* buffer = static_cast<OpenGLVertexBuffer*>(_buffer);
		unsigned int buffer_id = buffer->getBufferID();
		MYGUI_PLATFORM_ASSERT(buffer_id, "Vertex buffer is not created");

		unsigned int texture_id = 0;
		if (_texture)
		{
			OpenGLTexture* texture = static_cast<OpenGLTexture*>(_texture);
			texture_id = texture->getTextureID();
			//MYGUI_PLATFORM_ASSERT(texture_id, "Texture is not created");
		}

		glBindTexture(GL_TEXTURE_2D, texture_id);

		glBindBuffer(GL_ARRAY_BUFFER, buffer_id);

		// enable vertex arrays
		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_COLOR_ARRAY);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);

		// before draw, specify vertex and index arrays with their offsets
		size_t offset = 0;
		glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offset);
		offset += (sizeof(float) * 3);
		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (void*)offset);
		offset += (4);
		glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offset);

		glDrawArrays(GL_TRIANGLES, 0, _count);

		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		glDisableClientState(GL_COLOR_ARRAY);
		glDisableClientState(GL_VERTEX_ARRAY);

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
	}
Exemple #14
0
void OpenGLRenderer::renderToTexture(Texture *targetTexture) {
	OpenGLTexture *glTexture = (OpenGLTexture*)targetTexture;
	glBindTexture (GL_TEXTURE_2D, glTexture->getTextureID());
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, targetTexture->getWidth(), targetTexture->getHeight(), 0);	

}
Exemple #15
0
int OpenGLGraphics::Blit ( Uint32 _sourceSurfaceID, SDL_Rect const *_sourceRect,
                           Uint32 _destSurfaceID,   SDL_Rect const *_destRect )
{
    ARCReleaseAssert ( m_sdlScreen != NULL );

    OpenGLTexture *fromSurface = NULL;
    OpenGLTexture *toSurface = NULL;

    SDL_Rect *sourceRect = NULL;
    SDL_Rect *destRect = NULL;

    if ( _sourceSurfaceID == SCREEN_SURFACE_ID )
    {
        // trying to blit from screen?
        // not at the moment, sadly
        return -1;
    }

    // Get the SDL surface for the source surface.
    ARCReleaseAssert ( m_textures.valid ( _sourceSurfaceID ) );
    fromSurface = m_textures.get ( _sourceSurfaceID );
    ARCReleaseAssert ( fromSurface != NULL );

    // Get the SDL surface for the destination surface.
    if ( _destSurfaceID != SCREEN_SURFACE_ID )
    {
        ARCReleaseAssert ( m_textures.valid ( _destSurfaceID ) );
        toSurface = m_textures.get ( _destSurfaceID );
        ARCReleaseAssert ( toSurface != NULL );
    } else {
        toSurface = m_sdlScreen;
    }

    // With SDL, you can have a NULL destination rectangle if you are just
    // writing to 0,0 and the max possible WxH on the surface.
    SDL_Rect nullDestRect;
    if ( !_destRect )
    {
        nullDestRect.x = 0; nullDestRect.y = 0;
        nullDestRect.w = m_sdlScreen->m_sdlSurface->w;
        nullDestRect.h = m_sdlScreen->m_sdlSurface->h;
        destRect = &nullDestRect;
    } else {
        memcpy ( &nullDestRect, _destRect, sizeof(SDL_Rect) );
        destRect = &nullDestRect;
    }

    // With SDL, you can have a NULL source rectangle if you are just
    // reading from 0,0 and the max possible WxH on the surface.
    SDL_Rect nullSourceRect;
    if ( !_sourceRect )
    {
        nullSourceRect.x = 0; nullSourceRect.y = 0;
        if ( g_openGL->GetSetting ( OPENGL_TEX_ALLOW_NPOT, false ) ) {
            nullSourceRect.w = fromSurface->m_sdlSurface->w;
            nullSourceRect.h = fromSurface->m_sdlSurface->h;
        } else {
            nullSourceRect.w = fromSurface->m_originalWidth;
            nullSourceRect.h = fromSurface->m_originalHeight;
        }
        sourceRect = &nullSourceRect;
    } else {
        memcpy ( &nullSourceRect, _sourceRect, sizeof(SDL_Rect) );
        sourceRect = &nullSourceRect;
    }

    if ( destRect->x > toSurface->m_sdlSurface->w ) {
        // This blit is completely off the surface.
        return 1;
    }
    if ( destRect->y > toSurface->m_sdlSurface->h ) {
        // This blit is completely off the surface.
        return 1;
    }

    // Is this blit is going to be partially off the surface?
    if ( destRect->x + sourceRect->w > toSurface->m_sdlSurface->w )
        sourceRect->w = toSurface->m_sdlSurface->w - destRect->x;
    if ( destRect->y + sourceRect->h > toSurface->m_sdlSurface->h )
        sourceRect->h = toSurface->m_sdlSurface->h - destRect->y;

    // With SDL, you don't have to specify the dest width/height. With OpenGL, we do.
    destRect->w = sourceRect->w;
    destRect->h = sourceRect->h;

    // Now we need to do the actual blit!
    if ( _destSurfaceID == SCREEN_SURFACE_ID )
    {
        fromSurface->Upload();

        // draw from sourceSurfaceID
        g_openGL->ActivateTextureRect();
        fromSurface->Bind();
        g_openGL->ActivateWhiteWithAlpha ( fromSurface->m_alpha );
        g_openGL->VertexArrayStateTexture ();

        short *vertexArray = m_vertexArray, *texCoordArrayi = m_texCoordArrayi;
        float *texCoordArrayf = m_texCoordArrayf;
        vertexArray = m_vertexArray;

        vertexArray[0] = destRect->x;
        vertexArray[1] = destRect->y;
        vertexArray[2] = destRect->x + destRect->w;
        vertexArray[3] = destRect->y;
        vertexArray[4] = destRect->x;
        vertexArray[5] = destRect->y + destRect->h;
        vertexArray[6] = destRect->x + destRect->w;
        vertexArray[7] = destRect->y + destRect->h;

        if ( g_openGL->GetSetting ( OPENGL_USE_TEXTURE_RECTANGLES, false ) )
        {
            texCoordArrayi[0] = sourceRect->x;
            texCoordArrayi[1] = sourceRect->y;
            texCoordArrayi[2] = sourceRect->x + sourceRect->w;
            texCoordArrayi[3] = sourceRect->y;
            texCoordArrayi[4] = sourceRect->x;
            texCoordArrayi[5] = sourceRect->y + sourceRect->h;
            texCoordArrayi[6] = sourceRect->x + sourceRect->w;
            texCoordArrayi[7] = sourceRect->y + sourceRect->h;
        }
        else
        {
            float w = (float)fromSurface->m_sdlSurface->w,
                  h = (float)fromSurface->m_sdlSurface->h;
            float x = (float)sourceRect->x,
                  y = (float)sourceRect->y;
            texCoordArrayf[0] = x / w;
            texCoordArrayf[1] = y / h;
            texCoordArrayf[2] = x / w + (float)sourceRect->w / w;
            texCoordArrayf[3] = y / h;
            texCoordArrayf[4] = x / w;
            texCoordArrayf[5] = y / h + (float)sourceRect->h / h;
            texCoordArrayf[6] = x / w + (float)sourceRect->w / w;
            texCoordArrayf[7] = y / h + (float)sourceRect->h / h;
        }

        glDrawArrays ( GL_TRIANGLE_STRIP, 0, 4 );
        ASSERT_OPENGL_ERRORS;

        return 0;
    }
    else
    {

        // This is a very hackish way to do it, but the alpha settings
        // aren't preserved across blits for some reason, so this is
        // necessary!

        // Fill with fully opaque colour key.
        //SDL_FillRect ( toSurface->m_sdlSurface, destRect, FULL_ALPHA | m_colorKey );

        // Blit
        int res = SDL_BlitSurface ( fromSurface->m_sdlSurface, sourceRect, toSurface->m_sdlSurface, destRect );

        // Replace the fully opaque colour key with a fully transparent
        // colour key.
        //ReplaceColour ( _destSurfaceID, destRect, FULL_ALPHA | m_colorKey, ZERO_ALPHA & m_colorKey );

        // We want to upload the textures to graphics memory
        // later in order to make things fast.
        toSurface->Damage();

        return res;
    }

}
Exemple #16
0
void OpenGLRenderer::createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer) {
			
	GLuint depthTexture,colorTexture;
	GLenum status;
	GLuint frameBufferID;
	
	glGenFramebuffersEXT(1, &frameBufferID);   
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferID);     	
	glGenTextures(1,&colorTexture);
	glBindTexture(GL_TEXTURE_2D,colorTexture);
	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);	
	
	if(floatingPointBuffer) {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
	} else {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);	
	}
	
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTexture, 0);

	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if(status == GL_FRAMEBUFFER_COMPLETE_EXT) {
		Logger::log("color fbo generation successful\n");
	} else {
		Logger::log("color fbo generation failed\n");	
	}

	if(colorBuffer) {
		OpenGLTexture *colorBufferTexture = new OpenGLTexture(width, height);
		colorBufferTexture->setGLInfo(colorTexture, frameBufferID);
		*colorBuffer = ((Texture*)colorBufferTexture);
	}
	
	if(depthBuffer) {
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferID);     
		glGenTextures(1,&depthTexture);
		glBindTexture(GL_TEXTURE_2D,depthTexture);
		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);

	//	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
	//	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);	
		glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);	
	
		if(floatingPointBuffer) {	
			glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT16,width,height,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);
		} else {
			glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,width,height,0,GL_DEPTH_COMPONENT,GL_UNSIGNED_BYTE,0);
		}
	
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTexture, 0);

		status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

		if(status == GL_FRAMEBUFFER_COMPLETE_EXT) {
			Logger::log("depth fbo generation successful\n");
		} else {
			Logger::log("depth fbo generation failed\n");	
		}
		
		OpenGLTexture *depthBufferTexture = new OpenGLTexture(width, height);
		depthBufferTexture->setGLInfo(depthTexture, frameBufferID);	
		*depthBuffer = ((Texture*)depthBufferTexture);		
	}
	
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
Exemple #17
0
Uint32 OpenGLGraphics::GetPixel ( Uint32 _surfaceID, int x, int y )
{
    OpenGLTexture *tex = m_textures.get ( _surfaceID );
    return tex->GetPixel ( x, y );
}
Exemple #18
0
Uint32 OpenGLGraphics::LoadImage ( const char *_filename, bool _isColorKeyed )
{

    ARCReleaseAssert ( _filename != NULL );

    // Load the image from RAM.
    SDL_Surface* src = g_app->m_resource->GetImage ( _filename ); // use SDL_Image to load the image
    ARCReleaseAssert ( src != NULL );
    Uint32 oldWidth = 0, oldHeight = 0;

    Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif

    Uint32 targetW = src->w, targetH = src->h;

    if ( !g_openGL->GetSetting ( OPENGL_TEX_ALLOW_NPOT, false ) )
    {
        oldWidth = targetW, oldHeight = targetH;
        if ( !isPowerOfTwo ( targetW ) )
            targetW = nearestPowerOfTwo ( targetW );
        if ( !isPowerOfTwo ( targetH ) )
            targetH = nearestPowerOfTwo ( targetH );
        ARCReleaseAssert ( isPowerOfTwo ( targetW * targetH ) );
    }
    if ( g_openGL->GetSetting ( OPENGL_TEX_FORCE_SQUARE, false ) )
	{
		targetH = targetW = std::max ( targetW, targetH );
	}

    OpenGLTexture *tex = new OpenGLTexture();
    Uint32 ret = m_textures.insert ( tex );

    tex->Dispose();
    tex->Create ( targetW, targetH, _isColorKeyed );

    ARCReleaseAssert ( tex->m_sdlSurface != NULL );

	if ( _isColorKeyed && m_colorKeySet )
    {
		SDL_FillRect ( tex->m_sdlSurface, NULL, ZERO_ALPHA & m_colorKey );
        SDL_SetColorKey ( tex->m_sdlSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL, m_colorKey );
    }
    SDL_SetAlpha ( tex->m_sdlSurface, 0, SDL_ALPHA_OPAQUE );

    SDL_BlitSurface ( src, NULL, tex->m_sdlSurface, NULL );
    SDL_FreeSurface ( src );

    tex->Damage();

    return ret;
}
void BbqGeoRefdTerrainRenderer<HeightType, 
                               HeightDeltaType,
                               TextureType    >::activateTextures(
                                  const BbqTerrNode *node,
                                  DrawEnv *pEnv)
{
//    Profile( activateTextures );
    
    Vec2f texCoordOffset( 0, 0 );
    Vec2f texCoordScale( 1.0f / float( _oDatabaseInfo.heightTileSize - 1 ), 
                         1.0f / float( _oDatabaseInfo.heightTileSize - 1 ) );

    Vec2f coarserTexCoordOffset( 0, 0 );
    Vec2f coarserTexCoordScale( 
        1.0f / float( _oDatabaseInfo.heightTileSize - 1 ), 
        1.0f / float( _oDatabaseInfo.heightTileSize - 1 ) );

    OpenGLTexture* texture = this->uploadTexture( node, pEnv );
    OpenGLTexture* coarserTexture = 0;
    
    if( texture )
    {
        if( node->parent )
        {
            coarserTexture = this->uploadTexture( node->parent, pEnv );
            if( coarserTexture )
            {
                calculateTextureParameters( node, 
                                            node->parent, 
                                            coarserTexCoordOffset, 
                                            coarserTexCoordScale );
            }
        }
        else
        {
            coarserTexture = texture;
        }
    }
    else
    {
        // find a parent with a texture:
        const BbqTerrNode* parentNode = 0;
        texture         = findParentTexture( node, parentNode, pEnv );
        
        if( texture )
        {
            calculateTextureParameters( node, 
                                        parentNode, 
                                        texCoordOffset, 
                                        texCoordScale );
        }
        
        if( parentNode && parentNode->parent )
        {
            const BbqTerrNode* coarserParentNode = 0;
            
            coarserTexture = findParentTexture( parentNode,
                                                coarserParentNode, pEnv );
            
            if( coarserTexture  )
            {
                calculateTextureParameters( node, 
                                            coarserParentNode, 
                                            coarserTexCoordOffset, 
                                            coarserTexCoordScale );
            }
        }           
    }
    
    if( !coarserTexture )
    {
        coarserTexture = texture;
    }
    
    if( texture )
    {
        // todo: put these settings into a OpenGLTextureSampler class:
        texture->enable( GL_TEXTURE0, pEnv );

        texture0 = texture;

        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_S, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_T, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MIN_FILTER, 
                         GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MAG_FILTER, 
                         GL_LINEAR );     
        
        coarserTexture->enable( GL_TEXTURE1, pEnv );

        texture1 = coarserTexture;

        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_S, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_T, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MIN_FILTER, 
                         GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MAG_FILTER, 
                         GL_LINEAR ); 
    }
    else
    {
        // todo: use fallback texture:          
        fallbackTexture_.enable( GL_TEXTURE0, pEnv );

        texture0 = &fallbackTexture_;

        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_S, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_T, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MIN_FILTER, 
                         GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MAG_FILTER, 
                         GL_LINEAR );     
        
        fallbackTexture_.enable( GL_TEXTURE1, pEnv );

        texture1 = &fallbackTexture_;

        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_S, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_WRAP_T, 
                         GL_MIRROR_CLAMP_TO_EDGE_ATI );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MIN_FILTER, 
                         GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, 
                         GL_TEXTURE_MAG_FILTER, 
                         GL_LINEAR );     
    }
    
    heightColorTexture_.enable( GL_TEXTURE2, pEnv );

    glTexParameteri( GL_TEXTURE_2D, 
                     GL_TEXTURE_WRAP_S, 
                     GL_MIRROR_CLAMP_TO_EDGE_ATI );
    glTexParameteri( GL_TEXTURE_2D, 
                     GL_TEXTURE_WRAP_T, 
                     GL_MIRROR_CLAMP_TO_EDGE_ATI );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
    

#if 0
    fprintf(stderr, "T : %f %f | %f %f\n",
            texCoordScale[0], texCoordScale[1],
            texCoordOffset[0], texCoordOffset[1]);

    fprintf(stderr, "CT %f %f | %f %f\n",
            coarserTexCoordScale[0], coarserTexCoordScale[1],
            coarserTexCoordOffset[0], coarserTexCoordOffset[1]);
#endif

    _oTerrainShader.setUniform( "texCoordScale", texCoordScale );
    _oTerrainShader.setUniform( "texCoordOffset", texCoordOffset );
    _oTerrainShader.setUniform( "coarserTexCoordScale", coarserTexCoordScale );
    _oTerrainShader.setUniform( "coarserTexCoordOffset", coarserTexCoordOffset );
    
    _oTerrainShader.setSampler( "texture", 0 );
    _oTerrainShader.setSampler( "coarserTexture", 1 );
    //terrainShader_.setSampler( "heightColorTexture", 2 );
}