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