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;
}