1. 程式人生 > >OpenGL藍寶書第七章:立體天空和紋理折射、雙紋理(下)

OpenGL藍寶書第七章:立體天空和紋理折射、雙紋理(下)

ever oot 可行性 VR char 都是 pipeline 差異 pac

對照了藍寶書,才知道紅寶書的長處。

reflect函數的原理在紅寶書中有說明,僅僅有對照了紅寶書,才知道紅寶書的定位:高級工具書。

藍寶書作為入門級書籍,以較快的速度讓讀者敲到代碼去思考,總遺留了須要探索的內容。


藍寶書要看完。

紅寶書要看完。

C++11 標準版英文版也看了小部分。

多線程入門都不算。

Socket僅僅能實現基礎網絡連接,離真正的數據通信都算,何況多人在線對戰網絡模型的實現

設計模式看了又忘了,忘了又看。如果沒有機會去設計模塊級別的代碼實現,真的血了沒用,難道改UI?加班趕工哪有魄力略微幅度大點調整代碼。可惜當時沒預算到需求的演化須要我去用策略模式或者裝飾者模式去調整代碼結構。

工廠模式:封裝了類對象的生成過程。同意不同參數獲取不用對象

單例模式:控制模塊間的數據訪問出口,減低模塊之間的耦合

策略模式:也能夠封裝不用數據表現出統一的行為,提供了相似於單例的使用方法,減低耦合。


當時無心寫UI,大部分時間用來實現技能和AI,誰知UI的需求演化成為壓死我的最後一根稻草——由於主管們一致覺得可展示的UI具有最高的優先權,或者說當時主程僅僅希望我能完整實現UI的大大小小需求,給一個看得到的東西給我,但是,新代碼一次性讓我接觸到3大模塊。我最不喜歡偏偏是UI。

加上內部一些異動,我沒有適當地爭取,主程又給我添加UI任務。對啊。不討人喜歡的下場。一堆UI給你做,看你怎麽進步?

至少我今天搞定了圖形渲染的入門,明確了面對需求,對程序的修改是通過添加新代碼進行的,而不是更改現有的代碼。


要意識到變化性往往比溝通中被有意識忽略的多多了。

無意義的加班是不可能有這些進步的。

盡管我走了之後你們的獎金池多了。但是主程能讓人我的前任和我走了,你們之後就能讓其它優秀隊友走。

我選的這條路盡管辛苦。看著輕浮。僅僅要熬過了之後我就能成為大神。


win32或其它操作系統文件頭中的時間戳還沒找到,怎麽實現同文件副本的MD5正確校驗?如果找到了,文件更新列表的加減能夠由生成本地列表和獲取更新列表對照差異得到,調用下載模塊,覆蓋或者填充在本地資源路徑下。


導航網格內容中,至今沒能理解三角形生成原理,人家的博士論文,想在1個月內看懂,可行性非常低啊


ORGE沒碰、Unreal Engine 4.0 啃不下、Cocos 3D、Gameplay3D,怎樣深化?


至於IK,還非常遠,數學、物理基礎知識都要補呢。


//vp

#version 330

in vec4 vVertex;
in vec3 vNormal;
in vec2 vTexCoords;

uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform mat4 mInverseCamera;

smooth out vec3 vVaryingTexCoord;
smooth out vec2 vTarnishCoords;


void main(void)
{
//在慣性系的坐標
	vec3 vEyeNormal = normalMatrix * vNormal;
	
	vec4 vPosition4 = mvMatrix * vVertex;
	vec3 vEyeVertex = normalize(vPosition4.xyz/vPosition4.w);
	
	vec4 cCoords = vec4(reflect(vEyeVertex,vEyeNormal),1.0f);//不清楚reflect的原理,導致代碼思想斷片,靠猜?開玩笑,還是開源比較好
	cCoords = mInverseCamera * cCoords;//全面反射場景???
	
	vVaryingTexCoord.xyz = normalize(cCoords.xyz); //獲得是什麽坐標?
	
	vTarnishCoords = vTexCoords.st;
	
	gl_Position = mvpMatrix * vVertex;
}


