OpenGL第十节:彩色键控与混合

Posted yongfengnice

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL第十节:彩色键控与混合相关的知识,希望对你有一定的参考价值。

LTexture.h

bool loadPixelsFromFile( std::string path );
bool loadTextureFromFileWithColorKey( std::string path, GLubyte r, GLubyte g, GLubyte b, GLubyte a = 000 );
bool loadTextureFromPixels32();

 

LTexture.cpp

bool LTexture::loadPixelsFromFile( std::string path )

{

    freeTexture();

    bool pixelsLoaded = false;

    ILuint imgID = 0;

    ilGenImages( 1, &imgID );//生成ID

    ilBindImage( imgID );//绑定

    ILboolean success = ilLoadImage( path.c_str() );//加载图片

    if( success == IL_TRUE )

    {

        success = ilConvertImage( IL_RGBA, IL_UNSIGNED_BYTE );//转为rgba

        if( success == IL_TRUE )

        {

            GLuint imgWidth = (GLuint)ilGetInteger( IL_IMAGE_WIDTH );//获取图片宽高

            GLuint imgHeight = (GLuint)ilGetInteger( IL_IMAGE_HEIGHT );

            GLuint texWidth = powerOfTwo( imgWidth );//计算对应的二次幂

            GLuint texHeight = powerOfTwo( imgHeight );

            if( imgWidth != texWidth || imgHeight != texHeight )

            {

                iluImageParameter( ILU_PLACEMENT, ILU_UPPER_LEFT );//将图片放在左上角

                iluEnlargeCanvas( (int)texWidth, (int)texHeight, 1 );//调整图像大小

            }

            GLuint size = texWidth * texHeight;

            mPixels = new GLuint[ size ];

            mImageWidth = imgWidth;

            mImageHeight = imgHeight;

            mTextureWidth = texWidth;

            mTextureHeight = texHeight;

            memcpy( mPixels, ilGetData(), size * 4 );//把像素copy到mPixels

            pixelsLoaded = true;

        }

        ilDeleteImages( 1, &imgID );

    }

    if( !pixelsLoaded )

    {

        printf( "Unable to load %s\n", path.c_str() );

    }

    return pixelsLoaded;

}

 

bool LTexture::loadTextureFromFileWithColorKey( std::string path, GLubyte r, GLubyte g, GLubyte b, GLubyte a )

{

    if( !loadPixelsFromFile( path ) )

    {

        return false;

    }

    GLuint size = mTextureWidth * mTextureHeight;

    for( int i = 0; i < size; ++i )//遍历每一个像素

    {

        //Get pixel colors

        GLubyte* colors = (GLubyte*)&mPixels[ i ];//mPixels[ i ]是32位,rgba各占8位,GLubyte是8位,强转为8位指针指向即可分别对rgba分量操作

        if( colors[ 0 ] == r && colors[ 1 ] == g && colors[ 2 ] == b && ( 0 == a || colors[ 3 ] == a ) )

        {//下面四句设置为透明

            colors[ 0 ] = 255;

            colors[ 1 ] = 255;

            colors[ 2 ] = 255;

            colors[ 3 ] = 000;

        }

    }

    return loadTextureFromPixels32();

}

bool LTexture::loadTextureFromPixels32()

{

    bool success = true;

    if( mTextureID == 0 && mPixels != NULL )

    {

        glGenTextures( 1, &mTextureID );

        glBindTexture( GL_TEXTURE_2D, mTextureID );

        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, mTextureWidth, mTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mPixels );//创建纹理

        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

        glBindTexture( GL_TEXTURE_2D, NULL );

        GLenum error = glGetError();

        if( error != GL_NO_ERROR )

        {

            printf( "Error loading texture from %p pixels! %s\n", mPixels, gluErrorString( error ) );

            success = false;

        }

        else

        {

            delete[] mPixels;

            mPixels = NULL;

        }

    }

    else

    {

        printf( "Cannot load texture from current pixels! " );

        if( mTextureID != 0 )

        {

            printf( "A texture is already loaded!\n" );

        }

        else if( mPixels == NULL )

        {

            printf( "No pixels to create texture from!\n" );

        }

        success = false;

    }

    return success;

}

 

