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! " );
    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();
}

原文地址:https://www.cnblogs.com/yongfengnice/p/7891845.html