//fp

#version 330

smooth in vec3 vVaryingTexCoord;
smooth in vec2 vTarnishCoords;

uniform samplerCube cubeMap;
uniform sampler2D tarnishMap;

out vec4 vFragColor;

void main(void)
{
	vFragColor = texture(cubeMap, vVaryingTexCoord.stp);
	//兩段紋理。僅僅須要顏色相乘就能夠了。後面的紋理為最外層色彩
	vFragColor *= texture(tarnishMap, vTarnishCoords.st);
}



//cpp

#include <GLTools.h>
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

GLFrame viewFrame;
GLFrustum viewFrustum;
GLMatrixStack projctionMatrix;
GLMatrixStack mvpMatrix;
GLMatrixStack modelViewMatrix;
GLGeometryTransform transformPipeLine;

GLTriangleBatch sphereBatch;
GLBatch cubeBatch;

GLuint tarnishTexture;
GLuint cubeTexture;
GLuint reflectionShader;
GLuint skyBoxShader;

GLint locMVPReflect;
GLint locMVReflect;
GLint locNormalReflect;
GLint locInvertedCamera;

GLint locCubeMap, locTarnishMap;

GLint locMVPSkyBox;

// Six sides of a cube map
const char *szCubeFaces[6] = { "pos_x.tga", "neg_x.tga", "pos_y.tga", "neg_y.tga", "pos_z.tga", "neg_z.tga" };

GLenum cube[6] = {
	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};

void ChangeSize(int w, int h)
{
	if (h <= 0)
	{
		h = 1;
	}

	glViewport(0, 0, w, h);
	viewFrustum.SetPerspective(80.0f, float(w) / float(h), 1.0f, 120.0f);
	projctionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
	transformPipeLine.SetMatrixStacks(modelViewMatrix, projctionMatrix);
}


