Я только начал свой путь в графических вычислениях, поэтому я начал с понимания этого урока: https://learnopengl.com/Getting-started/Hello-Triangle.
Прежде чем приступить к созданию "динамического" рисования, я подумал, что преобразовать его в класс "Renderer"Интересно, что это был результат:
#pragma once
#include <fstream>
#include <vector>
#include "pch.h"
class Renderer {
public:
Renderer(GLFWwindow*);
void initVertexShaders(std::vector<std::string>&);
void initFragmentShaders(std::vector<std::string>&);
void load(float*, size_t);
void draw();
const GLubyte* renderer;
const GLubyte* version;
private:
GLFWwindow* window = nullptr;
GLuint vbo;
GLuint vao;
GLuint shaderProgram = 0; //= glCreateProgram();
GLuint vs[100];
GLuint fs[100];
};
pch.h - это предварительно скомпилированный заголовок, чтобы не компилировать glm, glfw и glew каждый раз при сборке проекта.
Идея заключалась в том, чтобы изолироватьразличные утилиты, я бы использовал load (float *, size_t) для отправки информации в gpu и draw () во время цикла главного окна.Идея состоит в том, чтобы сделать первое приближение к двумерному движку рендеринга без камеры.
В любом случае, исходный код:
#include "Renderer.hpp"
Renderer::Renderer(GLFWwindow* window) {
this->window = window;
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
this->renderer = glGetString(GL_RENDERER);
this->version = glGetString(GL_VERSION);
this->vao = 0;
this->vbo = 0;
}
void Renderer::load(float* points, size_t memory) {
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, memory, points, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
void Renderer::draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
void Renderer::initVertexShaders(std::vector<std::string>& paths) {
int i = 0;
std::ifstream ifs;
if(this->shaderProgram == 0) shaderProgram = glCreateProgram();
for (const auto& path : paths){
ifs.open(path);
std::string program_str(( std::istreambuf_iterator<char>(ifs)),
( std::istreambuf_iterator<char>() ));
const char* program_src = program_str.c_str();
vs[i] = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs[i], 1, &program_src, NULL);
glCompileShader(vs[i]);
glAttachShader(shaderProgram, vs[i]);
i++;
}
glLinkProgram(shaderProgram);
}
void Renderer::initFragmentShaders(std::vector<std::string>& paths) {
int i = 0;
std::ifstream ifs;
if(this->shaderProgram == 0) shaderProgram = glCreateProgram();
for (const auto& path : paths){
ifs.open();
std::string program_str(( std::istreambuf_iterator<char>(ifs)),
( std::istreambuf_iterator<char>() ));
const char* program_src = program_str.c_str();
fs[i] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs[i], 1, &program_src, NULL);
glCompileShader(fs[i]);
glAttachShader(shaderProgram, fs[i]);
i++;
}
glLinkProgram(shaderProgram);
}
Проблема возникает во время шейдера, я могу читать файлы безпроблема, но они ничего не делают.
Вопросы следующие: имеет ли смысл хранить все шейдеры в массиве?Может ли шейдерная программа состоять из нескольких вершинных / фрагментных шейдеров?Ошибка в другом месте?Весь класс имеет смысл в любом случае?
Спасибо.
edit: Код из main.cpp
#include "Renderer.hpp"
float points[] = {
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
//
0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
int main() {
std::vector<std::string> vertexShaders;
std::vector<std::string> fragmentShaders;
vertexShaders.push_back("shader/vs.glsl");
fragmentShaders.push_back("shader/fs.glsl");
glfwInit(); //glfwGetPrimaryMonitor()
GLFWwindow *window = glfwCreateWindow(960, 540, "Hello Triangle", NULL, NULL);
Renderer Ren(window);
Ren.load(points, sizeof(points));
Ren.initVertexShaders(vertexShaders);
Ren.initFragmentShaders(fragmentShaders);
while (!glfwWindowShouldClose(window)) {
Ren.draw();
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}