I'm learning Opengl with SFML right now...but there seems to be an unknown problem with the code, because the shader doesn't work (no color; mesh is just white). Maybe someone can help out, please?
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
#include <glm/gtc/type_ptr.hpp>
#include <GL/gl.h>
#include <vector>
class Shader
{
public:
Shader(const std::string& vertexCode, const std::string& fragmentCode);
void Use();
private:
uint32_t programID{};
};
Shader::Shader(const std::string& vertexCode, const std::string& fragmentCode)
{
const char* vertexShaderCode = vertexCode.c_str();
const char* fragmentShaderCode = fragmentCode.c_str();
// vertexshader
size_t vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderCode, nullptr);
glCompileShader(vertexShader);
int success{};
char infoLog[1024]{};
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 1024, nullptr, infoLog);
std::cerr << "Failed to compile shader!\nInfoLog:\n" << infoLog;
}
//fragmentshader
size_t fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderCode, nullptr);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 1024, nullptr, infoLog);
std::cerr << "Failed to compile shader!\nInfoLog:\n" << infoLog;
}
//
size_t programID = glCreateProgram();
glAttachShader(programID, vertexShader);
glAttachShader(programID, fragmentShader);
glLinkProgram(programID);
glGetProgramiv(programID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(programID, 1024, nullptr, infoLog);
std::cerr << "Failed to link shader!\nInfoLog:\n" << infoLog;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void Shader::Use()
{
glUseProgram(programID);
}
class Mesh
{
public:
Mesh(std::vector<glm::vec3> vertices, std::vector<uint32_t> indices);
void Draw() const;
private:
std::vector<glm::vec3> vertices;
std::vector<uint32_t> indices;
uint32_t vao, vbo, ebo;
};
Mesh::Mesh(std::vector<glm::vec3> vertices, std::vector<uint32_t> indices)
: vertices(vertices), indices(indices), vao(), vbo(), ebo()
{
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(glm::uint32_t), indices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Mesh::Draw() const
{
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
}
int main()
{
const char* vertexShaderCode = "#version 330 core\n"
"layout (location = 0) in vec3 pos;\n"
"void main() { gl_Position = vec4(pos, 1.0); }\n";
const char* fragmentShaderCode = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main() { FragColor = vec4(0.0, 0.0, 1.0, 1.0); }\n";
sf::Window window(sf::VideoMode(800, 800), "3D OpenGL");
if (glewInit() != GLEW_OK)
{
std::cerr << "Failed to initialize GLEW\n";
return -1;
}
Shader shader(vertexShaderCode, fragmentShaderCode);
Mesh mesh({
glm::vec3(0.8f, 0.8f, 0.0f), // top right
glm::vec3(0.8f, -0.8f, 0.0f), // bottom right
glm::vec3(-0.8f,-0.8f, 0.0f), // bottom left
glm::vec3(-0.8f, 0.8f, 0.0f), // top left
}, { 0,1,3,1,2,3, });
glClearColor(0.3f, 0.2f, 0.0f, 1.0f);
while (window.isOpen())
{
sf::Event event{};
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
glClear(GL_COLOR_BUFFER_BIT);
shader.Use();
mesh.Draw();
window.display();
}
}