
一、原始圖像數(shù)據(jù)
圖像存儲(chǔ)空間 = 圖像的?高度 * 圖像寬度 * 每個(gè)像素的字節(jié)數(shù)
例子:RGB(8位),寬度:199像素。圖片每行需要多少存儲(chǔ)空間?
199 * 3 * 8 = 597字節(jié)
二、認(rèn)識(shí)函數(shù)
2.1、改變/回復(fù)像素存儲(chǔ)方式
改變像素存儲(chǔ)?方式
void glPixelStorei(GLenum pname,GLint param);
恢復(fù)像素存儲(chǔ)?方式
void glPixelStoref(GLenum pname,GLfloat param);
例子:
參數(shù)1:GL_UNPACK_ALIGNMENT 指定OpenGL 如何從數(shù)據(jù)緩存區(qū)中解包圖像數(shù)據(jù)
參數(shù)2:表示參數(shù)GL_UNPACK_ALIGNMENT 設(shè)置的值
GL_UNPACK_ALIGNMENT 指內(nèi)存中每個(gè)像素行起點(diǎn)的排列請(qǐng)求,允許設(shè)置為1 (byte排列列)、2(排列為偶數(shù)byte的?)、4(字word排列)、8(?從雙字節(jié)邊界開(kāi)始)
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
2.2、從顏色緩存區(qū)內(nèi)容作為像素圖直接讀取
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei
height, GLenum format, GLenum type,const void * pixels);
參數(shù)1:x,矩形左下角的窗?坐標(biāo)
參數(shù)2:y,矩形左下角的窗?坐標(biāo)
參數(shù)3:width,矩形的寬,以像素為單位
參數(shù)4:height,矩形的高,以像素為單位
參數(shù)5:format,OpenGL 的像素格式,參考圖1
參數(shù)6:type,解釋參數(shù)pixels指向的數(shù)據(jù),告訴OpenGL 使?緩存區(qū)中的什么數(shù)據(jù)類型來(lái)存儲(chǔ)顏?色分量,像素?cái)?shù)據(jù)的數(shù)據(jù)類型,參考圖2
參數(shù)7:pixels,指向圖形數(shù)據(jù)的指針