void SetupRC(void)
{
	GLbyte * pBytes;
	int nWidth, nHeight, nComponent;
	GLenum eFormat;

	glCullFace(GL_BACK);
	glEnable(GL_DEPTH_TEST);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	// Load the tarnish texture
	glGenTextures(1, &tarnishTexture);
	glBindTexture(GL_TEXTURE_2D, tarnishTexture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	pBytes = gltReadTGABits("tarnish.tga", &nWidth, &nHeight, &nComponent, &eFormat);
	glTexImage2D(GL_TEXTURE_2D, 0, nComponent, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
	free(pBytes);
	glGenerateMipmap(GL_TEXTURE_2D);

	glGenTextures(1, &cubeTexture);
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

	

	for (size_t i = 0; i < 6; ++i)
	{
		pBytes = gltReadTGABits(szCubeFaces[i], &nWidth, &nHeight, &nComponent, &eFormat);
		// border 為0,是指邊框的寬度
		//eFormat 不須要 和internalFormat取值必須同樣。都是指定紋理中的顏色組件
		glTexImage2D(cube[i], 0, nComponent, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
		free(pBytes);
	}
	glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

	viewFrame.MoveForward(-4.0f);
	gltMakeSphere(sphereBatch, 1.0f, 52, 26);
	gltMakeCube(cubeBatch, 20.0f);

	reflectionShader = gltLoadShaderPairWithAttributes("Reflection.vp", "Reflection.fp", 3, 
		GLT_ATTRIBUTE_VERTEX, "vVertex", 
		GLT_ATTRIBUTE_NORMAL, "vNormal", 
		GLT_ATTRIBUTE_TEXTURE0, "vTexCoords");
	//uniform值綁定
	locMVPReflect = glGetUniformLocation(reflectionShader, "mvpMatrix");
	locMVReflect = glGetUniformLocation(reflectionShader, "mvMatrix");
	locNormalReflect = glGetUniformLocation(reflectionShader, "normalMatrix");
	locInvertedCamera = glGetUniformLocation(reflectionShader, "mInverseCamera");

	locCubeMap = glGetUniformLocation(reflectionShader, "cubeMap");
	locTarnishMap = glGetUniformLocation(reflectionShader, "tarnishMap");

	skyBoxShader = gltLoadShaderPairWithAttributes("skyBox.vp", "skyBox.fp", 1, GLT_ATTRIBUTE_VERTEX, "vVertex");
	//uniform值綁定

	locMVPSkyBox = glGetUniformLocation(skyBoxShader, "mvpMatrix");


	//啟用兩段紋理 與頂點著色器輸入輸出的紋理數組相應
	// glUniform1i(locCubeMap, 0);
	// glUniform1i(locTarnishMap, 1);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, tarnishTexture);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
}

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	M3DMatrix44f mCamera;
	M3DMatrix44f mCameraRotOnly;
	M3DMatrix44f mInverseCamera;

	viewFrame.GetCameraMatrix(mCamera, false);
	viewFrame.GetCameraMatrix(mCameraRotOnly, true);
	m3dInvertMatrix44(mInverseCamera, mCameraRotOnly);

	modelViewMatrix.PushMatrix();
	{
		
		modelViewMatrix.MultMatrix(mCamera);//向後移動 4.0f,慣性坐標系的向後則是z變小,模型變小
		glUseProgram(reflectionShader);

		glUniformMatrix4fv(locMVReflect, 1, GL_FALSE, transformPipeLine.GetModelViewMatrix());
		glUniformMatrix4fv(locMVPReflect, 1, GL_FALSE, transformPipeLine.GetModelViewProjectionMatrix());
		glUniformMatrix3fv(locNormalReflect, 1, GL_FALSE, transformPipeLine.GetNormalMatrix());
		glUniformMatrix4fv(locInvertedCamera, 1, GL_FALSE, mInverseCamera);

		glUniform1i(locCubeMap, 0);
		glUniform1i(locTarnishMap, 1);

		glEnable(GL_CULL_FACE);
		sphereBatch.Draw();
		glDisable(GL_CULL_FACE);
	}
	modelViewMatrix.PopMatrix();

	modelViewMatrix.PushMatrix();
	{
		modelViewMatrix.MultMatrix(mCameraRotOnly);
		glUseProgram(skyBoxShader);
		glUniformMatrix4fv(locMVPSkyBox, 1, GL_FALSE, transformPipeLine.GetModelViewProjectionMatrix());
		cubeBatch.Draw();
	}
	modelViewMatrix.PopMatrix();

	glutSwapBuffers();
}

void SpecialKeys(int key, int x, int y)
{
	float linear = 1.0f;
	float angular = float(m3dDegToRad(5.0f));

	if (key == GLUT_KEY_UP)
		viewFrame.MoveForward(linear);

	if (key == GLUT_KEY_DOWN)
		viewFrame.MoveForward(-linear);

	if (key == GLUT_KEY_LEFT)
		viewFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);

	if (key == GLUT_KEY_RIGHT)
		viewFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);

	glutPostRedisplay();
}

void ShutdownRC(void)
{
	glDeleteTextures(1, &tarnishTexture);
	glDeleteTextures(1, &cubeTexture);
	glDeleteProgram(reflectionShader);
	glDeleteProgram(skyBoxShader);
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(800, 600);
	glutCreateWindow("OpenGL Cube Maps");
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);
	glutSpecialFunc(SpecialKeys);

	GLenum err = glewInit();
	if (GLEW_OK != err) {
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		return 1;
	}


	SetupRC();

	glutMainLoop();

	ShutdownRC();

	return 0;
}


OpenGL藍寶書第七章:立體天空和紋理折射、雙紋理(下)