目前,我试图让一个三角形使用OpenGL 3.3和C++与GLM,GLFW3和GLEW库来渲染,而是得到一个错误试图创建时我的shader程序。的OpenGL 3.3/GLSL&C++的错误:“必须写入GL_POSITION”
Vertex info
(0) : error C5145: must write to gl_Position
我已经试图找出为什么出现这种情况,并要求对其他论坛,但没有人知道是什么原因。有三种可能的点,其中该错误可能有他的起源 - 在我main.cpp中,在那里我创建窗口,上下文,该程序,则VAO等...
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <iostream>
#include <string>
#include "util/shaderutil.hpp"
#define WIDTH 800
#define HEIGHT 600
using namespace std;
using namespace glm;
GLuint vao;
GLuint shaderprogram;
void initialize() {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glClearColor(0.5, 0.7, 0.9, 1.0);
string vShaderPath = "shaders/shader.vert";
string fShaderPath = "shaders/shader.frag";
shaderprogram = ShaderUtil::createProgram(vShaderPath.c_str(), fShaderPath.c_str());
}
void render() {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderprogram);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void clean() {
glDeleteProgram(shaderprogram);
}
int main(int argc, char** argv) {
if (!glfwInit()) {
cerr << "GLFW ERROR!" << endl;
return -1;
}
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* win = glfwCreateWindow(WIDTH, HEIGHT, "Rendering a triangle!", NULL, NULL);
glfwMakeContextCurrent(win);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
cerr << "GLEW ERROR!" << endl;
return -1;
} else {
glGetError();
//GLEW BUG: SETTING THE ERRORFLAG TO INVALID_ENUM; THEREFORE RESET
}
initialize();
while (!glfwWindowShouldClose(win)) {
render();
glfwPollEvents();
glfwSwapBuffers(win);
}
clean();
glfwDestroyWindow(win);
glfwTerminate();
return 0;
}
...的ShaderUtil一流的,在这里我在着色器文件中读取,编译它们,做错误检查,并返回一个最终方案...
#include "shaderutil.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
GLuint ShaderUtil::createProgram(const char* vShaderPath, const char* fShaderPath) {
/*VARIABLES*/
GLuint vertexShader;
GLuint fragmentShader;
GLuint program;
ifstream vSStream(vShaderPath);
ifstream fSStream(fShaderPath);
string vSCode, fSCode;
/*CREATING THE SHADER AND PROGRAM OBJECTS*/
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
/*READING THE SHADERCODE*/
/*CONVERTING THE SHADERCODE TO CHAR POINTERS*/
while (vSStream.is_open()) {
string line = "";
while (getline(vSStream, line)) {
vSCode += "\n" + line;
}
vSStream.close();
}
const char* vSCodePointer = vSCode.c_str();
while (fSStream.is_open()) {
string line = "";
while (getline(fSStream, line)) {
fSCode += "\n" + line;
}
fSStream.close();
}
const char* fSCodePointer = fSCode.c_str();
/*COMPILING THE VERTEXSHADER*/
glShaderSource(vertexShader, 1, &vSCodePointer, NULL);
glCompileShader(vertexShader);
/*VERTEXSHADER ERROR CHECKING*/
GLint vInfoLogLength;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &vInfoLogLength);
if (vInfoLogLength > 0) {
vector<char> vInfoLog(vInfoLogLength + 1);
glGetShaderInfoLog(vertexShader, vInfoLogLength, &vInfoLogLength, &vInfoLog[0]);
for(int i = 0; i < vInfoLogLength; i++) {
cerr << vInfoLog[i];
}
}
/*COMPILING THE FRAGMENTSHADER*/
glShaderSource(fragmentShader, 1, &fSCodePointer, NULL);
glCompileShader(fragmentShader);
/*FRAGMENTSHADER ERROR CHECKING*/
GLint fInfoLogLength;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &fInfoLogLength);
if (fInfoLogLength > 0) {
vector<char> fInfoLog(fInfoLogLength + 1);
glGetShaderInfoLog(fragmentShader, fInfoLogLength, &fInfoLogLength, &fInfoLog[0]);
for(int i = 0; i < fInfoLogLength; i++) {
cerr << fInfoLog[i];
}
}
/*LINKING THE PROGRAM*/
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
//glValidateProgram(program);
/*SHADERPROGRAM ERROR CHECKING*/
GLint programInfoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &programInfoLogLength);
if (programInfoLogLength > 0) {
vector<char> programInfoLog(programInfoLogLength + 1);
glGetProgramInfoLog(program, programInfoLogLength, &programInfoLogLength, &programInfoLog[0]);
for(int i = 0; i < programInfoLogLength; i++) {
cerr << programInfoLog[i];
}
}
/*CLEANUP & RETURNING THE PROGRAM*/
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return program;
}
...和顶点着色器本身,这是没有什么特别的。我只是创建一个顶点数组,并将它们推入gl_Position。
#version 330 core
void main() {
const vec3 VERTICES[3] = vec3[3] {
0.0, 0.5, 0.5,
0.5,-0.5, 0.5,
-0.5,-0.5, 0.5
};
gl_Position.xyz = VERTICES;
gl_Position.w = 1.0;
}
fragmentshader只输出一个叫做color的vec4,它被设置为(1.0,0.0,0.0,1.0)。编译器不会显示任何错误,但是当我尝试执行该程序时,我只是得到一个没有三角形的窗口和上面显示的错误消息。
还有我已经尝试过解决这个问题的几件事情,但他们没有工作:
我尝试创建我的main.cpp里面的顶点,并通过顶点推入顶点着色器缓冲对象;我改变了一些受opengl-tutorials.org启发的代码,最后得到了一个三角形来显示,但着色器没有应用;我只有main.cpp中的顶点出现在屏幕上,但“必须写入gl_Position”问题依然存在。
我尝试了不同的地方使用glGetError(),并得到了2个不同的错误代码:1280和1282;第一个是由GLEW内部的一个错误引起的,这导致状态从GL_NO_ERROR改变为GL_INVALID_ENUM或类似的东西。我被告知忽略这个,并且在初始化GLEW之后通过使用glGetError()将状态改回到GL_NO_ERROR。在渲染函数中使用glUseProgram()后出现了另一个错误代码。我想从中获得一些信息,但gluErrorString()函数在OpenGL 3.3中已被弃用,我找不到任何我的库提供的替代方法。
我试着将它链接验证后通过glValidateProgram我的程序()。当我这样做时,GL_POSITION错误信息没有露面了,但三角形没有任何,所以我认为这个功能只是清除信息日志把一些新的信息有关验证过程
所以现在,我不知道是什么原因导致了这个错误。
'VERTICES'是三个'vec3'实例的数组。 'gl_Position.xyz'是一个'vec3'。不计算。 – 2014-09-13 01:09:36
是的,顶点着色器不会编译。如果你遇到错误情况,你有没有检查过调试器?出于某种原因,您可能看不到错误输出。例如,打印错误后,您不会输出换行符。尝试添加一个'cerr << endl'。 – 2014-09-13 01:32:12