我刚刚开始使用OpenGL,已经遇到了一个相当令人沮丧的错误。我遵循了learnopengl教程,将大多数内容封装到一个渲染器类中,该类包含缓冲区等元素。下面是执行所有操作的主要代码:
# include <gfx/gfx.h>
# include <gfx/gl.h>
# include <gfx/shaders.h>
# include <iostream>
void Renderer::init() {
vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader_id, 1, &vertex_shader, nullptr);
glCompileShader(vertex_shader_id);
GLint vertex_shader_status;
glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &vertex_shader_status);
if (vertex_shader_status == false) {
std::cout << "vsh compilation failed due to";
char vertex_fail_info_log[1024];
glGetShaderInfoLog(vertex_shader_id, 1024, nullptr, vertex_fail_info_log);
std::cout << vertex_fail_info_log << std::endl;
abort();
}
fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader_id, 1, &fragment_shader, nullptr);
glCompileShader(fragment_shader_id);
GLint fragment_shader_status;
glGetShaderiv(fragment_shader_id, GL_COMPILE_STATUS, &fragment_shader_status);
if (fragment_shader_status == false) {
std::cout << "fsh compilation failed due to";
char fragment_fail_info_log[1024];
glGetShaderInfoLog(fragment_shader_id, 1024, nullptr, fragment_fail_info_log);
std::cout << fragment_fail_info_log << std::endl;
abort();
}
shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader_id);
glAttachShader(shader_program, fragment_shader_id);
glLinkProgram(shader_program);
GLint shader_program_status;
glGetProgramiv(shader_program, GL_LINK_STATUS, &shader_program_status);
if (shader_program_status == false) {
std::cout << "shprogram compilation failed due to";
char shader_program_fail_info_log[1024];
glGetShaderInfoLog(shader_program, 1024, nullptr, shader_program_fail_info_log);
std::cout << shader_program_fail_info_log << std::endl;
abort();
}
glUseProgram(shader_program);
glDeleteShader(vertex_shader_id);
glDeleteShader(fragment_shader_id);
}
void Renderer::draw(f32 verts[]) {
glUseProgram(shader_program);
glClearColor(1, 0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCreateVertexArrays(1, &vertex_array);
glBindVertexArray(vertex_array);
glCreateBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(f32), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(vertex_array);
glUseProgram(shader_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
以下是shaders.h:
# ifndef SHADERS_H
# define SHADERS_H
const char* vertex_shader =
"#version 460 coren"
"layout (location = 0) in vec3 aPos;n"
"void main() {n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);n"
"}n0";
const char* fragment_shader =
"#version 460 coren"
"out vec4 FragColor;n"
"void main() {n"
"FragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);n"
"}n0";
# endif
我一辈子也搞不清楚自己到底出了什么问题。红色清晰的颜色出现了,但没有其他颜色。
1条答案
按热度按时间jqjz2hbq1#
看起来你的绘制方法有问题。签名是
void Renderer::draw(f32 verts[]) {
,然后调用glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
。问题是,当您将一个数组传递给一个函数时,它会衰减为一个指针(尽管声明可能会让它看起来像没有发生,这非常令人困惑)。因此,在函数参数中,draw(f32 verts[])
等同于draw(f32* verts)
。This question对那里正在发生的事情有一些解释。无论如何,当您调用
sizeof(verts)
时,您只获得浮点指针的字节数,而不是verts
拥有的字节数。因此,当您调用glBufferData()
来创建要创建的三角形时,您将没有指定足够的字节。简单的解决方法是将一个长度传递到您的DRAW函数中,然后您将得到类似于Here是关于此特定函数的一些文档。可能还有其他错误,但由于您没有进行黑屏,并且代码通常看起来是正确的,所以不太可能有一堆无效操作或任何东西。
要在此之后继续调试,请将以下代码添加到代码中
并将
GL_ERROR_CHECK()
撒得到处都是,以查看是否有任何OpenGL调用无效。