glReadBuffer(mode);
指定讀取的緩存
glWriteBuffer(mode);
指定寫(xiě)?入的緩存
2.3、載?紋理
void glTexImage1D(GLenum target,GLint level,GLint
internalformat,GLsizei width,GLint border,GLenum
format,GLenum type,void *data);
void glTexImage2D(GLenum target,GLint level,GLint
internalformat,GLsizei width,GLsizei height,GLint
border,GLenum format,GLenum type,void * data);
void glTexImage3D(GLenum target,GLint level,GLint internalformat,GLSizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,void *data)
*target:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D。
- Level:指定所加載的mip貼圖層次。?般我們都把這個(gè)參數(shù)設(shè)置為0。
- internalformat:每個(gè)紋理單元中存儲(chǔ)多少顏色成分。
- width、height、depth參數(shù):指加載紋理理的寬度、?高度、深度。這些值必須是 2的整數(shù)次?方。(這是因?yàn)镺penGL 舊版本上的遺留留下的?一個(gè)要求。當(dāng)然現(xiàn)在已經(jīng)可以支持不是 2的整數(shù)次?方。但是開(kāi)發(fā)者們還是習(xí)慣使?用以2的整數(shù)次?方去設(shè)置這些參數(shù)。)
- border參數(shù):允許為紋理理貼圖指定?一個(gè)邊界寬度。
- format、type、data參數(shù):與我們?cè)谥vglDrawPixels 函數(shù)對(duì)于的參數(shù)相同
2.4、更新紋理
void glTexSubImage1D(GLenum target,GLint level,GLint xOffset,GLsizei width,GLenum
format,GLenum type,const GLvoid *data);
void glTexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei
width,GLsizei height,GLenum format,GLenum type,const GLvoid *data);
void glTexSubImage3D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLint
zOffset,GLsizei width,GLsizei height,GLsizei depth,Glenum type,const GLvoid * data);
2.5、插入替換紋理
void glCopyTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsize
width);
void glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint x,
y,GLsizei width,GLsizei height);
void glCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint
zOffset,GLint x,GLint y,GLsizei width,GLsizei height);
2.6、使?顏?緩存區(qū)加載數(shù)據(jù),形成新的紋理使?
void glCopyTexImage1D(GLenum target,GLint level,GLenum
internalformt,GLint x,GLint y,GLsizei width,GLint border);
void glCopyTexImage2D(GLenum target,GLint level,GLenum
internalformt,GLint x,GLint y,GLsizei width,GLsizei
height,GLint border);
x,y 在顏?緩存區(qū)中指定了開(kāi)始讀取紋理數(shù)據(jù)的位置; 緩存區(qū)里的數(shù)據(jù),是源緩存區(qū)通過(guò)glReadBuffer設(shè)置的。
注意:不存在glCopyTextImage3D ,因?yàn)槲覀?法從2D 顏?色緩存區(qū)中獲取體積數(shù)據(jù)。
三、紋理對(duì)象
void glGenTextures(GLsizei n,GLuint * textTures);
使?函數(shù)分配紋理對(duì)象
指定紋理對(duì)象的數(shù)量和指針(指針指向一個(gè)?符號(hào)整形數(shù)組,由紋理對(duì)象標(biāo)識(shí)符填充)。
void glBindTexture(GLenum target,GLunit texture);
綁定紋理理狀態(tài)
參數(shù)target:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
參數(shù)texture:需要綁定的紋理理對(duì)象
void glDeleteTextures(GLsizei n,GLuint *textures); //測(cè)試紋理理對(duì)象是否有效
刪除綁定紋理理對(duì)象
紋理對(duì)象以及紋理對(duì)象指針(指針指向一個(gè)?符號(hào)整形數(shù)組,由紋理對(duì)象標(biāo)識(shí)符填充)。
GLboolean glIsTexture(GLuint texture);
如果texture是?一個(gè)已經(jīng)分配空間的紋理理對(duì)象,那么這個(gè)函數(shù)會(huì)返回GL_TRUE,否則會(huì)返回GL_FALSE。
3.1、設(shè)置紋理參數(shù)
glTexParameterf(GLenum target,GLenum pname,GLFloat param);
glTexParameteri(GLenum target,GLenum pname,GLint param);
glTexParameterfv(GLenum target,GLenum pname,GLFloat *param);
glTexParameteriv(GLenum target,GLenum pname,GLint *param);
參數(shù)1:target,指定這些參數(shù)將要應(yīng)用在哪個(gè)紋理模式上,比如GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D。
參數(shù)2:pname,指定需要設(shè)置那個(gè)紋理參數(shù)
參數(shù)3:param,設(shè)定特定的紋理參數(shù)的值
3.2、設(shè)置過(guò)濾?式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST)
紋理縮?時(shí),使?鄰近過(guò)濾
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
紋理放大時(shí),使用線性過(guò)濾
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
3.2、設(shè)置環(huán)繞方式
| 參數(shù) | 描述 |
|---|---|
| GL_REPEAT | 對(duì)紋理的默認(rèn)行。重復(fù)紋理圖像 |
| GL_MIRRORED | 和GL_REPEAT一樣,但每次重復(fù)圖片是鏡像放置的。 |
| GL_CLAMP_TO_EDGE | 紋理坐標(biāo)會(huì)被約束在0到1之間,超出部分會(huì)重復(fù)紋理坐標(biāo)的邊緣,產(chǎn)生一種邊緣被拉伸的效果。 |
| GL_CLAMP_TO_BORDER | 超出的坐標(biāo)為用戶指定的邊緣顏色。 |
當(dāng)紋理坐標(biāo)超出默認(rèn)范圍時(shí),每個(gè)選項(xiàng)都有不同視覺(jué)效果輸出。我們來(lái)看看這些紋理圖像的例子:

glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);
參數(shù)1:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
參數(shù)2:GL_TEXTURE_WRAP_S、GL_TEXTURE_T、GL_TEXTURE_R,針對(duì)s,t,r坐標(biāo)
參數(shù)3:GL_REPEAT、GL_CLAMP、GL_CLAMP_TO_EDGE、GL_CLAMP_TO_BORDER
GL_REPEAT:OpenGL 在紋理坐標(biāo)超過(guò)1.0的?向上對(duì)紋理進(jìn)?重復(fù);
GL_CLAMP:所需的紋理單元取?紋理邊界或TEXTURE_BORDER_COLOR. GL_CLAMP_TO_EDGE環(huán)繞模式強(qiáng)制對(duì)范圍之外的紋理坐標(biāo)沿著合法的紋理單元的最后??或者最后一列來(lái)進(jìn)?采樣。
GL_CLAMP_TO_BORDER:在紋理坐標(biāo)在0.0到1.0范圍之外的只使?邊界紋理單元。邊界紋理單元是作為圍繞基本圖像的額外的行和列,并與基本紋理圖像一起加載的。
四、金字塔案例
#include "GLTools.h"
#include "GLShaderManager.h"
#include "GLFrustum.h"
#include "GLBatch.h"
#include "GLFrame.h"
#include "GLMatrixStack.h"
#include "GLGeometryTransform.h"
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
GLShaderManager shaderManager;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrame cameraFrame;
GLFrame objectFrame;
GLFrustum viewFrustum;
GLBatch pyramidBatch;
//紋理變量,一般使用無(wú)符號(hào)整型
GLuint textureID;
GLGeometryTransform transformPipeline;
M3DMatrix44f shadowMatrix;
//繪制金字塔
void MakePyramid(GLBatch& pyramidBatch)
{
/*1、通過(guò)pyramidBatch組建三角形批次
參數(shù)1:類型
參數(shù)2:頂點(diǎn)數(shù)
參數(shù)3:這個(gè)批次中將會(huì)應(yīng)用1個(gè)紋理
注意:如果不寫(xiě)這個(gè)參數(shù),默認(rèn)為0。
*/
pyramidBatch.Begin(GL_TRIANGLES, 18, 1);
/***前情導(dǎo)入
1)設(shè)置法線
void Normal3f(GLfloat x, GLfloat y, GLfloat z);
Normal3f:添加一個(gè)表面法線(法線坐標(biāo) 與 Vertex頂點(diǎn)坐標(biāo)中的Y軸一致)
表面法線是有方向的向量,代表表面或者頂點(diǎn)面對(duì)的方向(相反的方向)。在多數(shù)的關(guān)照模式下是必須使用。后面的課程會(huì)詳細(xì)來(lái)講法線的應(yīng)用
pyramidBatch.Normal3f(X,Y,Z);
2)設(shè)置紋理坐標(biāo)
void MultiTexCoord2f(GLuint texture, GLclampf s, GLclampf t);
參數(shù)1:texture,紋理層次,對(duì)于使用存儲(chǔ)著色器來(lái)進(jìn)行渲染,設(shè)置為0
參數(shù)2:s:對(duì)應(yīng)頂點(diǎn)坐標(biāo)中的x坐標(biāo)
參數(shù)3:t:對(duì)應(yīng)頂點(diǎn)坐標(biāo)中的y
(s,t,r,q對(duì)應(yīng)頂點(diǎn)坐標(biāo)的x,y,z,w)
pyramidBatch.MultiTexCoord2f(0,s,t);
3)void Vertex3f(GLfloat x, GLfloat y, GLfloat z);
void Vertex3fv(M3DVector3f vVertex);
向三角形批次類添加頂點(diǎn)數(shù)據(jù)(x,y,z);
pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f);
4)獲取從三點(diǎn)找到一個(gè)法線坐標(biāo)(三點(diǎn)確定一個(gè)面)
void m3dFindNormal(result,point1, point2,point3);
參數(shù)1:結(jié)果
參數(shù)2-4:3個(gè)頂點(diǎn)數(shù)據(jù)
*/
//塔頂
M3DVector3f vApex = { 0.0f, 1.0f, 0.0f };
M3DVector3f vFrontLeft = { -1.0f, -1.0f, 1.0f };
M3DVector3f vFrontRight = { 1.0f, -1.0f, 1.0f };
M3DVector3f vBackLeft = { -1.0f, -1.0f, -1.0f };
M3DVector3f vBackRight = { 1.0f, -1.0f, -1.0f };
M3DVector3f n;
//金字塔底部
//底部的四邊形 = 三角形X + 三角形Y
//三角形X = (vBackLeft,vBackRight,vFrontRight)
//1.找到三角形X 法線
m3dFindNormal(n, vBackLeft, vBackRight, vFrontRight);
//vBackLeft
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackLeft);
//vBackRight
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackRight);
//vFrontRight
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
pyramidBatch.Vertex3fv(vFrontRight);
//三角形Y =(vFrontLeft,vBackLeft,vFrontRight)
//1.找到三角形X 法線
m3dFindNormal(n, vFrontLeft, vBackLeft, vFrontRight);
//vFrontLeft
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
pyramidBatch.Vertex3fv(vFrontLeft);
//vBackLeft
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackLeft);
//vFrontRight
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
pyramidBatch.Vertex3fv(vFrontRight);
// 金字塔前面
//三角形:(Apex,vFrontLeft,vFrontRight)
m3dFindNormal(n, vApex, vFrontLeft, vFrontRight);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
pyramidBatch.Vertex3fv(vApex);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
pyramidBatch.Vertex3fv(vFrontLeft);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
pyramidBatch.Vertex3fv(vFrontRight);
//金字塔左邊
//三角形:(vApex, vBackLeft, vFrontLeft)
m3dFindNormal(n, vApex, vBackLeft, vFrontLeft);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
pyramidBatch.Vertex3fv(vApex);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackLeft);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
pyramidBatch.Vertex3fv(vFrontLeft);
//金字塔右邊
//三角形:(vApex, vFrontRight, vBackRight)
m3dFindNormal(n, vApex, vFrontRight, vBackRight);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
pyramidBatch.Vertex3fv(vApex);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
pyramidBatch.Vertex3fv(vFrontRight);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackRight);
//金字塔后邊
//三角形:(vApex, vBackRight, vBackLeft)
m3dFindNormal(n, vApex, vBackRight, vBackLeft);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
pyramidBatch.Vertex3fv(vApex);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackRight);
pyramidBatch.Normal3fv(n);
pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
pyramidBatch.Vertex3fv(vBackLeft);
//結(jié)束批次設(shè)置
pyramidBatch.End();
}
// 將TGA文件加載為2D紋理。
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
GLbyte *pBits;
int nWidth, nHeight, nComponents;
GLenum eFormat;
//1、讀紋理位,讀取像素
//參數(shù)1:紋理文件名稱
//參數(shù)2:文件寬度地址
//參數(shù)3:文件高度地址
//參數(shù)4:文件組件地址
//參數(shù)5:文件格式地址
//返回值:pBits,指向圖像數(shù)據(jù)的指針
pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
if(pBits == NULL)
return false;
//2、設(shè)置紋理參數(shù)
//參數(shù)1:紋理維度
//參數(shù)2:為S/T坐標(biāo)設(shè)置模式
//參數(shù)3:wrapMode,環(huán)繞模式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
//參數(shù)1:紋理維度
//參數(shù)2:線性過(guò)濾
//參數(shù)3:wrapMode,環(huán)繞模式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
//3.載入紋理
//參數(shù)1:紋理維度
//參數(shù)2:mip貼圖層次
//參數(shù)3:紋理單元存儲(chǔ)的顏色成分(從讀取像素圖是獲得)
//參數(shù)4:加載紋理寬
//參數(shù)5:加載紋理高
//參數(shù)6:加載紋理的深度
//參數(shù)7:像素?cái)?shù)據(jù)的數(shù)據(jù)類型(GL_UNSIGNED_BYTE,每個(gè)顏色分量都是一個(gè)8位無(wú)符號(hào)整數(shù))
//參數(shù)8:指向紋理圖像數(shù)據(jù)的指針
glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0,
eFormat, GL_UNSIGNED_BYTE, pBits);
//使用完畢釋放pBits
free(pBits);
//4.加載Mip,紋理生成所有的Mip層
//參數(shù):GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
void SetupRC()
{
//1.
glClearColor(0.7f, 0.7f, 0.7f, 1.0f );
shaderManager.InitializeStockShaders();
//2.
glEnable(GL_DEPTH_TEST);
//3.
//分配紋理對(duì)象 參數(shù)1:紋理對(duì)象個(gè)數(shù),參數(shù)2:紋理對(duì)象指針
glGenTextures(1, &textureID);
//綁定紋理狀態(tài) 參數(shù)1:紋理狀態(tài)2D 參數(shù)2:紋理對(duì)象
glBindTexture(GL_TEXTURE_2D, textureID);
//將TGA文件加載為2D紋理。
//參數(shù)1:紋理文件名稱
//參數(shù)2&參數(shù)3:需要縮小&放大的過(guò)濾器
//參數(shù)4:紋理坐標(biāo)環(huán)繞模式
LoadTGATexture("stone.tga", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, GL_CLAMP_TO_EDGE);
//4.創(chuàng)造金字塔pyramidBatch
MakePyramid(pyramidBatch);
//5.
/**相機(jī)frame MoveForward(平移)
參數(shù)1:Z,深度(屏幕到圖形的Z軸距離)
*/
cameraFrame.MoveForward(-10);
}
// 清理…例如刪除紋理對(duì)象
void ShutdownRC(void)
{
glDeleteTextures(1, &textureID);
}
void RenderScene(void)
{
//1.顏色值&光源位置
static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f };
static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f };
//2.清理緩存區(qū)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//3.當(dāng)前模型視頻壓棧
modelViewMatrix.PushMatrix();
//添加照相機(jī)矩陣
M3DMatrix44f mCamera;
//從camraFrame中獲取一個(gè)4*4的矩陣
cameraFrame.GetCameraMatrix(mCamera);
//矩陣乘以矩陣堆棧頂部矩陣,相乘結(jié)果存儲(chǔ)到堆棧的頂部 將照相機(jī)矩陣 與 當(dāng)前模型矩陣相乘 壓入棧頂
modelViewMatrix.MultMatrix(mCamera);
//創(chuàng)建mObjectFrame矩陣
M3DMatrix44f mObjectFrame;
//從objectFrame中獲取矩陣,objectFrame保存的是特殊鍵位的變換矩陣
objectFrame.GetMatrix(mObjectFrame);
//矩陣乘以矩陣堆棧頂部矩陣,相乘結(jié)果存儲(chǔ)到堆棧的頂部 將世界變換矩陣 與 當(dāng)前模型矩陣相乘 壓入棧頂
modelViewMatrix.MultMatrix(mObjectFrame);
//4.綁定紋理,因?yàn)槲覀兊捻?xiàng)目中只有一個(gè)紋理。如果有多個(gè)紋理。綁定紋理很重要
glBindTexture(GL_TEXTURE_2D, textureID);
/*5.點(diǎn)光源著色器
參數(shù)1:GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF(著色器標(biāo)簽)
參數(shù)2:模型視圖矩陣
參數(shù)3:投影矩陣
參數(shù)4:視點(diǎn)坐標(biāo)系中的光源位置
參數(shù)5:基本漫反射顏色
參數(shù)6:圖形顏色(用紋理就不需要設(shè)置顏色。設(shè)置為0)
*/
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
transformPipeline.GetModelViewMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos, vWhite, 0);
//pyramidBatch 繪制
pyramidBatch.Draw();
//模型視圖出棧,恢復(fù)矩陣(push一次就要pop一次)
modelViewMatrix.PopMatrix();
//6.交換緩存區(qū)
glutSwapBuffers();
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_DOWN)
objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_LEFT)
objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);
if(key == GLUT_KEY_RIGHT)
objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f);
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
//1.設(shè)置視口
glViewport(0, 0, w, h);
//2.創(chuàng)建投影矩陣
viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
//viewFrustum.GetProjectionMatrix() 獲取viewFrustum投影矩陣
//并將其加載到投影矩陣堆棧上
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
//3.設(shè)置變換管道以使用兩個(gè)矩陣堆棧(變換矩陣modelViewMatrix ,投影矩陣projectionMatrix)
//初始化GLGeometryTransform 的實(shí)例transformPipeline.通過(guò)將它的內(nèi)部指針設(shè)置為模型視圖矩陣堆棧 和 投影矩陣堆棧實(shí)例,來(lái)完成初始化
//當(dāng)然這個(gè)操作也可以在SetupRC 函數(shù)中完成,但是在窗口大小改變時(shí)或者窗口創(chuàng)建時(shí)設(shè)置它們并沒(méi)有壞處。而且這樣可以一次性完成矩陣和管線的設(shè)置。
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("Pyramid");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}
