OpenGL 着色器编译但窗口中未出现渲染
Posted
技术标签:
【中文标题】OpenGL 着色器编译但窗口中未出现渲染【英文标题】:OpenGL shaders compile but no rendering appears in the window 【发布时间】:2022-01-24 01:56:21 【问题描述】:顶点和片段着色器似乎都在编译,窗口出现并被赋予清晰的颜色,但我无法渲染三角形。我试图只使用 glBegin();顶点(); glEnd();作为替代方案,但这也导致没有渲染三角形。
main.c
#include <stdio.h>
#include <unistd.h>
#include <gfx/shader.h>
#include <gfx/vbo.h>
#include <gfx/vao.h>
GLfloat vertices[] =
0.0f,1.0f,0.0f,
1.0f,1.0f,0.0f,
-1.0f,-1.0f,0.0f
;
int main(void)
if(!glfwInit())
fprintf(stderr, "Unable to init GLFW.\n");
exit(1);
GLFWwindow *win;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
win = glfwCreateWindow(SCREENWIDTH, SCREENHEIGHT, "Terraria", NULL, NULL);
if(win==NULL)
fprintf(stderr, "Error creating opengl window\n");
glfwTerminate();
exit(1);
glfwMakeContextCurrent(win);
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
fprintf(stderr, "Unable to init glad\n");
glfwTerminate();
exit(1);
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(win, frame_buffer_size_cb);
struct Shader s = create_shader("resources/shaders/vec2.vs", "resources/shaders/vec2.fs");
uint32_t vaoID, vboID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(vboID, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
while(!glfwWindowShouldClose(win))
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(s.sh);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
3*sizeof(GLfloat),
(void*)0
);
glDrawArrays(GL_TRIANGLES, 0,3);
glDisableVertexAttribArray(0);
glfwSwapBuffers(win);
glfwPollEvents();
glfwTerminate();
return 0;
shader.h
#include <gfx/gfx.h>
struct Shader
uint32_t sh;
uint32_t vsh;
uint32_t fsh;
;
struct Shader create_shader(const char *vs_path, const char *fs_path);
shader.c
#include <gfx/shader.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
static uint32_t _compile(int8_t id, const char *path, uint16_t type)
uint32_t sh; //Shader handle or ID
FILE *fp = fopen(path, "rb"); //Open the shader source code file
long sz = file_size(fp); //Get the file size
char *shaderSource; //Create object to holder shader source code
shaderSource = calloc(sz+1, 1);
fread(shaderSource, 1, sz, fp); //Read the shader source code into new buffer
fclose(fp);
assert(strlen(shaderSource)>0);
sh = glCreateShader(type);
glShaderSource(sh, 1, (const GLchar **)&shaderSource, NULL);
glCompileShader(sh);
int success;
char infoLog[512];
glGetShaderiv(sh, GL_COMPILE_STATUS, &success);
if (!success)
glGetShaderInfoLog(sh, 512, NULL, infoLog);
printf("Unable to compile shader id %d\n", id);
free(shaderSource);
return sh;
struct Shader create_shader(const char *vs_path, const char *fs_path)
struct Shader h;
h.vsh = _compile(1,vs_path, GL_VERTEX_SHADER);
h.fsh = _compile(0,fs_path, GL_FRAGMENT_SHADER);
h.sh = glCreateProgram();
glAttachShader(h.sh, h.vsh);
glAttachShader(h.sh, h.fsh);
glLinkProgram(h.sh);
// check for linking errors
int success;
char infoLog[512];
glGetProgramiv(h.sh, GL_LINK_STATUS, &success);
if (!success)
glGetProgramInfoLog(h.sh, 512, NULL, infoLog);
printf("Unable to link gl program\n");
glDetachShader(h.sh, h.vsh);
glDetachShader(h.sh, h.fsh);
glDeleteShader(h.vsh);
glDeleteShader(h.fsh);
return h;
顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
片段着色器
#version 330 core
out vec4 FragColor;
void main()
FragColor = vec4(1.0,1.0,1.0,1.0);
【问题讨论】:
您已经对着色器编译和链接进行了错误检查,但在主循环中没有任何内容。在主循环中添加一些错误检查。要么你在画黑色,你在向后画,你在相机后面画,或者你忽略了一个错误。 @3Dave 在主循环中检查错误是有意义的。您对如何对主循环中的程序运行错误检查有什么建议吗?我想这不是编译和链接中的着色器错误日志。抱歉,我是 OpenGL 的新手。glGetError
。见khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetError.xml
如果你在你的主循环中放了一堆,比如,在每次gl*
调用之后,你会找到错误的来源。那时有点二进制搜索调试。对于无效操作,每个gl*
函数的帮助页面都会列出错误情况。
那个没有错误,把它放在循环中的每个调用之后。关于这个在相机后面的图,我所有的z值都是0.0f,我想只要视口设置正确,它就不会在右边?
【参考方案1】:
我找到了答案。如果您仔细查看 main,似乎您实际上应该将 glBindBuffer 调用到宏 GL_ARRAY_BUFFER 而不是像我想的那样调用 vbo 句柄。解决这个问题会导致我的程序运行。我的窗口提示也没有生效,因为我在创建窗口后调用它们。
【讨论】:
以上是关于OpenGL 着色器编译但窗口中未出现渲染的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 OpenGL 编译顶点着色器时会出现着色器编译器错误 #143、#160 和 #216?