本文展示如何在 C 語言中使用 OpenGL 3.3 核心模式,配合 GLSL 著色器與自訂數學庫 vmath.h,實現 3D 透視投影渲染。範例繪製兩組立方體,分別位於不同深度,透過透視矩陣呈現遠小近大的視覺效果。
#version 330
layout(location = 0) in vec4 vertexPosition;
layout(location = 1) in vec4 vertexColor;
smooth out vec4 theColor;
uniform vec2 offset;
uniform mat4 perspectiveMatrix;
void main() {
vec4 cameraPosition = vertexPosition + vec4(offset.x, offset.y, 0.0, 0.0);
gl_Position = perspectiveMatrix * cameraPosition;
theColor = vertexColor;
}
#version 330
smooth in vec4 theColor;
out vec4 outputColor;
void main() {
outputColor = theColor;
}
glewInit();
SetupShader(); // 編譯、鏈接著色器,檢查錯誤日誌
InitVBO(); // 建立 VAO、VBO,上傳頂點位置與顏色資料
使用 vmath.h 提供的 perspectiveFrustum() 函數:
Matrix44f M;
perspectiveFrustum(M, -1.0, 1.0, 1.0, -1.0, 1.0, 3.0);
// 參數:left, right, top, bottom, near, far
矩陣以列主序儲存,上傳給著色器時指定 GL_TRUE 表示轉置。
void RenderScene() {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programHandle);
// 取得 uniform 位置
offsetUniformLocation = glGetUniformLocation(programHandle, "offset");
perspectiveMatrixUniformLocation = glGetUniformLocation(programHandle, "perspectiveMatrix");
// 設定偏移與矩陣
glUniform2f(offsetUniformLocation, 0.5, 0.5);
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_TRUE, M);
glBindVertexArray(vaoHandle);
glDrawArrays(GL_TRIANGLES, 0, 36); // 36 個頂點 = 12 三角形 = 2 個立方體
glBindVertexArray(0);
glutSwapBuffers();
glutPostRedisplay();
}
typedef float Matrix44f[16];
void perspectiveFrustum(Matrix44f M, float left, float right,
float top, float bottom, float near, float far);
void orthoPerspect(Matrix44f M, float left, float right,
float top, float bottom, float near, float far);
// 另有 translate, scale, rotateX/Y/Z/XYZ 等變換函數
視窗顯示兩個彩色立方體,前方立方體較大,後方立方體較小,完美呈現透視效果。按 F1 可退出程式。
vmath.c 實現包含平移、縮放、旋轉、透視/正交投影矩陣生成。glew、freeglut、vmath、readtext 庫。