當(dāng)看完這一課之后,我開始感覺我對OpenlGL有了一定基礎(chǔ)了.我不知道為什么.我能夠很好理解它.
lesson_9當(dāng)中并沒有多大新的知識.全是我們之前所學(xué)的.卻需要完整的組織起來.希望它產(chǎn)生一個(gè)漂亮的圖形.
初看小星星的德數(shù)據(jù)結(jié)構(gòu),我并為能夠得出全部的東西.
typedef struct {
GLint r,g,b;
GLfloat dist;
GLfloat angle;
}stars; 最初看到這個(gè)數(shù)據(jù)結(jié)構(gòu)的時(shí)候我以為星星應(yīng)當(dāng)是個(gè)點(diǎn).結(jié)果我錯(cuò)了.因?yàn)槲铱赐曛笪液鋈幻靼琢瞬还芪覀兘M織任何的圖元,我們都可以將它看成"點(diǎn)".而最后在于我們?nèi)绾蝸肀硎具@個(gè)點(diǎn)罷了.矩陣變換也是基于點(diǎn).
就像是像素一樣.我們始終會(huì)認(rèn)為它僅僅只是個(gè)像素點(diǎn).然其實(shí)應(yīng)該是個(gè)具有面積的小方格.
所以星星的表示.這一課我們也需要使用小方格.這不僅用在這里.也將用于許多許多.如粒子.等.
而這一課也給了我一個(gè)空間感很強(qiáng)的變換操作,這讓我更傾向于使用局部坐標(biāo)系來考慮整個(gè)變化的過程.因?yàn)檫@讓我更能明白 我最后所繪制的圖形的位置.
對于每個(gè)星星我們需要一個(gè)小正方形來表示.結(jié)果在此貼上星星的紋理,在配合混色操作就能達(dá)到非常完美的效果.我們看代碼:我希望我的注釋能夠非常易懂的明白:

/**//** 以下變換的目的在于,我可以使得星星距離中心dist的一圈,因平移x位移時(shí)候,x軸已經(jīng)被旋轉(zhuǎn)至一定方向了*/

glTranslatef(0.0,0.0,zoom); /**//** 深入屏幕里面*/

glRotatef(tilt,1.0,0.0,0.0);/**//** 傾斜角度..x軸 */


glRotatef(star[loop].angle,0.0,1.0,0.0); /**//**當(dāng)前星星所在的角度*/

glTranslatef(star[loop].dist,0.0,0.0);/**//** x軸平移 */

glRotatef(-star[loop].angle,0.0f,1.0f,0.0f); // 取消當(dāng)前星星的角度
glRotatef(-tilt,1.0f,0.0f,0.0f); // 取消屏幕傾斜
而對于每個(gè)星星若要啟動(dòng)閃爍效果.我們只需要為它繪制兩次.以達(dá)到一個(gè)看起來是在閃爍的效果
總體代碼如下:

lesson_9


#include "openglglut.h"
#include "BmpLoader.h"

bool twinkle=false;
bool tp=false;
const int num = 50;

typedef struct
{
GLint r,g,b;//顏色
GLfloat dist;//距中心點(diǎn)距離
GLfloat angle;//繞y軸角度
}stars;
stars star[num];
GLfloat zoom = -15.f;
GLfloat tilt=90.0f;
GLfloat spin;

GLuint loop;
GLuint texture[1];

bool LoadBmpTexture(const char* filename,GLuint& texid)


{
BmpLoader bmp;
if(!bmp.loadBitmap((char*)filename))

{
printf("loadBitmap error\n");
return false;
}


glPixelStorei(GL_UNPACK_ALIGNMENT,4); /**//** ? */


glGenTextures(1,&texid); /**//** 創(chuàng)建一個(gè)紋理*/

glBindTexture(GL_TEXTURE_2D,texid); /**//** 為它指定一個(gè)紋理*/


glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /**//** 線性濾波 */

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); /**//** 線性濾波 */

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,bmp.bitInfo->biWidth,bmp.bitInfo->biHeight

,0,GL_RGB,GL_UNSIGNED_BYTE,bmp.image); /**//** 生成紋理*/
//bmp.Free();

return true;
}
void InitStar()


{
for(loop=0;loop<num;loop++)

{
star[loop].angle=0.0;
star[loop].dist=(loop/num)*5.0f;
star[loop].r=rand()%256;
star[loop].g=rand()%256;
star[loop].b=rand()%256;
}
}
int main(int argc,char** argv)


