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
|
||||
shaders/phong.vert
|
||||
shaders/phong.frag
|
||||
shaders/axes.vert
|
||||
shaders/axes.frag
|
||||
)
|
||||
|
||||
# 将着色器文件复制到可执行文件旁边
|
||||
|
||||
115
main.cpp
115
main.cpp
@ -21,15 +21,18 @@ int windowHeight = 768;
|
||||
|
||||
// 着色器程序ID
|
||||
GLuint programID;
|
||||
GLuint axesProgramID; // Shader program for axes
|
||||
// GLuint pickingProgramID; // (可选,如果实现拾取)
|
||||
|
||||
// Uniform ID
|
||||
GLuint MatrixID_MVP, MatrixID_M, MatrixID_V;
|
||||
GLuint LightPosID, LightColorID, LightPowerID, ViewPosID;
|
||||
GLuint TextureSamplerID;
|
||||
GLuint AxesMatrixID_MVP; // MVP uniform for axes shader
|
||||
|
||||
// VAO 和 VBO
|
||||
GLuint CubeVAO, CubeVBO_vertices, CubeVBO_normals, CubeVBO_uvs;
|
||||
GLuint AxesVAO, AxesVBO_vertices, AxesVBO_colors;
|
||||
// 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 cameraVerticalAngle = 0.0f; // 初始垂直角
|
||||
float initialFoV = 45.0f;
|
||||
float cameraSpeed = 3.0f; // 单位/秒
|
||||
float cameraSpeed = 9.0f; // 单位/秒
|
||||
float mouseSpeed = 0.002f;
|
||||
|
||||
// 鼠标状态
|
||||
@ -67,10 +70,11 @@ void mouseMotion(int x, int y);
|
||||
void idle();
|
||||
void createGradientTexture();
|
||||
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);
|
||||
|
||||
// 立方体顶点数据 (位置, 法线, UV)
|
||||
// 36个顶点,因为每个面有不同法线或UV,不能共享顶点
|
||||
const GLfloat cube_vertices[] = {
|
||||
// Back face
|
||||
-0.5f, -0.5f, -0.5f, // Bottom-left
|
||||
@ -116,6 +120,31 @@ const GLfloat cube_vertices[] = {
|
||||
-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[] = {
|
||||
// Back face
|
||||
0.0f, 0.0f, -1.0f,
|
||||
@ -273,6 +302,26 @@ void setupCubeBuffers() {
|
||||
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() {
|
||||
glewExperimental = GL_TRUE;
|
||||
@ -302,6 +351,12 @@ void initGL() {
|
||||
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;
|
||||
GLchar infoLog[512];
|
||||
@ -329,8 +384,12 @@ void initGL() {
|
||||
TextureSamplerID = glGetUniformLocation(programID, "myTextureSampler");
|
||||
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();
|
||||
setupCubeBuffers();
|
||||
setupAxesBuffers();
|
||||
|
||||
glutSetCursor(GLUT_CURSOR_NONE);
|
||||
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();
|
||||
}
|
||||
|
||||
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() {
|
||||
// 检查OpenGL错误
|
||||
GLenum err;
|
||||
@ -383,17 +459,6 @@ void display() {
|
||||
std::cerr << "深度测试未启用" << std::endl;
|
||||
}
|
||||
|
||||
// 先绑定着色器程序
|
||||
glUseProgram(programID);
|
||||
|
||||
// 检查着色器程序绑定状态
|
||||
GLint currentProgram;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
|
||||
if (currentProgram != programID) {
|
||||
std::cerr << "着色器程序未正确绑定" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
glm::vec3 direction(
|
||||
cos(cameraVerticalAngle) * sin(cameraHorizontalAngle),
|
||||
sin(cameraVerticalAngle),
|
||||
@ -413,6 +478,9 @@ void display() {
|
||||
up
|
||||
);
|
||||
|
||||
// Render Cube
|
||||
glUseProgram(programID); // Ensure correct shader is used for the cube
|
||||
|
||||
glm::mat4 ModelMatrixCube = glm::mat4(1.0);
|
||||
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));
|
||||
@ -472,6 +540,9 @@ void display() {
|
||||
// 解绑VAO
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Render Axes
|
||||
renderAxes(ProjectionMatrix, ViewMatrix);
|
||||
|
||||
// 检查绘制后的OpenGL错误
|
||||
while((err = glGetError()) != GL_NO_ERROR) {
|
||||
std::cerr << "OpenGL error after rendering: " << err << std::endl;
|
||||
@ -489,12 +560,12 @@ void display() {
|
||||
glutSolidSphere(0.1, 10, 10);
|
||||
|
||||
// 渲染操作说明文字
|
||||
renderText("操作说明:", 10, windowHeight - 20, 1.0f, 1.0f, 0.0f);
|
||||
renderText("W/S: 前进/后退", 10, windowHeight - 40);
|
||||
renderText("A/D: 左移/右移", 10, windowHeight - 60);
|
||||
renderText("空格/C: 上升/下降", 10, windowHeight - 80);
|
||||
renderText("鼠标左键拖拽: 视角旋转", 10, windowHeight - 100);
|
||||
renderText("ESC: 退出程序", 10, windowHeight - 120);
|
||||
renderText("Controls:", 10, windowHeight - 20, 1.0f, 1.0f, 0.0f);
|
||||
renderText("W/S: Move Forward/Backward", 10, windowHeight - 40);
|
||||
renderText("A/D: Strafe Left/Right", 10, windowHeight - 60);
|
||||
renderText("Space/C: Move Up/Down", 10, windowHeight - 80);
|
||||
renderText("Left Mouse Drag: Rotate View", 10, windowHeight - 100);
|
||||
renderText("ESC: Exit Program", 10, windowHeight - 120);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
@ -535,6 +606,11 @@ void keyboard(unsigned char key, int x, int y) {
|
||||
glDeleteVertexArrays(1, &CubeVAO);
|
||||
glDeleteProgram(programID);
|
||||
glDeleteTextures(1, &checkerboardTextureID);
|
||||
// Cleanup for axes
|
||||
glDeleteBuffers(1, &AxesVBO_vertices);
|
||||
glDeleteBuffers(1, &AxesVBO_colors);
|
||||
glDeleteVertexArrays(1, &AxesVAO);
|
||||
glDeleteProgram(axesProgramID);
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
@ -585,7 +661,6 @@ void mouseMotion(int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void idle() {
|
||||
cubeRotationAngle += 0.005f;
|
||||
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();
|
||||
VertexShaderCode = sstr.str();
|
||||
VertexShaderStream.close();
|
||||
std::cout << "顶点着色器代码:\n" << VertexShaderCode << std::endl;
|
||||
} else {
|
||||
std::cerr << "无法打开 " << vertex_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
|
||||
getchar();
|
||||
@ -31,7 +30,6 @@ GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_pat
|
||||
sstr << FragmentShaderStream.rdbuf();
|
||||
FragmentShaderCode = sstr.str();
|
||||
FragmentShaderStream.close();
|
||||
std::cout << "片元着色器代码:\n" << FragmentShaderCode << std::endl;
|
||||
} else {
|
||||
std::cerr << "无法打开 " << fragment_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
|
||||
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