Exemple #1
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 #2
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 #3
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 #4
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;
}