So I've been trying to learn OpenGL Lately with these videos (https://www.youtube.com/playlist?list=PLlrATfBNZ98foTJPJ_Ev03o2oq3-GGOS2).
But when i tried to run the program using modern OpenGL instead of legacy OpenGL, i had a little problem that was, that the third position of my triangle was displayed at the "0, 0 position" instead of being displayed at the given position, "1.0, 1.0". image of window with modern OpenGL
When i tried to write the code in legacy OpenGL the triangle was shown the correct way. image of window with legacy OpenGL
我是否错过了顶点缓冲区,顶点属性,顶点着色器或片段着色器中的某些内容?
以下是我与遗忘代码“褪色”一起使用的代码。
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
unsigned int CompileShader(unsigned int type, const std::string& source) {
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (!result) {
int lenght;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &lenght);
char* message = (char*)alloca(lenght * sizeof(char));
glGetShaderInfoLog(id, lenght, &lenght, message);
std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "Vertex" : "Fragment") << "shader!:" << std::endl << message << std::endl;
glDeleteShader(id);
return 0;
}
return id;
}
static unsigned int CreateShader(const std::string& VertexShader, const std::string& FragmentShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, VertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, FragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
return program;
}
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Test schermpje", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) {
std::cout << "ERROR!!" << std::endl;
}
std::cout << glGetString(GL_VERSION) << std::endl;
float positions[6] = {
1.0f, 1.0f,
-1.0f,-1.0f,
1.0f, -1.0f,
};
unsigned int Buffer;
glGenBuffers(1, &Buffer);
glBindBuffer(GL_ARRAY_BUFFER, Buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (const void*)8);
std::string VertexShader =
"#version 330 core\n"
"\n"
"layout(location = 0) in vec4 positions;\n"
"\n"
"void main()\n"
"{\n"
"gl_Position = positions;\n"
"}\n";
std::string FragmentShader =
"#version 330 core\n"
""
"layout(location = 0) out vec4 color;\n"
""
"void main()\n"
"{"
" color = vec4(0.0, 1.0, 1.0, 1.0);\n"
"}\n";
unsigned int shader = CreateShader(VertexShader, FragmentShader);
glUseProgram(shader);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/*glBegin(GL_TRIANGLES);
glVertex2f(1.0f, -1.0f);
glVertex2f(-1.0f, -1.0f);
glVertex2f(1.0f, 1.0f);
glEnd();*/
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glDeleteProgram(shader);
glfwTerminate();
return 0;
}
第一个顶点坐标的偏移量是0而不是8:
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (const void*)8);
(If a named buffer object is bound then) the last argument of
glVertexAttribPointer
is treated as a byte offset into the buffer object's data store. Since you've specified an offset of 8, the 1st vertex coordinate is stepped over.When you set an offset of 8, then actually the 2nd, 3rd and 4th vertex coordinate is read form the buffer. Since the buffer has just 3 attributes, the last coordinate is by default (0.0, 0.0).
在您的情况下,甚至可以将0传递给stride参数。这是特例。如果stride为0,则将通用顶点属性理解为紧密包装,并且通过元组的大小和类型来计算stride。