OpenGL6-纹理动画
?
代碼下載
#include "CELLWinApp.hpp"
#include <gl/GLU.h>
#include <assert.h>
#include <math.h>
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"winmm.lib")
/**
* 這個(gè)例子展示如何做紋理動(dòng)畫
* glMatriModel();
* 主要使用glTranslatef();
* glScalef();
* glRoatef()函數(shù)
* 按下 't'建,做移動(dòng)紋理
* 按下 's'鍵,縮放紋理
* 按下 'r'旋轉(zhuǎn)文件
*/
/**
* 頂點(diǎn)結(jié)構(gòu)聲明,u,v作弊啊飄
*/
struct Vertex
{
float u,v;
/**
* 頂點(diǎn)坐標(biāo)
*/
float x, y, z;
};
Vertex g_cubeVertices[] =
{
{ 0, 0, -1.0f,-1.0f, 1.0f },
{ 1, 0, 1.0f,-1.0f, 1.0f },
{ 1, 1, 1.0f, 1.0f, 1.0f },
{ 0, 1, -1.0f, 1.0f, 1.0f },
};
class Tutorial5 :public CELL::Graphy::CELLWinApp
{
public:
Tutorial5(HINSTANCE hInstance)
:CELL::Graphy::CELLWinApp(hInstance)
,_primitiveType(GL_POINTS)
,_flag('T')
{
}
virtual void render()
{
do
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
static float fXrot = 0.0f;
/**
* 獲取一幀繪制的時(shí)間
*/
static DWORD dwBegin = timeGetTime();
float fElpased = float(timeGetTime() - dwBegin) * 0.001f;
dwBegin = timeGetTime();
/**
* 指明,要操作的矩陣是模型矩陣
*/
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0f, 0.0f, -5.0f );
/**
* 指定操作紋理矩陣
*/
glMatrixMode(GL_TEXTURE);
/**
* 平移矩陣
*/
if (_flag == 'T')
{
glTranslatef(fElpased,0,0);
}
/**
* 縮放矩陣
*/
else if (_flag == 'S')
{
glScalef(fElpased + 1,fElpased + 1,fElpased + 1);
}
/**
* 旋轉(zhuǎn)矩陣
*/
else if (_flag == 'R')
{
/**
* OpenGL中使用的是角度,將弧度轉(zhuǎn)化為角度
*/
#define RAD2DEG 57.2957795130823208f
glRotatef(fElpased * RAD2DEG,0,0,1);
}
/**
* 使用紋理
*/
glBindTexture(GL_TEXTURE_2D,_textureId);
glInterleavedArrays( GL_T2F_V3F, 0, g_cubeVertices );
glDrawArrays( GL_QUADS, 0, 4 );
SwapBuffers( _hDC );
} while (false);
}
/**
* 生成投影矩陣
* 后面為了重用性,我們會(huì)寫一個(gè)專門的matrix類,完成矩陣的一系列擦做
* 這個(gè)是很有必須要的,當(dāng)你對(duì)Opengl了解的不斷深入,你會(huì)發(fā)現(xiàn),很多都是和數(shù)學(xué)有關(guān)的
*/
void perspective(float fovy,float aspect,float zNear,float zFar,float matrix[4][4])
{
assert(aspect != float(0));
assert(zFar != zNear);
#define PI 3.14159265358979323f
float rad = fovy * (PI / 180);
float halfFovy = tan(rad / float(2));
matrix[0][0] = float(1) / (aspect * halfFovy);
matrix[1][1] = float(1) / (halfFovy);
matrix[2][2] = -(zFar + zNear) / (zFar - zNear);
matrix[2][3] = -float(1);
matrix[3][2] = -(float(2) * zFar * zNear) / (zFar - zNear);
#undef PI
}
virtual void onInit()
{
/**
* 調(diào)用父類的函數(shù)。
*/
CELL::Graphy::CELLWinApp::onInit();
/**
* 設(shè)置Opengl的投影方式,改例子里面,我們使用正交投影
* OpenGL的投影方式有兩種(我知道的):正交,和透視,有興趣的可以google下
* 這里采用的窗口坐標(biāo)系,與Windows窗口坐標(biāo)一直,左上角為 0,0,右下角為 _winWidth,_winHeight
* 這種投影下繪制出來的物體沒有三維感
*/
//glOrtho(0,_winWidth,_winHeight,0,1,-1);
//! 修改投影方式-透視投影,
//! 指定我們要進(jìn)行操作的矩陣,OpenGL是一個(gè)狀態(tài)機(jī),所以要操作那一個(gè)狀態(tài)的時(shí)候,需要進(jìn)行切換
//! 下面的這句話就是切換到投影矩陣上
//! gluPerspective細(xì)節(jié)實(shí)現(xiàn),參照下面的網(wǎng)址:http://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
glMatrixMode( GL_PROJECTION );
#if 0
glLoadIdentity();
gluPerspective( 45.0, (GLdouble)_winWidth / (GLdouble)_winHeight, 0.1, 100.0);
float mat[4][4];
glGetFloatv(GL_PROJECTION_MATRIX,(float*)mat);
#else
//! 這里我們也可以自己按照Opengl的投影方式生成一個(gè)投影矩陣,
//! 然后將投影矩陣給OpenGL
GLfloat matrix[4][4] =
{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
};
perspective(45.0f, (GLfloat)_winWidth / (GLfloat)_winHeight, 0.1f, 100.0f,matrix);
glLoadMatrixf((float*)matrix);
#endif
glClearColor(0,0,0,1);
/**
* 增加如下兩句話
* glEnable(GL_DEPTH_TEST); 啟動(dòng)深度測(cè)試,這樣,有遮擋計(jì)算,被遮蓋的將覆蓋
* glEnable(GL_TEXTURE_2D); 啟動(dòng)紋理,支持紋理貼圖,這樣才可以繪制紋理出來
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
/**
* 讀一個(gè)bmp圖片
*/
HBITMAP hBmp = (HBITMAP)LoadImageA(0,"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
/**
* 獲取圖片的大小
*/
BITMAP bmpInf = {0};
GetObject(hBmp,sizeof(bmpInf),&bmpInf);
/**
* 獲取圖片的顏色數(shù)據(jù)(r,g,b)
*/
int size = bmpInf.bmHeight * bmpInf.bmWidth * 3;
char* data = new char[size];
BITMAPINFO bi;
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = bmpInf.bmWidth;
bi.bmiHeader.biHeight = bmpInf.bmHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = size;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
/**
* 獲取rgb數(shù)據(jù)
*/
int idata = GetDIBits(_hDC,hBmp,0,bi.bmiHeader.biHeight,data,&bi,DIB_RGB_COLORS);
/**
* 產(chǎn)生一個(gè)紋理Id,可以認(rèn)為是紋理句柄,后面的操作將書用這個(gè)紋理id
*/
glGenTextures( 1, &_textureId );
/**
* 使用這個(gè)紋理id,或者叫綁定(關(guān)聯(lián))
*/
glBindTexture( GL_TEXTURE_2D, _textureId );
/**
* 指定紋理的放大,縮小濾波,使用線性方式,即當(dāng)圖片放大的時(shí)候插值方式
*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
/**
* 將圖片的rgb數(shù)據(jù)上傳給opengl.
*/
glTexImage2D(
GL_TEXTURE_2D, //! 指定是二維圖片
0, //! 指定為第一級(jí)別,紋理可以做mipmap,即lod,離近的就采用級(jí)別大的,遠(yuǎn)則使用較小的紋理
GL_RGB, //! 紋理的使用的存儲(chǔ)格式
bmpInf.bmWidth, //! 寬度,老一點(diǎn)的顯卡,不支持不規(guī)則的紋理,即寬度和高度不是2^n。
bmpInf.bmHeight, //! 寬度,老一點(diǎn)的顯卡,不支持不規(guī)則的紋理,即寬度和高度不是2^n。
0, //! 是否的邊
GL_BGR_EXT, //! 數(shù)據(jù)的格式,bmp中,windows,操作系統(tǒng)中存儲(chǔ)的數(shù)據(jù)是bgr格式
GL_UNSIGNED_BYTE, //! 數(shù)據(jù)是8bit數(shù)據(jù)
data
);
delete []data;
/**
* 刪除圖片
*/
DeleteObject(hBmp);
}
virtual int events(unsigned msg, unsigned wParam, unsigned lParam)
{
switch(msg)
{
case WM_KEYDOWN:
{
if (wParam == 'S' ||wParam == 'S')
{
_primitiveType += 1;
if (_primitiveType >=GL_POLYGON )
{
_primitiveType = 0;
}
}
_flag = wParam;
}
break;
}
return __super::events(msg,wParam,lParam);
}
protected:
unsigned _primitiveType;
/**
* 保存紋理Id
*/
unsigned _textureId;
/**
* 標(biāo)志,移動(dòng) = 't',旋轉(zhuǎn) = 'r' 縮放='s'
*/
unsigned _flag;
};
int CALLBACK _tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nShowCmd
)
{
(void*)hInstance;
(void*)hPrevInstance;
(void*)lpCmdLine;
(void*)nShowCmd;
Tutorial5 winApp(hInstance);
winApp.start(640,480);
return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/zhanglitong/p/3189718.html
總結(jié)
以上是生活随笔為你收集整理的OpenGL6-纹理动画的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 队列 VS 堆栈
- 下一篇: 淘宝JavaScript 编码风格规范