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
", 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!
" );
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!
" );
return 1;
}
if( !loadMedia() )//加载媒体,该方法根据像素创建纹理
{
printf( "Unable to load media!
" );
return 2;
}
glutDisplayFunc( render );
glutTimerFunc( 1000 / SCREEN_FPS, runMainLoop, 0 );
glutMainLoop();
return 0;
}