目前,我試圖讓一個三角形使用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