I am currently trying to create a 2D engine in C++ using OpenGL for fun (I have a special definition of fun). I suspect that the solution I am using to draw my assets is broken because everything worked fine on a normal OpenGL scale, but when I started making changes, everything went wrong. Additionally, when I tried to use FBOs, things started to break down further. Initially, I thought the coordinate system might be at fault, this is why i tried to change it
Here is my loop.
bool SG_Window::LoopShow() {
double lastTime = glfwGetTime();
double tickRate = 1.0 / 60.0;
this->ShaderCompilate();
while (!glfwWindowShouldClose(this->window))
{
glViewport(0, 0, this->width, this->height);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); /
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwPollEvents();
double currentTime = glfwGetTime();
double deltaTime = currentTime - lastTime;
if (deltaTime >= tickRate) {
lastTime = currentTime;
for (SG_Assets* asset : *this->linkedAssets) {
if (asset->IsActualise()) {
//glBindFramebuffer(GL_FRAMEBUFFER, asset->getFBO());
//glViewport(0, 0, asset->w, asset->h);
//glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
std::cout << "asset actualisé" << std::endl;
asset->draw();
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
//glViewport(0, 0, width, height);
glfwSwapBuffers(this->window);
}
}
for (std::function<void()> function : *this->functions) {
function();
}
}
else {
glfwWaitEventsTimeout(tickRate);
}
}
std::cout << "Sortie de la boucle de fenêtre." << std::endl;
return true;
}
and here it’s my drawing of assets system.
#include "SG_Assets.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "SG_Window.h"
#include "SG_WindowData.h"
#include <glm/gtc/type_ptr.hpp>
SG_Assets::SG_Assets(float x, float y, float w, float h, float r, float g, float b, float a)
: x(x), y(y), w(w), h(h), actualise(true)
{
offset[0] = x;
offset[1] = y;
color[0] = r;
color[1] = g;
color[2] = b;
color[3] = a;
// Initialiser les vertices dès la création de l'objet
updateVertices();
compilShader();
createBuffer();
}
void SG_Assets::updateVertices() {
float X = static_cast<float>(x);
float Y = static_cast<float>(y);
float W = static_cast<float>(w);
float H = static_cast<float>(h);
int windowWidth = SG_WindowData::getInstance().getWidth();
int windowHeight = SG_WindowData::getInstance().getHeight();
vertices[0] = X; vertices[1] = Y; // Haut gauche
vertices[2] = X + W; vertices[3] = Y; // Haut droite
vertices[4] = X; vertices[5] = Y + H; // Bas gauche
vertices[6] = X + W; vertices[7] = Y + H; // Bas droite
// Logs pour vérifier les vertices
std::cout << "Vertices updated:" << std::endl;
for (int i = 0; i < 8; ++i) {
std::cout << vertices[i] << " ";
}
std::cout << std::endl;
createBuffer();
}
void SG_Assets::createFBO() {
GL_CHECK(glGenFramebuffers(1, &fbo));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fbo));
GL_CHECK(glGenTextures(1, &textureColor));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, textureColor));
std::cout << "Creating framebuffer" << std::endl;
std::cout << "W: " << W << " H: " << H << std::endl;
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColor, 0));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
else {
std::cout << "Framebuffer created successfully." << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void SG_Assets::createBuffer() {
if (!glfwGetCurrentContext()) {
std::cerr << "OpenGL context not initialized!" << std::endl;
return;
}
GL_CHECK(glGenVertexArrays(1, &this->VAO));
std::cout << "VAO ID: " << this->VAO << std::endl;
GL_CHECK(glGenBuffers(1, &this->VBO));
std::cout << "VBO ID: " << this->VBO << std::endl;
GL_CHECK(glBindVertexArray(this->VAO));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, this->VBO));
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(this->vertices), this->vertices, GL_STATIC_DRAW));
std::cout << "Buffer data set with vertices." << std::endl;
GL_CHECK(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0));
GL_CHECK(glEnableVertexAttribArray(0));
std::cout << "Vertex attribute pointer set." << std::endl;
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
GL_CHECK(glBindVertexArray(0));
std::cout << "Buffers unbound." << std::endl;
}
void SG_Assets::setPosition(float newX, float newY) {
x = newX;
y = newY;
offset[0] = x;
offset[1] = y;
updateVertices(); // Mettre à jour les vertices
actualise = true; // Marquer l'asset pour redessinage
}
void SG_Assets::compilShader() {
this->vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cerr << "ERROR::SHADER::VERTEX::COMPILATION_FAILEDn" << infoLog << std::endl;
}
else {
std::cout << "Vertex shader compiled successfully." << std::endl;
}
this->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cerr << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILEDn" << infoLog << std::endl;
}
else {
std::cout << "Fragment shader compiled successfully." << std::endl;
}
this->shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILEDn" << infoLog << std::endl;
}
else {
std::cout << "Shader program linked successfully." << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void SG_Assets::draw() {
GL_CHECK(glUseProgram(this->shaderProgram));
GLint projectionLoc = glGetUniformLocation(shaderProgram, "projection");
if (projectionLoc == -1) {
std::cerr << "Could not find uniform 'projection' in shader program." << std::endl;
}
else {
glm::mat4 projection = *SG_WindowData::getInstance().getProjection();
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
std::cout << "Projection uniform set." << std::endl;
}
GLint colorLoc = glGetUniformLocation(shaderProgram, "color");
if (colorLoc == -1) {
std::cerr << "Could not find uniform 'color' in shader program." << std::endl;
}
else {
GL_CHECK(glUniform4fv(colorLoc, 1, color));
std::cout << "Color uniform set." << std::endl;
}
GL_CHECK(glBindVertexArray(VAO));
GL_CHECK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
std::cout << "Drawing arrays." << std::endl;
// Réinitialiser le drapeau après le dessin, a remettre si on veut que l'asset ne soit pas redessiné
}
void SG_Assets::drawStencil() {
GL_CHECK(glBindVertexArray(VAO));
GL_CHECK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
GLuint SG_Assets::getFBO() {
return this->fbo;
}
bool SG_Assets::IsActualise() {
return actualise;
}
void SG_Assets::Actualise() {
actualise = true;
}
void SG_Assets::Lock() {
actualise = true;
}
void checkGLError(const char* stmt, const char* fname, int line) {
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
std::cerr << "OpenGL error " << err << ", at " << fname << ":" << line << " - for " << stmt << std::endl;
abort();
}
}
i have try a lot of things, nothing work, i am becoming mad pls help me (i know, a big part of the code is not optimal, a lot of open pointeurs but i juste have start the project, i will deal with that when it work)
A lot of thing, every checkpoint i place is complete by the programme, everything look goods but no display.
Alertinime is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1