{

createWindow("opengl lesson_6",&argc,argv); /**//** 初始化并創(chuàng)建窗口*/


glutDisplayFunc(glutDisplay); /**//** 注冊重繪函數(shù)*/

glutIdleFunc(glutIdle); /**//** 注冊空閑回調(diào)函數(shù)*/

glutReshapeFunc(glutResize); /**//** 注冊窗口調(diào)整函數(shù)*/

glutSpecialFunc(glutSpecial); /**//** 注冊特殊按鍵窗口*/

glutKeyboardFunc(glutKeyboard); /**//** 注冊鍵盤處理函數(shù)*/


InitStar(); /**//** 初始化本例中星星數(shù)據(jù)*/


InitTexture(); /**//** 初始化啟用紋理映射并加載紋理*/

InitBlend(); /**//** 初始化混色*/

InitOpenGL(); /**//** 初始化opengl 這節(jié)課有必要注釋掉這個(gè)函數(shù)中的深度測試的兩句代碼*/

glutMainLoop(); /**//** 仿真循環(huán)*/
}
void InitBlend()


{
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glEnable(GL_BLEND);
}
void InitTexture(void)


{

/**//** 讀入工程目錄下data文件中的bmp文件*/
if(!LoadBmpTexture("..\\Data\\Star.bmp",texture[0]))

{
printf("load texture error!\n");
exit(0);
}

/**//** 若載入紋理成功 則啟用紋理映射*/
glEnable(GL_TEXTURE_2D);
}
void glutDisplay()


{
glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D,texture[0]);
for(loop=0;loop<num;loop++)

{
glLoadIdentity();

/**//** 以下變換的目的在于,我可以使得星星距離中心dist的一圈,因平移x位移時(shí)候,x軸已經(jīng)被旋轉(zhuǎn)至一定方向了*/

glTranslatef(0.0,0.0,zoom); /**//** 深入屏幕里面*/

glRotatef(tilt,1.0,0.0,0.0);/**//** 傾斜角度..x軸 */


glRotatef(star[loop].angle,0.0,1.0,0.0); /**//**當(dāng)前星星所在的角度*/

glTranslatef(star[loop].dist,0.0,0.0);/**//** x軸平移 */

glRotatef(-star[loop].angle,0.0f,1.0f,0.0f); // 取消當(dāng)前星星的角度
glRotatef(-tilt,1.0f,0.0f,0.0f); // 取消屏幕傾斜

if (twinkle) // 啟用閃爍效果

{
// 使用byte型數(shù)值指定一個(gè)顏色
glColor4ub(star[(num-loop)-1].r,star[(num-loop)-1].g,star[(num-loop)-1].b,255);
glBegin(GL_QUADS); // 開始繪制紋理映射過的四邊形
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd(); // 四邊形繪制結(jié)束
}

glRotatef(spin,0.0f,0.0f,1.0f); // 繞z軸旋轉(zhuǎn)星星
// 使用byte型數(shù)值指定一個(gè)顏色
glColor4ub(star[loop].r,star[loop].g,star[loop].b,255);
glBegin(GL_QUADS); // 開始繪制紋理映射過的四邊形
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd(); // 四邊形繪制結(jié)束

spin+=0.01f; // 星星的公轉(zhuǎn)
star[loop].angle+=float(loop)/num; // 改變星星的自轉(zhuǎn)角度
star[loop].dist-=0.01f; // 改變星星離中心的距離
spin+=0.01;

if (star[loop].dist<0.0f) // 星星到達(dá)中心了么

{
star[loop].dist+=5.0f; // 往外移5個(gè)單位
star[loop].r=rand()%256; // 賦一個(gè)新紅色分量
star[loop].g=rand()%256; // 賦一個(gè)新綠色分量
star[loop].b=rand()%256; // 賦一個(gè)新藍(lán)色分量
}

}
glutSwapBuffers();
}
void glutIdle()


{
glutPostRedisplay();
}

void glutKeyboard(unsigned char key,int x,int y)


{
switch(key)

{

case 27: /**//** Esc按鍵按下后退出程序 */
exit(0);
break;
case 't':
case 'T':
twinkle=!twinkle;
default:
break;
}
}
void glutSpecial(int value, int x, int y)


{
switch (value)

{
case GLUT_KEY_F1: // 按F1鍵時(shí)切換窗口/全屏模式
if(isFullScreen)

{
glutReshapeWindow(GL_WIN_WIDTH, GL_WIN_HEIGHT);
glutPositionWindow(GL_WIN_INITIAL_X, GL_WIN_INITIAL_Y);
isFullScreen = false;
}
else

{
glutFullScreen();
isFullScreen = true;
}
return;
default:
return;
}
}
效果圖:
posted on 2009-08-08 17:48
米游 閱讀(660)
評論(1) 編輯 收藏 引用 所屬分類:
OpenGL/OSG