嘿,我认为我如何将数据发送到顶点或使用GL_CCW对索引进行排序的方式可能有误
struct Vertex
{
glm::vec3 position;
glm::vec3 color;
glm::vec3 normal;
};
使用Vertex结构的顶点
Vertex vertices[] =
{
/*FRONT SQUARE*/
///BOTTOM LEFT
glm::vec3(-0.5f, -0.5f, 1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
///bottom RIGHT
glm::vec3(0.5f, -0.5f, 1.0f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
////TOP RIGHT
glm::vec3(0.5f, 0.5f, 1.0f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
///TOP LEFT
glm::vec3(-0.5f, 0.5f, 1.0f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
///BOTTOM LEFT
glm::vec3(-0.5f, -0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
///bottom RIGHT
glm::vec3(0.5f, -0.5f, -1.0f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
////TOP RIGHT
glm::vec3(0.5f, 0.5f, -1.0f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f),
///TOP LEFT
glm::vec3(-0.5f, 0.5f, -1.0f), glm::vec3(1.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f)
};
unsigned noOfVertices = sizeof(vertices) / sizeof(Vertex);
这是我的索引排序
GLuint indices[] =
{
// /front face
0, 1, 2,
2, 3, 0,
// right
1, 5, 6,
6, 2, 1,
// back
7, 6, 5,
5, 4, 7,
// left
4, 0, 3,
3, 7, 4,
// bottom
4, 5, 1,
1, 0, 4,
// top
3, 2, 6,
6, 7, 3
};
unsigned noOfIndices = sizeof(indices) / sizeof(GLuint);
主要功能和初始化窗口
int main()
{
启动窗口
///initialise GLFW for Window
if (glfwInit() == GLFW_FALSE)
{
std::cout << "ERROR::GLFW-INTI::FAILED" << "\n";
glfwTerminate();
}
///Create window with functions
GLFWwindow* window;
const int window_height = 480;
int window_width = 680;
int framebuffer_height = window_height;
int framebuffer_width = window_width;
char* title = "mytutorial";
int GLverMAJ = 3;
int GLverMin = 3;
///sets how the window should be drawn and which hints
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GLverMAJ);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GLverMin);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
///create the window with the previously set options
window = glfwCreateWindow(window_width, window_height, title, NULL, NULL);
//checks if window created
if (window == nullptr)
{
std::cout << "ERROR:::GLFWCREATEWINDOWFAILED" << "\n";
}
///sets the frame buffer size
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
glfwMakeContextCurrent(window);
//need to read on this part
glewExperimental = GL_TRUE;
//initiliase the glew
if (glewInit() != GLEW_OK)
{
std::cout << "ERROR::GLEWINIT::FAILED" << "\n";
}
初始化opengl选项
///enable functions first
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
//initialise the enabled functions
glCullFace(GL_BACK);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LESS);
///set the way its draw
glFrontFace(GL_CCW);
///set the polygon mode and fill ////Set as GL_LINE TO LOOK AT CUBE MESH
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
这是我在其中初始化视图,项目和模型的矩阵的地方
///初始化矩阵
///view
///front, position, up then use in lookat
glm::vec3 cameraPos(0.f, 0.f, 1.f);
glm::vec3 cameraUp(0.f, 1.f, 0.f);
glm::vec3 cameraFront(0.f, 0.f, -0.1f);
glm::mat4 ViewMatrix(1.f);
ViewMatrix = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
///set up prespective projection
float fov = 90.f;
float nearPlane = -1.f;
float farPlane = 1000.f;
///projection
glm::mat4 ProjectionMatrix(1.f);
ProjectionMatrix = glm::perspective(glm::radians(fov), static_cast<float>(framebuffer_width / framebuffer_height), nearPlane, farPlane);
//Model Matrix
glm::mat4 ModelMatrix(1.f);
然后我创建我的着色器
///set up SHADERS
char infolog[512];
GLint success;
GLuint Vertexshader = glCreateShader(GL_VERTEX_SHADER);
///std::string str_src =
std::string temp = "";
std::string src = "";
std::ifstream infile;
infile.open("vert.glsl");
if (infile.is_open())
{
while (std::getline(infile, temp))
src += temp + "\n";
}
infile.close();
const GLchar* source = src.c_str();
///link created shader with shader source
glShaderSource(Vertexshader, 1, &source, NULL);
glCompileShader(Vertexshader);
///error check compilation status
glGetShaderiv(Vertexshader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(Vertexshader, 512, NULL, infolog);
std::cout << infolog;
}
success = 0;
GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
///std::string str_src =
temp = "";
src = "";
infile.open("frag.glsl");
if (infile.is_open())
{
while (std::getline(infile, temp))
src += temp + "\n";
}
infile.close();
source = src.c_str();
///link created shader with shader source
glShaderSource(FragmentShader, 1, &source, NULL);
glCompileShader(FragmentShader);
///error check compilation status
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(FragmentShader, 512, NULL, infolog);
std::cout << infolog;
}
将创建的着色器与程序链接
///create and link the program
success = 0;
GLuint programID;
programID = glCreateProgram();
glAttachShader(programID, Vertexshader);
glAttachShader(programID, FragmentShader);
glLinkProgram(programID);
glGetProgramiv(programID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(programID, 512, NULL, infolog);
std::cout << "ERROR::SHADER::COULD_NOT_LINK_PROGRAM" << "\n";
std::cout << infolog << "\n";
}
链接未使用和删除的缓冲区后
///after linking we unuse the program and delete the shaders
glUseProgram(0);
glDeleteShader(Vertexshader);
glDeleteShader(FragmentShader);
这是我发起VAO VBO和EBO的地方
///vbo, ebo and vertex array
GLuint VAO;
GLuint VBO;
GLuint EBO;
//gen and bind vao
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
///gen vbo
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, noOfVertices * sizeof(Vertex), vertices, GL_STATIC_DRAW);
///gen EBO
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, noOfIndices * sizeof(GLuint), indices, GL_STATIC_DRAW);
这是我觉得可能有问题的部分
///tell buffer where data is located
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
//colour
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, normal));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
///use program send in uniforms to the shader.
glUseProgram(programID);
///GLuint s = glGetUniformLocation(programID, "ViewMatrix");
GLuint s = glGetUniformLocation(programID, "ModelMatrix");
glUniformMatrix4fv(s, 1, GL_FALSE, glm::value_ptr(ModelMatrix));
s = glGetUniformLocation(programID, "ProjectionMatrix");
glUniformMatrix4fv(s, 1, GL_FALSE, glm::value_ptr(ProjectionMatrix));
s = glGetUniformLocation(programID, "ViewMatrix");
glUniformMatrix4fv(s, 1, GL_FALSE, glm::value_ptr(ViewMatrix));
glUseProgram(0);
///main while loop
while (!glfwWindowShouldClose(window))
{
//clear
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
///draw
glfwPollEvents();
glUseProgram(programID);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, noOfIndices, GL_UNSIGNED_INT, 0);
///flush
glfwSwapBuffers(window);
glFlush();
///unuse
glBindVertexArray(0);
glUseProgram(0);
}
return 0;
}
答案 0 :(得分:0)
在我看来,您的程序似乎正常运行。如果我没记错的话,那么您的相机就位于立方体内部,从其中一个面的位置直视另一侧的面。您所看到的正是在这种情况下所期望看到的。在图像的中心,您有两个三角形,它们构成了您所要看到的脸部的背面。您得到的“怪异线”只是构成其他面的三角形的边缘。由于您的相机位于立方体内部,因此这些面必定会一直延伸到相机的后方,并且所有物体都将在近平面处被切掉,在该平面上,您可以从外部“包围”所有物体。
一切都被压缩了,因为这
static_cast<float>(framebuffer_width / framebuffer_height)
不会产生您最有可能想要的效果。您仍然在这里执行整数除法。
此外,我不确定您对近平面使用负值会产生什么样的效果。很有可能,这也不是您真正想要的,我建议您在其中使用一些正值,例如0.1f
…
答案 1 :(得分:0)
glm::perspective
的近平面和远平面都必须为正值,static_cast<float>(framebuffer_width / framebuffer_height)
将是整数除法:
float fov = 90.f;
float nearPlane = 0.1f; // 0.1 instead of -1.0
float farPlane = 1000.f;
glm::mat4 ProjectionMatrix(1.f);
ProjectionMatrix = glm::perspective(glm::radians(fov),
static_cast<float>(framebuffer_width) / static_cast<float>(framebuffer_height),
nearPlane, farPlane);
请参见glm::perspective
:
GLM_FUNC_DECL mat<4, 4, T, defaultp> glm::perspective( T fovy, T aspect, T near, T far )
[...]
near
指定从查看者到附近剪切平面的距离(始终为正)。
far
指定查看者到远裁剪平面的距离(始终为正)。
glm 库提供与OpenGL和GLSL相关的矩阵运算。 glm API documentation指的是The OpenGL Shading Language specification 4.20。
请参见The OpenGL Shading Language 4.6, 5.4.2 Vector and Matrix Constructors, page 101:
要通过指定向量或标量来初始化矩阵,必须按列优先顺序将分量分配给矩阵元素。
mat4(float, float, float, float, // first column float, float, float, float, // second column float, float, float, float, // third column float, float, float, float); // fourth column
这意味着顶点着色器中顶点坐标的转换必须为:
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(vertex_position,1.0);
另请参阅GLSL Programming/Vector and Matrix Operations:
很可能通过将glUniformMatrix4fv
的第三参数设置为GL_TRUE
,可以将矩阵设置为统一矩阵时进行转置:
GLuint s = glGetUniformLocation(programID, "ModelMatrix");
glUniformMatrix4fv(s, 1, GL_TRUE, glm::value_ptr(ModelMatrix));
s = glGetUniformLocation(programID, "ProjectionMatrix");
glUniformMatrix4fv(s, 1, GL_TRUE, glm::value_ptr(ProjectionMatrix));
s = glGetUniformLocation(programID, "ViewMatrix");
glUniformMatrix4fv(s, 1, GL_TRUE, glm::value_ptr(ViewMatrix));
并以相反顺序计算顶点坐标转换:
gl_Position = vec4(vertex_position,1.0) * ModelMatrix * ViewMatrix * ProjectionMatrix;
此外,立方体a的面的缠绕顺序为顺时针,因此必须为:
glFrontFace(GL_CCW);
glFrontFace(GL_CW);
将相机位置更改为
glm::vec3 cameraPos(0.f, 0.f, 2.f);
您将得到以下结果: