c++ - OpenGL着色器编译器抛出随机错误并且无法渲染
问题描述
我正在尝试编写一个简单的代码来在屏幕上绘制一个三角形,但是在完成 C++ 中的基本代码之后,我遇到了一个问题,即着色器编译器似乎抛出随机错误,每次编译都不同,通常出现在行:
failed to compile shader:: Operation timed out
ERROR: 0:X: 'text' : syntax error: syntax error
: Operation timed out
文本通常是某种看似随机的命令(我在docs.gl中找不到),或者是单个 ASCII 字符(包括括号、标点符号、分号、大写和小写字母)。有时,它不会抛出任何东西,有时,它甚至会抛出一个段错误,无论是否存在错误。
主.cpp:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
int loadShader(const char* path, unsigned int type){
FILE* file = fopen(path,"r");
if(file==NULL){
printf("\033[31mERROR:\033[0m failed to load shader file: %s\n", path);
return 0;
}
fseek(file, 0L, SEEK_END);
long size = ftell(file);
char* buffer = new char[size];
rewind(file);
if(!buffer){
fclose(file);
printf("\033[31mERROR:\033[0m failed to allocate memory to load shader file: %s\n", path);
return 0;
}
if(1!=fread(buffer, size, 1, file)){
fclose(file);
printf("\033[31mERROR:\033[0m failed to read shader file: %s\n", path);
return 0;
}
unsigned int shader = glCreateShader(type);
glShaderSource(shader, 1, &buffer, (int*)&size);
glCompileShader(shader);
int status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status){
char err[1024];
glGetShaderInfoLog(shader, 1024, NULL, err);
printf("\033[31mERROR:\033[0m failed to compile shader: %s\n", err);
}
std::cout<<"loaded shader successfully"<<std::endl;
delete [] buffer;
return shader;
}
int main(void){
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Aimless", nullptr, nullptr); // Windowed
//GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", glfwGetPrimaryMonitor(), nullptr); // Fullscreen
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLuint vertexShader = loadShader("vertex.shader", GL_VERTEX_SHADER);
GLuint fragmentShader = loadShader("fragment.shader", GL_FRAGMENT_SHADER);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
while(!glfwWindowShouldClose(window)){
float vertices[] = {
0.0f, 0.5f,// vertex 1
0.5f, -0.5f,// vertex 2
-0.5f, -0.5f // vertex 3
};
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
GLuint vao;
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glfwSwapBuffers(window);
glfwPollEvents();
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);
}
glfwTerminate();
return 0;
}
顶点着色器:
#version 150 core
in vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
片段着色器:
#version 150 core
out vec4 color;
void main(){
color = vec4(1.0, 1.0, 1.0, 1.0);
}
我正在使用 CLI 在 MacOS 上编译代码:
clang++ -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -lglfw -lglew main.cpp -o main.o
解决方案
你的内存分配的东西完全坏了:
char* buffer = new char(size);
这分配了一个字符并将其初始化为size
.
你想要的是new char[size]
。
你正在用你的err
消息缓冲区做同样的事情。
此外:
if(!buffer){
这不是 C++new
运算符的工作方式。如果它不能分配内存,它会抛出一个异常,而不是返回一个NULL
指针。
最后:你永远不会delete
使用缓冲区,所以当这个函数返回时你会泄漏内存。(注意,当使用正确的数组语法进行分配时,如前所述,释放的正确方法是delete [] buffer
)。
推荐阅读
- python - 使用opencv调整文件夹中的批量图像大小
- c# - 在 C# 中获取“#”哈希后的 URL 部分
- c# - 如何在 .net core 2.0 中压缩 Web API HttpClient 返回的响应?
- java - 如何从 JPA 中的表中选择一个月中的每条记录?
- javascript - 仅 HTML 内容更改时的浏览器后退/下一个箭头
- google-maps - 带有饼图和标签的地图
- python - 如何使用 gensim wikicorpus 获取带有标点符号的维基百科语料库文本?
- r - 将位置编号分配给R中的字符
- javascript - 将 C# 数据结果传递给 JavaScript 变量
- windows - 使用IP地址连接到tomcat