OpenGL第九节:操作像素点去更新纹理
LTexture.h
bool lock();
bool unlock();
GLuint* getPixelData32();//获取像素
GLuint getPixel32( GLuint x, GLuint y );//获取x,y位置对应的像素点
void setPixel32( GLuint x, GLuint y, GLuint pixel );//设置x,y位置对应的像素点
private:
GLuint* mPixels;//指向当前像素
LTexture.cpp
LTexture::LTexture()
{
...
mPixels = NULL;
}
void LTexture::freeTexture()
{
if( mPixels != NULL )
{
delete[] mPixels;
mPixels = NULL;
}
...
}
bool LTexture::lock()
{
if( mPixels == NULL && mTextureID != 0 )//mPixels == NULL表示此时没有lock
{
GLuint size = mTextureWidth * mTextureHeight;
mPixels = new GLuint[ size ];//给纹理分配内存
glBindTexture( GL_TEXTURE_2D, mTextureID );//绑定
glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, mPixels );//获取像素,mPixels是传出参数
glBindTexture( GL_TEXTURE_2D, NULL );//解除绑定
return true;
}
return false;
}
bool LTexture::unlock()
{
if( mPixels != NULL && mTextureID != 0 )// mPixels != NULL 表示此时没有unlock
{
glBindTexture( GL_TEXTURE_2D, mTextureID );//绑定
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, mTextureWidth, mTextureHeight, GL_RGBA, GL_UNSIGNED_BYTE, mPixels );//更新纹理,此方法比销毁纹理后再执行glTexImage2D()高效
delete[] mPixels;//释放内存
mPixels = NULL;
glBindTexture( GL_TEXTURE_2D, NULL );解除绑定
return true;
}
return false;
}
GLuint* LTexture::getPixelData32()
{
return mPixels;
}
GLuint LTexture::getPixel32( GLuint x, GLuint y )
{
return mPixels[ y * mTextureWidth + x ];
}
void LTexture::setPixel32( GLuint x, GLuint y, GLuint pixel )
{
mPixels[ y * mTextureWidth + x ] = pixel;
}
LUtil.cpp
LTexture gCircleTexture;
bool loadMedia()
{
if( !gCircleTexture.loadTextureFromFile( "circle.png" ) )
{
printf( "Unable to load circle texture!\n" );
return false;
}
gCircleTexture.lock();//lock上,获取像素
GLuint targetColor;//构造一个颜色
GLubyte* colors = (GLubyte*)&targetColor;
colors[ 0 ] = 000;
colors[ 1 ] = 255;
colors[ 2 ] = 255;
colors[ 3 ] = 255;
GLuint* pixels = gCircleTexture.getPixelData32();
GLuint pixelCount = gCircleTexture.textureWidth() * gCircleTexture.textureHeight();
for( int i = 0; i < pixelCount; ++i )
{
if( pixels[ i ] == targetColor )//如果等于上面构造的颜色,将其置为透明
{
pixels[ i ] = 0;
}
}
for( int y = 0; y < gCircleTexture.imageHeight(); ++y )
{
for( int x = 0; x < gCircleTexture.imageWidth(); ++x )
{
if( y % 10 != x % 10 )
{
gCircleTexture.setPixel32( x, y, 0 );//对角线置为透明
}
}
}
gCircleTexture.unlock();//unlock,更新纹理
return true;
}
void render()
{
glClear( GL_COLOR_BUFFER_BIT );
gCircleTexture.render( ( SCREEN_WIDTH - gCircleTexture.imageWidth() ) / 2.f, ( SCREEN_HEIGHT - gCircleTexture.imageHeight() ) / 2.f );
glutSwapBuffers();
}