LUtil.cpp

bool initGL(){

  ...

  glEnable( GL_BLEND );//启用混合

  glDisable( GL_DEPTH_TEST );

  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

  ...

}

bool loadMedia()

{

    if( !gCircleTexture.loadTextureFromFileWithColorKey( "circle.png", 000, 255, 255 ) )

    {

        printf( "Unable to load circle texture!\n" );

        return false;

    }

    return true;

}

void render()

{

    glClear( GL_COLOR_BUFFER_BIT );

    glColor4f( 1.f, 1.f, 1.f, 0.5f );

    gCircleTexture.render( ( SCREEN_WIDTH - gCircleTexture.imageWidth() ) / 2.f, ( SCREEN_HEIGHT - gCircleTexture.imageHeight() ) / 2.f );

    glutSwapBuffers();

}

 

bool LTexture::loadPixelsFromFile( std::string path ){    //Deallocate texture data    freeTexture();
    //Texture loading success    bool pixelsLoaded = false;
    //Generate and set current image ID    ILuint imgID = 0;    ilGenImages( 1, &imgID );    ilBindImage( imgID );
    //Load image    ILboolean success = ilLoadImage( path.c_str() );
    //Image loaded successfully    if( success == IL_TRUE )    {        //Convert image to RGBA        success = ilConvertImage( IL_RGBA, IL_UNSIGNED_BYTE );        if( success == IL_TRUE )        {            //Initialize dimensions            GLuint imgWidth = (GLuint)ilGetInteger( IL_IMAGE_WIDTH );            GLuint imgHeight = (GLuint)ilGetInteger( IL_IMAGE_HEIGHT );
            //Calculate required texture dimensions            GLuint texWidth = powerOfTwo( imgWidth );            GLuint texHeight = powerOfTwo( imgHeight );
            //Texture is the wrong size            if( imgWidth != texWidth || imgHeight != texHeight )            {                //Place image at upper left                iluImageParameter( ILU_PLACEMENT, ILU_UPPER_LEFT );
                //Resize image                iluEnlargeCanvas( (int)texWidth, (int)texHeight, 1 );            }
            //Allocate memory for texture data            GLuint size = texWidth * texHeight;            mPixels = new GLuint[ size ];
            //Get image dimensions            mImageWidth = imgWidth;            mImageHeight = imgHeight;            mTextureWidth = texWidth;            mTextureHeight = texHeight;
            //Copy pixels            memcpy( mPixels, ilGetData(), size * 4 );            pixelsLoaded = true;        }
        //Delete file from memory        ilDeleteImages( 1, &imgID );    }
    //Report error    if( !pixelsLoaded )    {        printf( "Unable to load %s\n", path.c_str() );    }
    return pixelsLoaded;}
bool LTexture::loadTextureFromFileWithColorKey( std::string path, GLubyte r, GLubyte g, GLubyte b, GLubyte a ){    //Load pixels    if( !loadPixelsFromFile( path ) )    {        return false;    }
    //Go through pixels    GLuint size = mTextureWidth * mTextureHeight;    for( int i = 0; i < size; ++i )    {        //Get pixel colors        GLubyte* colors = (GLubyte*)&mPixels[ i ];
        //Color matches        if( colors[ 0 ] == r && colors[ 1 ] == g && colors[ 2 ] == b && ( 0 == a || colors[ 3 ] == a ) )        {            //Make transparent            colors[ 0 ] = 255;            colors[ 1 ] = 255;            colors[ 2 ] = 255;            colors[ 3 ] = 000;        }    }
    //Create texture    return loadTextureFromPixels32();}

以上是关于OpenGL第十节:彩色键控与混合的主要内容,如果未能解决你的问题,请参考以下文章

IOS OpenGL ES 图像扩展边缘彩色模糊 GPUImageRGBDilationFilter

OpenGL彩色方块

将负值混合到帧缓冲区 0 opengl

是否可以使用 LWJGL 将 C++ OpenGL 代码与 Java 混合?

opengl:混合跨平台的结果不一致

使用着色器渲染“顶点彩色”三角形时的OpenGL“黑屏”