OpenGl-實驗-設計程式實現點光源的移動觀察效果
程式碼比較亂,還請見諒,如果有幫助到您,請給俺點個贊(畢竟花了好久除錯出來的,滿眼都是淚)
一:實現效果
二:程式碼實現
通過小鍵盤控制光源的移動
#include <windows.h>
#include <GL/glut.h>
#include <math.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#define PI 3.1416
float r[17]={0,0.1,0.2,0.3,0.4,1,0.7,1,0.4,0.6,0,1};
float g[17]={1,0,0.5,1,0.5,0.6,0.7,0.3,1,0.6,0.2,0,1,0};
float b[17]={0.3,0.8,0.9,1,0,0,0,1,0.4,0.6,1,0.2,1,0.5,1};
GLint color[9]={1,2,3,0,2,3,1,2,3};
float n=30.0;
float n2=-30.0;
GLfloat xRot = -5.0f;
GLfloat yRot = 5.0f;
GLfloat zRot = -5.0f;
static GLfloat vertex_list[][3] = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
};
static const GLint index_list[][4] = {
0, 2, 3, 1,
0, 4, 6, 2,
0, 1, 5, 4,
4, 5, 7, 6,
1, 3, 7, 5,
2, 6, 7, 3,
};
GLfloat light_position1 [] = {xRot,yRot,zRot,1.0}; //點光源位置
void Init(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(1.0f, 1.0f, 0.0f);
// 儲存座標和角度
GLfloat x, y, z, angle,x1,y1;
//光照引數初始化全位於此處
GLfloat mat_specular [] = {1.0,1.0,1.0,1.0}; //鏡面反射引數
GLfloat mat_shininess [] = {100.0}; //高光指數
// GLfloat light_position [] = {5.0,5.0,5.0,1.0}; //點光源位置
//GLfloat light_position [] = {0.0,0.0,50.0,0.0}; //無限遠模擬平行光
// GLfloat white_light [] = {1.0,1.0,1.0,1.0}; //設定光源顏色
GLfloat light_1 [] = {1.0,0.5,0.3,1.0}; //設定光源顏色
//GLfloat light_2 [] = {0,0.5,0.3,1.0}; //設定光源顏色
// GLfloat light_position1 [] = {xRot,yRot,zRot,1.0}; //點光源位置
// GLfloat light_position2 [] = {5.0,-5.0,5.0,1.0}; //點光源位置
GLfloat model_ambient [] = {0.1,0.1,0.1,1.0}; //環境光引數
glClearColor(0.0,0.0,0.0,0.0); //背景色
glShadeModel(GL_SMOOTH); //多變形填充模式
//材質屬性:如何反射光線(材料環境、散射、鏡面顏色、光澤度)
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); //使用鏡面材質顏色
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); //使用光澤度
//燈光設定
// glLightfv(GL_LIGHT0,GL_POSITION,light_position); //定義光源的位置
// glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light); //定義散射光為白色
// glLightfv(GL_LIGHT0,GL_SPECULAR,white_light); //定義鏡面光為白色
glLightfv(GL_LIGHT1,GL_POSITION,light_position1); //定義光源的位置
glLightfv(GL_LIGHT1,GL_DIFFUSE,light_1); //定義散射光為白色
glLightfv(GL_LIGHT1,GL_SPECULAR,light_1); //定義鏡面光為白色
// glLightfv(GL_LIGHT2,GL_POSITION,light_position2); //定義光源的位置
// glLightfv(GL_LIGHT2,GL_DIFFUSE,light_2); //定義散射光為白色
// glLightfv(GL_LIGHT2,GL_SPECULAR,light_2); //定義鏡面光為白色
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,model_ambient); //光照模型引數:全域性環境光
glEnable(GL_LIGHTING); //開啟光源
// glEnable(GL_LIGHT0); //啟動 0 號光源
glEnable(GL_LIGHT1); //啟動 0 號光源
// glEnable(GL_LIGHT2); //啟動 0 號光源
glEnable(GL_DEPTH_TEST); //開啟深度測試
// 把著色模式設定為單調著色
//glShadeModel(GL_FLAT); //glShadeModel(GL_SMOOTH);
// 把順時針環繞的多邊形設為正面,這與預設是相反的,因為我們使用的是三角形扇
glFrontFace(GL_CW);
glOrtho(-1.0f,1.0f,-1.0f,1.0f,-1.0f,1.0f);
}
void SpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_UP)
xRot -= 5.0f;
if (key == GLUT_KEY_DOWN)
xRot += 5.0f;
if (key == GLUT_KEY_LEFT)
yRot -= 5.0f;
if (key == GLUT_KEY_RIGHT)
yRot += 5.0f;
if (key> 356.0f)
xRot = 0.0f;
if (key< -1.0f)
xRot = 355.0f;
if (key> 356.0f)
yRot = 0.0f;
if (key< -1.0f)
yRot = 355.0f;
if (key==GLUT_KEY_F1) //繞著 z 軸旋轉
zRot+= 5.0f;
// 使用新的座標重新繪製場景
glutPostRedisplay();
}
void RenderScene()
{
// 儲存座標和角度
GLfloat x, y, z, angle,x1,y1;
// 用於三角形顏色的交替設定
int iPivot = 1;
// 用預設顏色設定背景色,並清除深度緩衝區(必須的,因為 3D 空間有視景深度)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//開啟剔除功能(背面剔除,它用於消除一個表面的背面)
//glEnable(GL_CULL_FACE);
// 開啟深度測試,如果不開啟深度測試,3D 錐體的顯示就會與現實情況不符合
glEnable(GL_DEPTH_TEST);
// 儲存矩陣狀態並旋轉
glPushMatrix();
GLfloat light_position1 [] = {xRot,yRot,zRot,1.0}; //點光源位置
glLightfv(GL_LIGHT1,GL_POSITION,light_position1); //定義光源的位置
/*
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
*/
// glBegin(GL_TRIANGLE_FAN);
glBegin(GL_QUADS);
for(int i=0; i<6; ++i) // 有六個面,迴圈六次
{
glColor3d(r[i],g[i],b[i]);//顏色設定為青色
for(int j=0; j<4; ++j) // 每個面有四個頂點,迴圈四次
{
glNormal3f(vertex_list[index_list[i][j]][0],vertex_list[index_list[i][j]][1],vertex_list[index_list[i][j]][2]); //設定法向量
glVertex3fv(vertex_list[index_list[i][j]]);
}
}
glEnd();
// ...
//glEnd();
glPopMatrix();
glutSwapBuffers();
}
int main(int argv,char *argc[]){
glutInit(&argv,argc);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(400,400);
glutInitWindowPosition(400,300);
glutCreateWindow("3D 空間繪製圓錐面");
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
Init();
glutMainLoop();
}
三:補充
法向量的設定
一個面一個法向量。三個頂點決定一個面。法向量可以通過 3 個頂點得到的兩個向量叉乘求出。
函式:glNormal3f (GLfloat x, GLfloat y, GLfloat z):x, y, z 表示法向量指向的位置。
作用:用來設定當前的法向量,這個法向量將被應用到緊接下來的 glVertex() 所定義的頂點上。但是通常各個頂
點的法向是各不相同的,所以我們通常在定義每個頂點之前都為它確定一次法向量。
用法示例:
glBegin();
glNormal3f(x,y,z); //設定法向量
glVertex3f(x,y,z); //設定點座標
glNormal3f(x,y,z); //設定法向量
glVertex3f(x,y,z); //設定點座標
glEnd();
相關文章
- 設計模式(python實現):觀察者模式設計模式Python
- Go 實現常用設計模式(五)觀察者模式Go設計模式
- 設計模式實戰 - 觀察者模式設計模式
- 實驗 21:觀察者模式模式
- 三種方式實現觀察者模式 及 Spring中的事件程式設計模型模式Spring事件程式設計模型
- 設計模式學習-使用go實現觀察者模式設計模式Go
- 11.22實驗 21:觀察者模式模式
- JS原生實現觀察者模式JS模式
- 原生實現的觀察者模式(Observer Model)模式Server
- Java實驗二:類程式設計實驗Java程式設計
- 流動的觀察者模式 | Flutter 設計模式Flutter設計模式
- SVG點選實現動態放大的圓效果SVG
- 程式設計實驗4程式設計
- 程式設計實驗五程式設計
- 道觀小程式架構設計與實現分析架構
- SoftwareMill實現領域驅動設計的經驗REM
- 移動端日曆元件設計與實現元件
- 實驗1 現代C++程式設計初體驗C++程式設計
- PHP實現觀察者模式SplSubject SplObserver SplObjectStoragePHP模式ServerObject
- Html5實現移動端、PC端 刮刮卡效果HTML
- 【程式碼簡述設計模式】----- 觀察者模式設計模式
- 【觀察者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實現設計模式JavaJSGoPython
- 安卓移動應用程式碼安全加固系統設計及實現安卓
- 程式設計實戰篇——Spring Boot 自動配置實現程式設計Spring Boot
- 設計模式 —— 觀察者模式設計模式
- 設計模式(觀察者模式)設計模式
- 設計模式----觀察者模式設計模式
- 【設計模式】觀察者模式設計模式
- 設計模式——觀察者模式設計模式
- 探究netty的觀察者設計模式Netty設計模式
- 設計模式中的觀察者模式設計模式
- 【資訊科技】【2013.08】觀察蜜蜂活動的自動影像處理系統的實現
- 使用函式式實現觀察者模式模式函式模式
- 好程式設計師技術分享jQuery實現類似fullpage外掛的全屏滾動效果程式設計師jQuery
- 程式設計25年後,現實將我打回菜鳥程式設計師的起點程式設計師
- 實驗 2 Scala 程式設計初級實踐程式設計
- 美女程式設計師觀點:程式設計師最重要的非程式設計技巧程式設計師
- 動畫-CAShapeLayer實現QQ訊息紅點拖拽效果動畫