我正在尝试使用OpenGL中的顶点和索引来制作一个圆柱体。我仍在尝试使用三角形、余弦和正弦函数构建圆柱体的底部,并对其进行渲染。但出于某种原因,它变成了一个由两个三角形组成的大三角形。有人能帮我算出圆柱体底座的正确坐标吗?或者更好的是,它协调了一个完整的圆柱体。以下是我的代码:
# include <GLglew.h>
# include <GLFWglfw3.h>
# include <iostream>
// GLM library
# include <glm/glm.hpp>
# include <glm/gtc/matrix_transform.hpp>
# include <glm/gtc/type_ptr.hpp>
using namespace std;
int width, height;
const double PI = 3.14159;
const float toRadians = PI / 180.0f;
// Draw Primitive(s)
void draw() {
GLenum mode = GL_TRIANGLES;
GLsizei indices = 6;
glDrawElements(mode, indices, GL_UNSIGNED_BYTE, nullptr);
}
// Create and Compile Shaders
static GLuint CompileShader(const string& source, GLuint shaderType) {
// Create Shader Object
GLuint shaderID = glCreateShader(shaderType);
const char* src = source.c_str();
// Attach source code to Shader object
glShaderSource(shaderID, 1, &src, nullptr);
// Compile Shader
glCompileShader(shaderID);
// Return ID of Compiled shader
return shaderID;
}
// Create Program Object
static GLuint CreateShaderProgram(const string& vertexShader, const string& fragmentShader) {
// Compile vertex shader
GLuint vertexShaderComp = CompileShader(vertexShader, GL_VERTEX_SHADER);
// Compile fragment shader
GLuint fragmentShaderComp = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// Create program object
GLuint shaderProgram = glCreateProgram();
// Attch vertex and fragment shaders to program object
glAttachShader(shaderProgram, vertexShaderComp);
glAttachShader(shaderProgram, fragmentShaderComp);
// Link shaders to create executable
glLinkProgram(shaderProgram);
// Delete compiled vertex and fragment shaders
glDeleteShader(vertexShaderComp);
glDeleteShader(fragmentShaderComp);
// Return Shader Program
return shaderProgram;
}
int main(void) {
width = 640; height = 480;
GLFWwindow* window;
// Initialize the library
if (!glfwInit())
return -1;
// Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(width, height, "Main Window", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
// Initialize GLEW
if (glewInit() != GLEW_OK)
cout << "Error!" << endl;
GLfloat vertices[] = {
// Triangle One
0.0, 0.0, 0.0, // vert 0
1.0, 0.0, 0.0, // red
cos(60), sin(60), 0.0, // vert 1
0.0, 1.0, 0.0, // green
cos(60), -sin(60), 0.0, // vert 2
0.0, 0.0, 1.0, // blue
// Part of Triangle Two
-cos(60), -sin(60), 0.0, // vert 3
1.0, 0.0, 1.0, // purple
// Part of Triangle Three
-cos(60), -sin(60), 0.0, // vert 4
0.0, 1.0, 0.0, // green
// Part of Triangle Four
-cos(60), sin(60), 0.0, // vert 5
0.0, 0.0, 1.0, // blue
// Part of Triangle Five
-cos(60), sin(60), 0.0, // vert 6
1.0, 0.0, 1.0, // purple
// Part of Triangle Six
-cos(60), sin(60), 0.0, // vert 7
0.0, 1.0, 0.0 // green
};
// Define element indices
GLubyte indices[] = {
0,1,2,
0,2,3,
0,3,4,
0,4,5,
0,5,6,
0,6,7
};
// Enable Depth Buffer
glEnable(GL_DEPTH_TEST);
// Wireframe mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
GLuint VBO, EBO, VAO;
glGenBuffers(1, &VBO); // Create VBO and returns ID
glGenBuffers(1, &EBO); // Create EBO
glGenVertexArrays(1, &VAO); // Create VAO
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Select VBO and activate buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Select EBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Load indices attributes
// Specify attributes location and layout to GPU
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Color attribute location and layout
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
// Vertex shader source code
string vertexShaderSource =
"#version 330 coren"
"layout(location = 0) in vec4 vPosition;"
"layout(location = 1) in vec4 aColor;"
"out vec4 oColor;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"void main()n"
"{n"
"gl_Position = projection * view * model * vPosition;"
"oColor = aColor;"
"}n";
// Fragment shader source code
string fragmentShaderSource =
"#version 330 coren"
"in vec4 oColor;"
"out vec4 fragColor;"
"void main()n"
"{n"
"fragColor = oColor;"
"}n";
// Creating Shader Program
GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
while (!glfwWindowShouldClose(window)) {
// Resize window and graphics simultaneously
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// Render here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use Shader Program exe and select VAO before drawing
glUseProgram(shaderProgram); // Call Shader per-frame when updating attributes
// Declare identity matrix
glm::mat4 viewMatrix(1.0f);
glm::mat4 projectionMatrix(1.0f);
// Initialize transforms
//modelMatrix = glm::scale(modelMatrix, glm::vec3(1.0f, 1.0f, 1.0f));
viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, -3.0f));
viewMatrix = glm::rotate(viewMatrix, 45.0f * toRadians, glm::vec3(1.0f, 0.0f, 0.0f));
projectionMatrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
// Select uniform shader and variable
GLuint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLuint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection");
// Pass transform to Shader
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glBindVertexArray(VAO); // User-defined VAO must be called before draw
for (GLuint i = 0; i < 4; i++) {
glm::mat4 modelMatrix(1.0f);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));
// Draw primitive(s)
draw();
}
// Unbind Shader exe and VOA after drawing per frame
glBindVertexArray(0); // In case different VAO will be used after
glUseProgram(0); // In case different shader will be used after
glBindVertexArray(VAO);
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}
1条答案
按热度按时间vxqlmq5t1#
glm::perspective
s视图参数的单位是弧度,而不是度。可以使用glm::radians
将度数转换为弧度:projectionMatrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
cos
和sin
的单位是弧度,而不是度。由于要计算圆周围的点,因此必须增加每个顶点的Angular :当然,你必须画出所有的花边。因此,指数的数量是18个,而不是6个: