Я только начал изучать Grpahics в C ++, а также шейдеры и спрайты.Я написал небольшой вершинный шейдер и фрагментный шейдер.
Вершинный шейдер:
#version 130
in vec2 vertexPosition;
void main() {
gl_Position.xy = vertexPosition;
gl_Position.z = 0.0;
gl_Position.w = 1.0;
}
Фрагментный шейдер:
#version 130
out vec3 color;
void main() {
color = vec3(0.94, 0.37, 0.36);
}
При компиляции я получаю следующие сообщения об ошибках:
Fragment shader failed to compile with the following errors:
ERROR: 0:6: error(#143) Undeclared identifier: gl_Position
ERROR: 0:6: error(#216) Vector field selection out of range "xy"
ERROR: 0:6: error(#160) Cannot convert from: "default in highp 2-component vector of vec2" to: "float"
ERROR: 0:7: error(#216) Vector field selection out of range "z"
ERROR: 0:8: error(#216) Vector field selection out of range "w"
ERROR: error(#273) 5 compilation errors. No code generated
Как исправить эти ошибки?
PS: Я использую встроенную графику процессора AMD A10 8700P Radeon R6.Читая другие вопросы, я заметил, что использование видеокарты AMD является основной причиной ряда проблем, поэтому, если это проблема в моем случае, то как я могу это исправить?
Я использую отдельный класс для всехGLSL-манипуляции.
GLSLProgram.h:
#pragma once
#include <GL/glew.h>
#include <string>
class GLSLProgram
{
public:
GLSLProgram();
~GLSLProgram();
void compileShaders(const std::string &vertexShaderFilePath, const std::string &fragmentShaderFilePath);
void linkShaders();
void addAttribute(const std::string& attributeName);
void use();
void unuse();
private:
int _numAttributes;
void compileShader(const std::string &filePath, GLuint id);
GLuint _programID;
GLuint _vertexShaderID;
GLuint _fragmentShaderID;
};
GLSLProgram.cpp:
#include "GLSLProgram.h"
#include "Errors.h"
#include <fstream>
#include <vector>
GLSLProgram::GLSLProgram() :
_numAttributes(0), _programID(0), _vertexShaderID(0), _fragmentShaderID(0)
{
}
GLSLProgram::~GLSLProgram() {
}
void GLSLProgram::compileShaders(const std::string &vertexShaderFilePath, const std::string &fragmentShaderFilePath) {
_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if (!_vertexShaderID) {
fatalError("Vertex Shader failed to be created!");
}
_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (!_fragmentShaderID) {
fatalError("Fragment Shader failed to be created!");
}
compileShader(vertexShaderFilePath, _vertexShaderID);
compileShader(vertexShaderFilePath, _fragmentShaderID);
}
void GLSLProgram::linkShaders() {
// Vertex and fragment shaders are successfully compiled.
// Now time to link them together into a program.
// Get a program object.
_programID = glCreateProgram();
// Attach our shaders to our program
glAttachShader(_programID, _vertexShaderID);
glAttachShader(_programID, _fragmentShaderID);
// Link our program
glLinkProgram(_programID);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(_programID, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<char> errorLog(maxLength);
glGetProgramInfoLog(_programID, maxLength, &maxLength, &errorLog[0]);
// We don't need the program anymore.
glDeleteProgram(_programID);
// Don't leak shaders either.
glDeleteShader(_vertexShaderID);
glDeleteShader(_fragmentShaderID);
std::printf("%s\n", &(errorLog[0]));
fatalError("Shaders failed to link!");
}
// Always detach shaders after a successful link.
glDetachShader(_programID, _vertexShaderID);
glDetachShader(_programID, _fragmentShaderID);
glDeleteShader(_vertexShaderID);
glDeleteShader(_fragmentShaderID);
}
void GLSLProgram::addAttribute(const std::string &attributeName) {
glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str());
}
void GLSLProgram::use() {
glUseProgram(_programID);
for(int i = 0; i < _numAttributes; ++i) {
glEnableVertexAttribArray(i);
}
}
void GLSLProgram::unuse() {
glUseProgram(0);
for(int i = 0; i < _numAttributes; ++i) {
glDisableVertexAttribArray(i);
}
}
void GLSLProgram::compileShader(const std::string &filePath, GLuint id)
{
std::ifstream shaderFile(filePath);
if (shaderFile.fail())
{
perror(filePath.c_str());
fatalError("Failed to open " + filePath);
}
std::string fileContents = "";
std::string line;
while (std::getline(shaderFile, line))
{
fileContents += line + "\n";
}
shaderFile.close();
const char *contentsPtr = fileContents.c_str();
glShaderSource(id, 1, &contentsPtr, nullptr);
glCompileShader(id);
GLint success = 0;
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if (success == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
std::vector<char> errorLog(maxLength);
glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
glDeleteShader(id);
std::printf("%s\n", &(errorLog[0]));
fatalError("Shader " + filePath + " Failed to compile");
}
}
Fatal Error просто печатает предоставленную строку и завершает работу.