我正在尝试在OpenGL中编码3d金字塔,我无法弄清楚为什么我的三角形在金字塔的侧面不重叠,以及为了达到实际金字塔形状需要做的事情。
我尝试更新步幅,旋转,但我茫然。我还尝试过将形状加倍的概念,但这也不起作用。
我将感谢任何人对于如何完成此代码以获得3D金字塔的见识
我的代码:
#include <GLEW/glew.h>
#include <GLFW/glfw3.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();
// Attach 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 1
0.0,1.0,0.0,
1.0,0.0,0.0,
-1.0,-1.0,1.0,
0.0,1.0,0.0,
1.0,-1.0,1.0,
0.0,0.0,1.0,
//Triangle 2
0.0,1.0,0.0,
1.0,0.0,0.0,
1.0,-1.0,1.0,
0.0,0.0,1.0,
1.0,-1.0,-1.0,
0.0,1.0,0.0,
//Triangle 3
0.0,1.0,0.0,
1.0,0.0,0.0,
1.0,-1.0,-1.0,
0.0,1.0,0.0,
-1.0,-1.0,-1.0,
0.0,0.0,1.0,
//Triangle 4
0.0,1.0,0.0,
1.0,0.0,0.0,
-1.0,-1.0,-1.0,
0.0,0.0,1.0,
-1.0,-1.0,1.0,
0.0,1.0,0.0
};
// Define element indices GLubyte indices[] = { 0, 1, 2, 1, 2,
3 };
//plane positions glm::vec3 planePositions[] = {
glm::vec3(0.0f,0.0f,0.5f), glm::vec3(0.5f,0.0f,0.0f),
glm::vec3(0.0f,0.0f,-0.5f), glm::vec3(-0.5f,0.0f,0.0f) };
//Plane rotations glm::float32 planeRotationsY[] = {
0.0f,80.0f, 10.0f, 90.f };
glm::float32 planeRotationsX[] = {
20.0f,-15.0f, 90.0f, 45.f };
//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
glGenBuffers(1, &EBO); // Create EBO
glGenVertexArrays(1, &VAO); // Create VOA
glBindVertexArray(VAO);
// VBO and EBO Placed in User-Defined VAO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Select VBO
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
// Specify attribute location and layout to GPU
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0); // Unbind VOA or close off (Must call VOA explicitly in loop)
// Vertex shader source code
string vertexShaderSource =
"#version 330 core\n"
"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 core\n"
"in vec4 oColor;"
"out vec4 fragColor;"
"void main()\n"
"{\n"
"fragColor = oColor;"
"}\n";
// Creating Shader Program
GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
// Use Shader Program exe once
//glUseProgram(shaderProgram);
/* Loop until the user closes the window */
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;
glm::mat4 projectionMatrix;
//Initialize transforms
//modelMatrix = glm::scale(modelMatrix, glm::vec3(0.5f, 0.5f, 0.5f));
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;
modelMatrix = glm::translate(modelMatrix, planePositions[i]);
modelMatrix = glm::rotate(modelMatrix, planeRotationsY[i] * toRadians, glm::vec3(0.0f, 1.0f, 0.0f));
modelMatrix = glm::rotate(modelMatrix, planeRotationsX[i] * toRadians, glm::vec3(1.0f, 0.0f, 0.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); //Incase different VAO wii be used after
glUseProgram(0); // Incase different shader will be used after
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
//Clear GPU resources
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
答案 0 :(得分:0)
似乎存在一些代码格式化问题,但是我看到了:
// Define element indices
GLubyte indices[] = { 0, 1, 2, 1, 2, 3 };
在我看来,这是不正确的,顶点数据的注释方式看起来应该是这样的:
GLubyte indices[] = {
// First triangle
0, 1, 2,
// Second triangle
3, 4, 5,
// Third triangle
6, 7, 8,
// Fourth triangle
9, 10, 11,
};
然后您可以:
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
但是索引数组是不必要的。您可以将其完全删除,只需使用:
glDrawArrays(GL_TRIANGLES, 0, 12);