feat: add axes shaders and rendering functionality
This commit is contained in:
parent
82bd391640
commit
aecc61b0a6
@ -94,6 +94,8 @@ target_link_libraries(OpenGLProject
|
|||||||
set(SHADER_FILES
|
set(SHADER_FILES
|
||||||
shaders/phong.vert
|
shaders/phong.vert
|
||||||
shaders/phong.frag
|
shaders/phong.frag
|
||||||
|
shaders/axes.vert
|
||||||
|
shaders/axes.frag
|
||||||
)
|
)
|
||||||
|
|
||||||
# 将着色器文件复制到可执行文件旁边
|
# 将着色器文件复制到可执行文件旁边
|
||||||
|
|||||||
115
main.cpp
115
main.cpp
@ -21,15 +21,18 @@ int windowHeight = 768;
|
|||||||
|
|
||||||
// 着色器程序ID
|
// 着色器程序ID
|
||||||
GLuint programID;
|
GLuint programID;
|
||||||
|
GLuint axesProgramID; // Shader program for axes
|
||||||
// GLuint pickingProgramID; // (可选,如果实现拾取)
|
// GLuint pickingProgramID; // (可选,如果实现拾取)
|
||||||
|
|
||||||
// Uniform ID
|
// Uniform ID
|
||||||
GLuint MatrixID_MVP, MatrixID_M, MatrixID_V;
|
GLuint MatrixID_MVP, MatrixID_M, MatrixID_V;
|
||||||
GLuint LightPosID, LightColorID, LightPowerID, ViewPosID;
|
GLuint LightPosID, LightColorID, LightPowerID, ViewPosID;
|
||||||
GLuint TextureSamplerID;
|
GLuint TextureSamplerID;
|
||||||
|
GLuint AxesMatrixID_MVP; // MVP uniform for axes shader
|
||||||
|
|
||||||
// VAO 和 VBO
|
// VAO 和 VBO
|
||||||
GLuint CubeVAO, CubeVBO_vertices, CubeVBO_normals, CubeVBO_uvs;
|
GLuint CubeVAO, CubeVBO_vertices, CubeVBO_normals, CubeVBO_uvs;
|
||||||
|
GLuint AxesVAO, AxesVBO_vertices, AxesVBO_colors;
|
||||||
// GLuint LightVAO; // 用于表示光源的球体 (使用 GLUT 绘制,可能不需要单独VAO)
|
// GLuint LightVAO; // 用于表示光源的球体 (使用 GLUT 绘制,可能不需要单独VAO)
|
||||||
|
|
||||||
// 纹理
|
// 纹理
|
||||||
@ -40,7 +43,7 @@ glm::vec3 cameraPosition = glm::vec3(3.0f, 3.0f, 3.0f);
|
|||||||
float cameraHorizontalAngle = glm::pi<float>(); // 初始水平角 (pi)
|
float cameraHorizontalAngle = glm::pi<float>(); // 初始水平角 (pi)
|
||||||
float cameraVerticalAngle = 0.0f; // 初始垂直角
|
float cameraVerticalAngle = 0.0f; // 初始垂直角
|
||||||
float initialFoV = 45.0f;
|
float initialFoV = 45.0f;
|
||||||
float cameraSpeed = 3.0f; // 单位/秒
|
float cameraSpeed = 9.0f; // 单位/秒
|
||||||
float mouseSpeed = 0.002f;
|
float mouseSpeed = 0.002f;
|
||||||
|
|
||||||
// 鼠标状态
|
// 鼠标状态
|
||||||
@ -67,10 +70,11 @@ void mouseMotion(int x, int y);
|
|||||||
void idle();
|
void idle();
|
||||||
void createGradientTexture();
|
void createGradientTexture();
|
||||||
void setupCubeBuffers();
|
void setupCubeBuffers();
|
||||||
|
void setupAxesBuffers(); // Added
|
||||||
|
void renderAxes(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix); // Added
|
||||||
void renderText(const char* text, float x, float y, float r = 1.0f, float g = 1.0f, float b = 1.0f);
|
void renderText(const char* text, float x, float y, float r = 1.0f, float g = 1.0f, float b = 1.0f);
|
||||||
|
|
||||||
// 立方体顶点数据 (位置, 法线, UV)
|
// 立方体顶点数据 (位置, 法线, UV)
|
||||||
// 36个顶点,因为每个面有不同法线或UV,不能共享顶点
|
|
||||||
const GLfloat cube_vertices[] = {
|
const GLfloat cube_vertices[] = {
|
||||||
// Back face
|
// Back face
|
||||||
-0.5f, -0.5f, -0.5f, // Bottom-left
|
-0.5f, -0.5f, -0.5f, // Bottom-left
|
||||||
@ -116,6 +120,31 @@ const GLfloat cube_vertices[] = {
|
|||||||
-0.5f, 0.5f, -0.5f, // top-left
|
-0.5f, 0.5f, -0.5f, // top-left
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Axes vertex data
|
||||||
|
const GLfloat axes_vertices[] = {
|
||||||
|
// X-axis (red)
|
||||||
|
0.0f, 0.0f, 0.0f,
|
||||||
|
2.0f, 0.0f, 0.0f,
|
||||||
|
// Y-axis (green)
|
||||||
|
0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 2.0f, 0.0f,
|
||||||
|
// Z-axis (blue)
|
||||||
|
0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 2.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
const GLfloat axes_colors[] = {
|
||||||
|
// X-axis (red)
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
// Y-axis (green)
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
// Z-axis (blue)
|
||||||
|
0.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 0.0f, 1.0f
|
||||||
|
};
|
||||||
|
|
||||||
const GLfloat cube_normals[] = {
|
const GLfloat cube_normals[] = {
|
||||||
// Back face
|
// Back face
|
||||||
0.0f, 0.0f, -1.0f,
|
0.0f, 0.0f, -1.0f,
|
||||||
@ -273,6 +302,26 @@ void setupCubeBuffers() {
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setupAxesBuffers() {
|
||||||
|
glGenVertexArrays(1, &AxesVAO);
|
||||||
|
glBindVertexArray(AxesVAO);
|
||||||
|
|
||||||
|
// Vertex positions
|
||||||
|
glGenBuffers(1, &AxesVBO_vertices);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, AxesVBO_vertices);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(axes_vertices), axes_vertices, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
// Vertex colors
|
||||||
|
glGenBuffers(1, &AxesVBO_colors);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, AxesVBO_colors);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(axes_colors), axes_colors, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
void initGL() {
|
void initGL() {
|
||||||
glewExperimental = GL_TRUE;
|
glewExperimental = GL_TRUE;
|
||||||
@ -302,6 +351,12 @@ void initGL() {
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
axesProgramID = LoadShaders("shaders/axes.vert", "shaders/axes.frag");
|
||||||
|
if (axesProgramID == 0) {
|
||||||
|
std::cerr << "Failed to load axes shaders. Exiting." << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
// 添加着色器编译状态检查
|
// 添加着色器编译状态检查
|
||||||
GLint success;
|
GLint success;
|
||||||
GLchar infoLog[512];
|
GLchar infoLog[512];
|
||||||
@ -329,8 +384,12 @@ void initGL() {
|
|||||||
TextureSamplerID = glGetUniformLocation(programID, "myTextureSampler");
|
TextureSamplerID = glGetUniformLocation(programID, "myTextureSampler");
|
||||||
if (TextureSamplerID == -1) std::cerr << "myTextureSampler uniform not found" << std::endl;
|
if (TextureSamplerID == -1) std::cerr << "myTextureSampler uniform not found" << std::endl;
|
||||||
|
|
||||||
|
AxesMatrixID_MVP = glGetUniformLocation(axesProgramID, "MVP");
|
||||||
|
if (AxesMatrixID_MVP == -1) std::cerr << "Axes MVP uniform not found" << std::endl;
|
||||||
|
|
||||||
createGradientTexture();
|
createGradientTexture();
|
||||||
setupCubeBuffers();
|
setupCubeBuffers();
|
||||||
|
setupAxesBuffers();
|
||||||
|
|
||||||
glutSetCursor(GLUT_CURSOR_NONE);
|
glutSetCursor(GLUT_CURSOR_NONE);
|
||||||
glutWarpPointer(windowWidth / 2, windowHeight / 2);
|
glutWarpPointer(windowWidth / 2, windowHeight / 2);
|
||||||
@ -367,6 +426,23 @@ void renderText(const char* text, float x, float y, float r, float g, float b) {
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderAxes(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix) {
|
||||||
|
glUseProgram(axesProgramID);
|
||||||
|
|
||||||
|
glm::mat4 ModelMatrixAxes = glm::mat4(1.0); // Identity matrix, axes at origin
|
||||||
|
glm::mat4 MVP_Axes = projectionMatrix * viewMatrix * ModelMatrixAxes;
|
||||||
|
|
||||||
|
if (AxesMatrixID_MVP != -1) {
|
||||||
|
glUniformMatrix4fv(AxesMatrixID_MVP, 1, GL_FALSE, &MVP_Axes[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(AxesVAO);
|
||||||
|
glLineWidth(2.0f); // Make axes lines thicker
|
||||||
|
glDrawArrays(GL_LINES, 0, 6); // 3 lines, 2 vertices each
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glLineWidth(1.0f); // Reset line width
|
||||||
|
}
|
||||||
|
|
||||||
void display() {
|
void display() {
|
||||||
// 检查OpenGL错误
|
// 检查OpenGL错误
|
||||||
GLenum err;
|
GLenum err;
|
||||||
@ -383,17 +459,6 @@ void display() {
|
|||||||
std::cerr << "深度测试未启用" << std::endl;
|
std::cerr << "深度测试未启用" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先绑定着色器程序
|
|
||||||
glUseProgram(programID);
|
|
||||||
|
|
||||||
// 检查着色器程序绑定状态
|
|
||||||
GLint currentProgram;
|
|
||||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
|
|
||||||
if (currentProgram != programID) {
|
|
||||||
std::cerr << "着色器程序未正确绑定" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 direction(
|
glm::vec3 direction(
|
||||||
cos(cameraVerticalAngle) * sin(cameraHorizontalAngle),
|
cos(cameraVerticalAngle) * sin(cameraHorizontalAngle),
|
||||||
sin(cameraVerticalAngle),
|
sin(cameraVerticalAngle),
|
||||||
@ -413,6 +478,9 @@ void display() {
|
|||||||
up
|
up
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Render Cube
|
||||||
|
glUseProgram(programID); // Ensure correct shader is used for the cube
|
||||||
|
|
||||||
glm::mat4 ModelMatrixCube = glm::mat4(1.0);
|
glm::mat4 ModelMatrixCube = glm::mat4(1.0);
|
||||||
ModelMatrixCube = glm::translate(ModelMatrixCube, glm::vec3(0.0f, 0.0f, 0.0f));
|
ModelMatrixCube = glm::translate(ModelMatrixCube, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
ModelMatrixCube = glm::rotate(ModelMatrixCube, cubeRotationAngle, glm::vec3(0.0f, 1.0f, 0.0f));
|
ModelMatrixCube = glm::rotate(ModelMatrixCube, cubeRotationAngle, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
@ -472,6 +540,9 @@ void display() {
|
|||||||
// 解绑VAO
|
// 解绑VAO
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
// Render Axes
|
||||||
|
renderAxes(ProjectionMatrix, ViewMatrix);
|
||||||
|
|
||||||
// 检查绘制后的OpenGL错误
|
// 检查绘制后的OpenGL错误
|
||||||
while((err = glGetError()) != GL_NO_ERROR) {
|
while((err = glGetError()) != GL_NO_ERROR) {
|
||||||
std::cerr << "OpenGL error after rendering: " << err << std::endl;
|
std::cerr << "OpenGL error after rendering: " << err << std::endl;
|
||||||
@ -489,12 +560,12 @@ void display() {
|
|||||||
glutSolidSphere(0.1, 10, 10);
|
glutSolidSphere(0.1, 10, 10);
|
||||||
|
|
||||||
// 渲染操作说明文字
|
// 渲染操作说明文字
|
||||||
renderText("操作说明:", 10, windowHeight - 20, 1.0f, 1.0f, 0.0f);
|
renderText("Controls:", 10, windowHeight - 20, 1.0f, 1.0f, 0.0f);
|
||||||
renderText("W/S: 前进/后退", 10, windowHeight - 40);
|
renderText("W/S: Move Forward/Backward", 10, windowHeight - 40);
|
||||||
renderText("A/D: 左移/右移", 10, windowHeight - 60);
|
renderText("A/D: Strafe Left/Right", 10, windowHeight - 60);
|
||||||
renderText("空格/C: 上升/下降", 10, windowHeight - 80);
|
renderText("Space/C: Move Up/Down", 10, windowHeight - 80);
|
||||||
renderText("鼠标左键拖拽: 视角旋转", 10, windowHeight - 100);
|
renderText("Left Mouse Drag: Rotate View", 10, windowHeight - 100);
|
||||||
renderText("ESC: 退出程序", 10, windowHeight - 120);
|
renderText("ESC: Exit Program", 10, windowHeight - 120);
|
||||||
|
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
}
|
}
|
||||||
@ -535,6 +606,11 @@ void keyboard(unsigned char key, int x, int y) {
|
|||||||
glDeleteVertexArrays(1, &CubeVAO);
|
glDeleteVertexArrays(1, &CubeVAO);
|
||||||
glDeleteProgram(programID);
|
glDeleteProgram(programID);
|
||||||
glDeleteTextures(1, &checkerboardTextureID);
|
glDeleteTextures(1, &checkerboardTextureID);
|
||||||
|
// Cleanup for axes
|
||||||
|
glDeleteBuffers(1, &AxesVBO_vertices);
|
||||||
|
glDeleteBuffers(1, &AxesVBO_colors);
|
||||||
|
glDeleteVertexArrays(1, &AxesVAO);
|
||||||
|
glDeleteProgram(axesProgramID);
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -585,7 +661,6 @@ void mouseMotion(int x, int y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void idle() {
|
void idle() {
|
||||||
cubeRotationAngle += 0.005f;
|
cubeRotationAngle += 0.005f;
|
||||||
if (cubeRotationAngle > 2.0f * glm::pi<float>()) {
|
if (cubeRotationAngle > 2.0f * glm::pi<float>()) {
|
||||||
|
|||||||
@ -16,7 +16,6 @@ GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_pat
|
|||||||
sstr << VertexShaderStream.rdbuf();
|
sstr << VertexShaderStream.rdbuf();
|
||||||
VertexShaderCode = sstr.str();
|
VertexShaderCode = sstr.str();
|
||||||
VertexShaderStream.close();
|
VertexShaderStream.close();
|
||||||
std::cout << "顶点着色器代码:\n" << VertexShaderCode << std::endl;
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "无法打开 " << vertex_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
|
std::cerr << "无法打开 " << vertex_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
|
||||||
getchar();
|
getchar();
|
||||||
@ -31,7 +30,6 @@ GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_pat
|
|||||||
sstr << FragmentShaderStream.rdbuf();
|
sstr << FragmentShaderStream.rdbuf();
|
||||||
FragmentShaderCode = sstr.str();
|
FragmentShaderCode = sstr.str();
|
||||||
FragmentShaderStream.close();
|
FragmentShaderStream.close();
|
||||||
std::cout << "片元着色器代码:\n" << FragmentShaderCode << std::endl;
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "无法打开 " << fragment_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
|
std::cerr << "无法打开 " << fragment_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
|
||||||
getchar();
|
getchar();
|
||||||
|
|||||||
10
shaders/axes.frag
Normal file
10
shaders/axes.frag
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// shaders/axes.frag
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 fragmentColor;
|
||||||
|
out vec3 color;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
color = fragmentColor;
|
||||||
|
}
|
||||||
|
|
||||||
15
shaders/axes.vert
Normal file
15
shaders/axes.vert
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// shaders/axes.vert
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 vertexPosition_modelspace;
|
||||||
|
layout(location = 1) in vec3 vertexColor;
|
||||||
|
|
||||||
|
out vec3 fragmentColor;
|
||||||
|
|
||||||
|
uniform mat4 MVP;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
gl_Position = MVP * vec4(vertexPosition_modelspace, 1.0);
|
||||||
|
fragmentColor = vertexColor;
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user