Я тренируюсь в программировании openGL и хочу создать свои собственные классы, чтобы облегчить мне жизнь.Однако в моем классе Shader я столкнулся с проблемой.
Мой класс Shader состоит из одной строки C ++ (имя шейдера) и двух других строк C (которые содержат код фрагмента ивершинные шейдеры).
Затем, во время инициализации, я читаю свои файлы, чтобы записать каждый символ в мою строку C.На данный момент эти две переменные заполнены правильно, но если я попытаюсь прочитать их с помощью моего getVertex()
метода, он вообще не покажет мне, что в нем должно быть.
Код шейдеров фрагментов и вершин должениметь запас в const GLchar *
из-за glShaderSource()
, который используется для загрузки шейдеров.Вот прототип этой функции: void glShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
.
Я уже пытался использовать базовый const char *
как const GLchar *
, но он четный.
Я также пытался снабдить шейдерамикод в строки C ++ и преобразовать их в строку C в основном, но это ничего не меняет.
Вот мой код с отладочной печатью:
-main.cpp
#include "head.h"
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
int main(){
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //For MacOS
/*Window initialization*/
GLFWwindow* window = glfwCreateWindow(800, 600, "Hello Window!", NULL, NULL);
if (window == NULL){
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
/*GLAD initialization*/
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
/*Initialize shaders*/
Shader myShaders("Hello");
std::cout << "Main Print\n" << myShaders.getVertex() << std::endl;
/*Triangle Vertices*/
/*float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};*/
/*Rectangle Vertices*/
float vertices[] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
unsigned int VBO;
glGenBuffers(1, &VBO);
/*Define the type of the VBO*/
glBindBuffer(GL_ARRAY_BUFFER, VBO);
/*Copy vertices into the GL_ARRAY_BUFFER object (VBO)*/
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/*Creating a VS object*/
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
/*Link the VS code to the VS object*/
glShaderSource(vertexShader, 1, &myShaders.getVertex(), NULL);
glCompileShader(vertexShader);
/*Testing the VS compilation*/
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success){
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
/*As the VS, same for FS*/
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &myShaders.getFragment(), NULL);
glCompileShader(fragmentShader);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
/*Creating the program Shader*/
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
/*Testing PS compilation*/
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
/*Deleting shaders already used*/
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
/*Activating our shader*/
glUseProgram(shaderProgram);
/*How to interprets data*/
/*(layout (location = 0),vec3,type of the vec,for [-1.0;1.0],stride worked with 0 too, offset to begin*/
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
/*Creating Vertex Array Object*/
unsigned int VAO;
glGenVertexArrays(1, &VAO);
// 1. Lier le Vertex Array Object (VAO)
glBindVertexArray(VAO);
// 2. Copier les sommets dans un tampon pour qu’OpenGL les utilise
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. Initialiser les pointeurs d’attributs de sommets
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
/*Creating an EBO for tell the order of vertices to being draw*/
unsigned int EBO;
glGenBuffers(1, &EBO);
/*GL_ELEMENT_ARRAY_BUFFER for EBO*/
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
/*Setting the view*/
glViewport(0, 0, 800, 600);
/*To get a thread style*/
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
/*Render Loop*/
while (!glfwWindowShouldClose(window)){
glClearColor(0.5f, 0.3f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
processInput(window);
glUseProgram(shaderProgram);
//glBindVertexArray(VAO);
/*(Kind of primitive to use, begin of vertices tab, end of vertices tab)*/
//glDrawArrays(GL_TRIANGLES, 0, 3);
/*6 for length of EBO*/
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
/*Resize*/
void framebuffer_size_callback(GLFWwindow* window, int width, int height){
glViewport(0, 0, width, height);
}
/*Handle inputs*/
void processInput(GLFWwindow* window){
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
-shader.hpp:
#pragma once
class Shader {
public:
Shader(std::string const& name) : name_(name){
std::string tmp;
std::ifstream stream("./shaders/" + name_ + ".fs");
if(stream) {
while (stream.good()) {
tmp += stream.get();
}
}
fragment_ = tmp.c_str();
stream.close();
tmp = "";
stream.open("./shaders/" + name_ + ".vs");
if(stream) {
while (stream.good()) {
tmp += stream.get();
}
}
vertex_ = tmp.c_str();
stream.close();
std::cout << "Shader Initialization Print\n" << vertex_ << "\n\n";
}
void initialize(){
if (name_.size() > 0) {
std::string tmp;
std::ifstream stream("./shaders/" + name_ + ".fs");
if (stream) {
while (stream.good()) {
tmp += stream.get();
}
}
fragment_ = tmp.c_str();
stream.close();
tmp = "";
stream.open("./shaders/" + name_ + ".vs");
if (stream) {
while (stream.good()) {
tmp += stream.get();
}
}
vertex_ = tmp.c_str();
stream.close();
}
}
void setName(std::string const& name) {
name_ = name;
}
std::string getName() {
return name_;
}
void setFragment(std::string const& fragment) {
fragment_ = fragment.c_str();
}
const GLchar* & getFragment() {
return fragment_;
}
void setVertex(std::string const& vertex) {
vertex_ = vertex.c_str();
}
const GLchar* & getVertex() {
std::cout << "getVertex() Print\n" << vertex_ << "\n\n";
return vertex_;
}
private:
std::string name_;
const GLchar * vertex_;
const GLchar * fragment_;
};
-head.h:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "shader.hpp"
-Trace исполнения
Shader Initialization Print
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
getVertex() Print
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
Main Print
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
getVertex() Print
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
ERROR::SHADER::VERTEX::COMPILATION_FAILED
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
ERROR::SHADER::PROGRAM::COMPILATION_FAILED
Vertex info
-----------
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
(0) : error C2003: incompatible options for link
Fragment info
-------------
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
(0) : error C2003: incompatible options for link
Собственно, я ожидаючтобы получить то, что печатают инициализацию шейдера везде, я вызываю свои getVertex()
/ getFragment()
методы.