OpenGL第五节:纹理贴图和像素操作


LOpengGL.h不变

 

LTexture.h

#include "LOpenGL.h"
#include <stdio.h>

class LTexture
{
public:
LTexture();

~LTexture();

bool loadTextureFromPixels32( GLuint* pixels, GLuint width, GLuint height );//根据像素创建或者说加载纹理

void freeTexture();//释放

void render( GLfloat x, GLfloat y );//渲染

GLuint getTextureID();

GLuint textureWidth();

GLuint textureHeight();

private:
GLuint mTextureID;//纹理ID

GLuint mTextureWidth;//纹理宽
GLuint mTextureHeight;//纹理高
};

 

LUtil.h

bool loadMedia();//添加加载资源的方法

 

LTexture.cpp

LTexture::LTexture()//构造函数
{
  mTextureID = 0;
  mTextureWidth = 0;
  mTextureHeight = 0;
}

LTexture::~LTexture()//析构函数
{
  freeTexture();
}

void LTexture::freeTexture()
{
  if( mTextureID != 0 )//删除纹理
  {
    glDeleteTextures( 1, &mTextureID );
    mTextureID = 0;
  }

  mTextureWidth = 0;
  mTextureHeight = 0;
}

bool LTexture::loadTextureFromPixels32( GLuint* pixels, GLuint width, GLuint height )
{
  freeTexture();//如果存在了就先释放

  mTextureWidth = width;
  mTextureHeight = height;

  glGenTextures( 1, &mTextureID );//生成一个纹理ID

  glBindTexture( GL_TEXTURE_2D, mTextureID );//然后绑定到TEXTURE_2D

  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );//生成纹理,参数:纹理类型,映射级别,纹理存储像素格式,宽度,高度,边框宽度,传进来的像素格式,传进来的像素的数据类型,传进来的像素

  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );//设置参数,magnify放大时按线性放大
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );//设置参数,minify缩小时按线性缩小

  glBindTexture( GL_TEXTURE_2D, NULL );//解除绑定

  GLenum error = glGetError();
  if( error != GL_NO_ERROR )
  {
    printf( "Error loading texture from %p pixels! %s\n", pixels, gluErrorString( error ) );
    return false;
  }

  return true;
}

void LTexture::render( GLfloat x, GLfloat y )
{
  if( mTextureID != 0 )
  {
    glLoadIdentity();//重置为单位矩阵,去掉之前的移动等操作

    glTranslatef( x, y, 0.f );

    glBindTexture( GL_TEXTURE_2D, mTextureID );

    glBegin( GL_QUADS );
      glTexCoord2f( 0.f, 0.f ); glVertex2f( 0.f, 0.f );//glTexCoord2f方法的参数分别是s,t,取值0~1 。s代表水平方向,t代表竖直方向,(0,0)代表左上角,(1,0)代表右上角,(1,1)代表右下角,(0,0)代表左下角
      glTexCoord2f( 1.f, 0.f ); glVertex2f( mTextureWidth, 0.f );
      glTexCoord2f( 1.f, 1.f ); glVertex2f( mTextureWidth, mTextureHeight );
      glTexCoord2f( 0.f, 1.f ); glVertex2f( 0.f, mTextureHeight );
    glEnd();
  }
}

纹理坐标如下图所示:

  

GLuint LTexture::getTextureID()
{
  return mTextureID;
}

GLuint LTexture::textureWidth()
{
  return mTextureWidth;
}

GLuint LTexture::textureHeight()
{
  return mTextureHeight;
}

 

LUtil.cpp

LTexture gCheckerBoardTexture;

bool loadMedia()
{
  const int CHECKERBOARD_WIDTH = 128;//棋盘的宽,需要是2的幂次方
  const int CHECKERBOARD_HEIGHT = 128;//期盼的高
  const int CHECKERBOARD_PIXEL_COUNT = CHECKERBOARD_WIDTH * CHECKERBOARD_HEIGHT;//总的像素数
  GLuint checkerBoard[ CHECKERBOARD_PIXEL_COUNT ];

  for( int i = 0; i < CHECKERBOARD_PIXEL_COUNT; ++i )//遍历每个像素,然后复制
  {
    GLubyte* colors = (GLubyte*)&checkerBoard[ i ];//一个像素是32位,rgba各8位,强制转化为一个8位的指针指向它,这样可以分别操作r,g,b,a每种颜色

    if(i / 128 & 16   ^   i % 128 & 16 )//间隔
    {//设置为白色
      colors[ 0 ] = 0xFF;//r
      colors[ 1 ] = 0xFF;//g
      colors[ 2 ] = 0xFF;//b
      colors[ 3 ] = 0xFF;//a
    }
    else
    {//设置为红色
      colors[ 0 ] = 0xFF;
      colors[ 1 ] = 0x00;
      colors[ 2 ] = 0x00;
      colors[ 3 ] = 0xFF;
    }
  }

  if( !gCheckerBoardTexture.loadTextureFromPixels32( checkerBoard, CHECKERBOARD_WIDTH, CHECKERBOARD_HEIGHT ) )//创建纹理
  {
    printf( "Unable to load checkerboard texture!\n" );
    return false;
  }

  return true;
  }

void render()
{
  glClear( GL_COLOR_BUFFER_BIT );

  GLfloat x = ( SCREEN_WIDTH - gCheckerBoardTexture.textureWidth() ) / 2.f;//中心点
  GLfloat y = ( SCREEN_HEIGHT - gCheckerBoardTexture.textureHeight() ) / 2.f;

  gCheckerBoardTexture.render( x, y );//绘制

  glutSwapBuffers();//更新屏幕
}

 

main.cpp

int main( int argc, char* args[] )
{
  glutInit( &argc, args );

  glutInitContextVersion( 2, 1 );

  glutInitDisplayMode( GLUT_DOUBLE );
  glutInitWindowSize( SCREEN_WIDTH, SCREEN_HEIGHT );
  glutCreateWindow( "OpenGL" );

  if( !initGL() )//初始化OpenGL
  {
    printf( "Unable to initialize graphics library!\n" );
    return 1;
  }

  if( !loadMedia() )//加载媒体,该方法根据像素创建纹理
  {
    printf( "Unable to load media!\n" );
    return 2;
  }

  glutDisplayFunc( render );

  glutTimerFunc( 1000 / SCREEN_FPS, runMainLoop, 0 );

  glutMainLoop();

  return 0;
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM