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