我很难弄明白为什么我的Glew/GLFW应用程序不能呈现一个简单的正方形,所以我将其分解到一个文件中,试图找出缺少了什么。
下面的代码成功地打开了一个窗口,清除为我设置的关闭的绿色/蓝色,但没有渲染正方形。如果我在Frag着色器中添加了一个错误,它会在应该绘制正方形的地方将像素渲染为黑色(但令人惊讶的是,它没有导致程序崩溃)。
我没有收到从render_func()
中的glGetError()
调用返回的错误。
这是我正在运行的代码,除了着色器编译代码(我直接从另一个运行良好的项目中提取),以减少我共享的示例代码。
# ifndef GLEW_STATIC
# define GLEW_STATIC
# endif
# include "GL/glew.h"
# ifndef GLFW_INCLUDE_NONE
# define GLFW_INCLUDE_NONE
# endif
# include "GLFW/glfw3.h"
# ifndef GLM_FORCE_CTOR_INIT
# define GLM_FORCE_CTOR_INIT
# endif
# include "glm/glm.hpp"
# include <array>
# include <memory>
constexpr static std::array<glm::vec3, 4> vertices {{ {-0.5, -0.5, 0.0}, {-0.5, 0.5, 0.0}, {0.5, 0.5, 0.0}, {0.5, -0.5, 0.0} }};
constexpr static std::array<uint32_t , 6> indices {{ 0, 1, 2, 2, 3, 0 }};
const std::string vertex_shader_source = R"(
#version 460 core
layout (location = 0) in vec3 attrib_pos;
out vec3 frag_pos;
void main()
{
frag_pos = attrib_pos;
}
)";
const std::string fragment_shader_source = R"(
#version 460 core
in vec3 frag_pos;
out vec4 o_frag_colour;
void main()
{
o_frag_colour = vec4(1.0, 0.5, 0.0, 1.0);
}
)";
GLFWwindow* init_window()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW Window", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height){ glViewport(0, 0, width, height); });
glfwSetErrorCallback([](int error, const char* description){
std::cout << "nodget::App::init_glfw() - ERROR - " << std::to_string(error) << ":n" << description << std::endl;
throw;
});
glewExperimental = GL_TRUE;
glewInit();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glFrontFace(GL_CW);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
return window;
}
uint32_t init_vertex_array()
{
using VERTEX_ELEMENT_TYPE = decltype(vertices)::value_type;
using INDEX_ELEMENT_TYPE = decltype(indices)::value_type;
uint32_t VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
std::cout << "vertices.size() * sizeof(Vertex) " << vertices.size() * sizeof(VERTEX_ELEMENT_TYPE) << std::endl;
std::cout << "indices.size() * sizeof(uint32_t) " << indices.size() * sizeof(INDEX_ELEMENT_TYPE) << std::endl;
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(VERTEX_ELEMENT_TYPE), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(INDEX_ELEMENT_TYPE), indices.data(), GL_STATIC_DRAW);
enum {
VERTEX_POSITION_ATTRIB_INDEX = 0
};
glEnableVertexAttribArray(VERTEX_POSITION_ATTRIB_INDEX);
glVertexAttribPointer(VERTEX_POSITION_ATTRIB_INDEX, 3, GL_FLOAT, false, sizeof(glm::vec3), (void*)0);
glBindVertexArray(0);
return VAO;
}
void render_func(GLFWwindow* window, uint32_t vao_id, uint32_t shader_id)
{
auto error = glGetError();
if (error != GL_NO_ERROR) {
std::cout << "Pre Loop Error: " << error << std::endl;
}
while(true) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_id);
glBindVertexArray(vao_id);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
error = glGetError();
if (error != GL_NO_ERROR) {
std::cout << "Mid Loop Error: " << error << std::endl;
}
}
}
int main()
{
auto window = init_window();
auto vao_id = init_vertex_array();
const std::shared_ptr<nodget::Shader> shader = std::make_shared<nodget::Shader>(std::move(vertex_shader_source), std::move(fragment_shader_source));
shader->init_func();
render_func(window, vao_id, shader->id);
}
1条答案
按热度按时间w6lpcovy1#
必须将剪裁空间坐标写入
gl_Position
。gl_Position
用于基元组装: