1. 程式人生 > >計算機圖形學-光照紋理模型

計算機圖形學-光照紋理模型

話不多說,看圖和程式碼註釋微笑

#include <stdlib.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
GLfloat *currentCoeff;
GLenum currentPlane;
GLint currentGenMode;
float roangles = 45.0;
#define stripeImageWidth 32
GLubyte stripeImage[4 * stripeImageWidth];
//自定義初始化opengl函式

void makeStripeImage(void) { //生成紋理
	for (int j = 0; j < stripeImageWidth; j++) {
		stripeImage[4 * j + 0] = (GLubyte)((j <= 4) ? 255 : 0);
		stripeImage[4 * j + 1] = (GLubyte)((j > 4) ? 255 : 0);
		stripeImage[4 * j + 2] = (GLubyte)0;
		stripeImage[4 * j + 3] = (GLubyte)255;
	}
}
void init(void)
{
	GLfloat xequalzero[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat slanted[] = { 1.0, 1.0, 1.0, 0.0 };
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	makeStripeImage();
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	/*
	
	   glTexParameteri()指定紋理的各種屬性:這些屬性包括:
		
		
		GL_TEXTURE_MIN/MAG_FILTER 當紋理貼圖需要被放大或縮小時的插值方式
									   此屬性通常必須要指定,否則可能看不到貼圖
		GL_TEXTURE_MIN/MAG_LOD  設定紋理的最小和最大LOD級別(可為正負)
		GL_TEXTURE_MAX_LOD 設定最小的那個mipmap的序號
		GL_TEXTURE_MAX_LEVE設定最大的那個mipmap的序號
		GL_TEXTURE_WRAP_S/T/R 設定紋理座標的擴充套件方式,在這個引數下,可以使用的擴充套件方式有:GL_CLAMP(夾緊), GL_CLAMP_TO_BORDER, GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT(重複),各種鋪陳方式的效果如圖:
 
		GL_TEXTURE_BORDER_COLOR 設定紋理的邊界(BORDER)顏色
		GL_TEXTURE_PRIORITY 設定紋理在GPU快取中的優先順序,通常為了效能考慮,紋理會被放在GPU的快取中,但是存放的數量是有限的,這個引數可以設定在GPU中的存放優先順序
		GL_GENERATE_MIPMAP 設定當base mipmap改變後是否更新所有的mipmap
 
        GL_TEXTURE_COMPARE_MODE GL_TEXTURE_COMPARE_FUNC和GL_DEPTH_TEXTURE_MODE屬性是專門為陰影貼圖
	*/
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	//紋理對映
	glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//紋理環境
	currentCoeff = xequalzero;
	currentGenMode = GL_OBJECT_LINEAR;
	currentPlane = GL_OBJECT_PLANE;
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);//自動生成紋理座標,設定生成紋理的平面參考方式
	glTexGenfv(GL_S, currentPlane, currentCoeff);//來設定這個平面
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_1D);
	//glShadeModel(GL_SMOOTH);
	// 設定光源
	GLfloat sun_light_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };
	GLfloat sun_light_ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
	GLfloat sun_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat sun_light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

	glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);//第0號光源位置
	glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);//0號光源環境光屬性
	//經過很多次反射後最終遺留在環境中的光線強度(顏色)
	glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);//散射光屬性
	glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);//鏡面反射光屬性

	//OPENGL在後面的渲染中使用光照,預設情況下是關閉的
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	glEnable(GL_AUTO_NORMAL);
	glEnable(GL_NORMALIZE);
	glFrontFace(GL_CW);
	// 設定材質
	GLfloat earth_mat_ambient[] = { 0.5f, 1.0f, 0.5f, 1.0f };
	GLfloat earth_mat_diffuse[] = { 0.5f, 1.0f, 0.5f, 1.0f };
	GLfloat earth_mat_specular[] = { 0.0f, 0.5f, 0.5f, 1.0f };
	GLfloat earth_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };
	GLfloat earth_mat_shininess = 50.0f;

	glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);//材質環境顏色
	glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);//材質散射顏色
	glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);//材質鏡面反射顏色
	glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);//材質發射光顏色
	glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);//鏡面反射指數
	
	//GL_FRONT、GL_BACK或GL_FRONT_AND_BACK,指出材質屬性將應用於物體的哪面。
	/*
	GL_AMBIENT(0.2,0.2,0.2,1.0)材質的環境顏色
	GL_DIFFUSE(0.8,0.8,0.8,1.0)材質的散射顏色
	GL_AMBIENT_AND_DIFFUSE材質的環境顏色和散射顏色
	GL_SPECULAR(0.0,0.0,0.0,1.0)材質的鏡面反射顏色
	GL_SHININESS 0.0 鏡面反射指數
	GL_EMISSION (0.0,0.0,0.1,1.0)材質的發射光顏色
	GL_COLOR_INDEXES (0, 1, 1)環境顏色索引、散射顏色索引和鏡面反射顏色索引
	*/
}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glRotatef(roangles, 0.0, 0.0, 1.0);
	//glTranslatef(Move_x, Move_y, Move_z);
	glutSolidSphere(1.0, 32, 32);
	glPopMatrix();

	//glEnable/glDisable —— 開啟和關閉伺服器端GL功能
	glDisable(GL_DEPTH_TEST);//啟用深度測試
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_1D);//對活動的材質進行貼圖
	glDisable(GL_LIGHTING);//關閉光源
	glDisable(GL_LIGHT0);//關閉光源,
	glDisable(GL_AUTO_NORMAL);//執行後,圖形能把光反射到各個方向
	glDisable(GL_NORMALIZE);//在轉換之後和光照之前將法線向量標準化成單位長度
	glFlush();
}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);

	//設定投影引數
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//正交投影
	if (w <= h)
		glOrtho(-1.5, 1.5, -1.5*(GLfloat)h / (GLfloat)w, 1.5*(GLfloat)h / (GLfloat)w, -10.0, 10.0);
	else
		glOrtho(-1.5*(GLfloat)w / (GLfloat)h, 1.5*(GLfloat)w / (GLfloat)h, -1.5, 1.5, -10.0, 10.0);

	//設定模型引數--幾何體引數
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("球");

	init();

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);

	glutMainLoop();
	return 0;
}