Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Fail to draw a rectangle after rendering on a framebuffer once with opengl  (Read 2048 times)

0 Members and 1 Guest are viewing this topic.

jokoon

  • Newbie
  • *
  • Posts: 35
    • View Profile
The goal here is to create noise, render on a framebuffer, pull the data on the CPU (done in pull()). I don't need to do further rendering with opengl in the loop, I only need it at the beginning.

I load glad after initializing my SFML window, and my opengl code works fine.

The problem is drawing things with SFML again.

I've read the example and the tutorial but I fail to understand what is going wrong...

Here is the code.

Shader class

#ifndef SHADER_H
#define SHADER_H

#include <glad/glad.h>
#include <glm/glm.hpp>

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
namespace gl_things {
    class Shader
    {
    public:
        unsigned int ID;
        // constructor generates the shader on the fly
        // ------------------------------------------------------------------------
        Shader() {}
        Shader(const char* vertexPath, const char* fragmentPath)
        {
            // 1. retrieve the vertex/fragment source code from filePath
            std::string vertexCode;
            std::string fragmentCode;
            std::ifstream vShaderFile;
            std::ifstream fShaderFile;
            // ensure ifstream objects can throw exceptions:
            vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
            fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
            try
            {
                // open files
                vShaderFile.open(vertexPath);
                fShaderFile.open(fragmentPath);
                std::stringstream vShaderStream, fShaderStream;
                // read file's buffer contents into streams
                vShaderStream << vShaderFile.rdbuf();
                fShaderStream << fShaderFile.rdbuf();
                // close file handlers
                vShaderFile.close();
                fShaderFile.close();
                // convert stream into string
                vertexCode = vShaderStream.str();
                fragmentCode = fShaderStream.str();
            }
            catch (std::ifstream::failure e)
            {
                std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
            }
            const char* vShaderCode = vertexCode.c_str();
            const char * fShaderCode = fragmentCode.c_str();
            // 2. compile shaders
            unsigned int vertex, fragment;
            int success;
            char infoLog[512];
            // vertex shader
            vertex = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertex, 1, &vShaderCode, NULL);
            glCompileShader(vertex);
            checkCompileErrors(vertex, "VERTEX");
            // fragment Shader
            fragment = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragment, 1, &fShaderCode, NULL);
            glCompileShader(fragment);
            checkCompileErrors(fragment, "FRAGMENT");
            // shader Program
            ID = glCreateProgram();
            glAttachShader(ID, vertex);
            glAttachShader(ID, fragment);
            glLinkProgram(ID);
            checkCompileErrors(ID, "PROGRAM");
            // delete the shaders as they're linked into our program now and no longer necessery
            glDeleteShader(vertex);
            glDeleteShader(fragment);

        }
        // activate the shader
        // ------------------------------------------------------------------------
        void use() const
        {
            glUseProgram(ID);
        }
        // utility uniform functions
        // ------------------------------------------------------------------------
        void setBool(const std::string &name, bool value) const
        {
            glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
        }
        // ------------------------------------------------------------------------
        void setInt(const std::string &name, int value) const
        {
            glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
        }
        // ------------------------------------------------------------------------
        void setFloat(const std::string &name, float value) const
        {
            glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
        }
        // ------------------------------------------------------------------------
        void setVec2(const std::string &name, const glm::vec2 &value) const
        {
            glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
        }
        void setVec2(const std::string &name, float x, float y) const
        {
            glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
        }
        // ------------------------------------------------------------------------
        void setVec3(const std::string &name, const glm::vec3 &value) const
        {
            glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
        }
        void setVec3(const std::string &name, float x, float y, float z) const
        {
            glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
        }
        // ------------------------------------------------------------------------
        void setVec4(const std::string &name, const glm::vec4 &value) const
        {
            glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
        }
        void setVec4(const std::string &name, float x, float y, float z, float w) const
        {
            glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
        }
        // ------------------------------------------------------------------------
        void setMat2(const std::string &name, const glm::mat2 &mat) const
        {
            glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
        }
        // ------------------------------------------------------------------------
        void setMat3(const std::string &name, const glm::mat3 &mat) const
        {
            glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
        }
        // ------------------------------------------------------------------------
        void setMat4(const std::string &name, const glm::mat4 &mat) const
        {
            glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
        }

    private:
        // utility function for checking shader compilation/linking errors.
        // ------------------------------------------------------------------------
        void checkCompileErrors(GLuint shader, std::string type)
        {
            GLint success;
            GLchar infoLog[1024];
            if (type != "PROGRAM")
            {
                glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
                if (!success)
                {
                    glGetShaderInfoLog(shader, 1024, NULL, infoLog);
                    std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
                }
            }
            else
            {
                glGetProgramiv(shader, GL_LINK_STATUS, &success);
                if (!success)
                {
                    glGetProgramInfoLog(shader, 1024, NULL, infoLog);
                    std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
                }
            }
        }
    };
}
#endif

actual code

//#include "stdafx.h"
#include <algorithm>

#include <iostream>
#include <string>
#include <vector>
#include <map>

#include <SFML/Graphics.hpp>

//#include <SFML/OpenGL.hpp>
//#include <Box2D\Box2D.h>
using namespace std;
using namespace sf;

#include "glad\glad.h"
//#define GLAD_GL_IMPLEMENTATION
//#include "gl.h"

#include "shader_m.h"
#include <SFML\Window\ContextSettings.hpp>

typedef Vector2f Vec2;
typedef Vector2<double> Vec2d;
typedef Vector2i Vec2i;

#define msg(s) cout<< #s << " " << s << endl;

RenderWindow * window;
Vec2i windowsize;

namespace perlin_shading {
    gl_things::Shader ourShader;

    float vertices[] = {
        // positions          // colors           // texture coords
        // 0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
        // 0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
        //-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
        //-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
         1.f,  1.f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
         1.f, -1.f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
        -1.f, -1.f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
        -1.f,  1.f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
    };
    unsigned int indices[] = {
        0, 1, 3, // first triangle
        1, 2, 3  // second triangle
    };
    unsigned int VBO, VAO, EBO;
    unsigned int texture, tex32F, fbo;

    void init_geom() {
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);

        glBindVertexArray(VAO);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

        // position attribute
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
        // color attribute
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
        glEnableVertexAttribArray(1);
        // texture coord attribute
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
        glEnableVertexAttribArray(2);

    }
    void init_framebuffer() {
        // texture with internal format `GL_RGBA32F`
        //GLuint tex32F = texture;
        glGenTextures(1, &tex32F);
        glBindTexture(GL_TEXTURE_2D, tex32F);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 300, 300, 0, GL_RED, GL_FLOAT, nullptr);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // framebuffer with attached texture
        //fbo = 0;
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex32F, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        {
            // In both cases you should validate the completeness of the frambuffer glCheckFramebufferStatus:
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
            if (status != GL_FRAMEBUFFER_COMPLETE) {
                glBindFramebuffer(GL_FRAMEBUFFER, 0);
                msg("glCheckFramebufferStatus error");
            }
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
        }

    }

    void pull() {
        //glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        {
            glViewport(0, 0, 300, 300);
            // bind Texture
            ourShader.use();
            glBindTexture(GL_TEXTURE_2D, texture);
            //glBindTexture(GL_TEXTURE_2D, tex32F);
            glBindVertexArray(VAO);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        }

        //glfwSwapBuffers(window);

        // Render the image after glBindFramebuffer(GL_FRAMEBUFFER, fbo). After the rendering by the shader the image is stored in the texture object, because the texture is attached to the color plane of fbo. So at this point the texture can be read by glGetTexImage
        glBindTexture(GL_TEXTURE_2D, tex32F);

        float values[300 * 300];
        //glFinish();
        glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, values);

        float min_val = 1e20, max_val = -1e20;

        for (int i = 0; i < 300; ++i) {
            for (int j = 0; j < 300; ++j) {
                float val = values[i + 300 * j];
                max_val = max(val, max_val);
                min_val = min(val, min_val);
            }
        }
        msg(max_val);
        msg(min_val);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

    }
    int do_things() {

        window->setActive(true);
        {
            if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(sf::Context::getFunction)))
            //if (!gladLoadGL())
            {
                std::cout << "Failed to initialize GLAD" << std::endl;
                return -1;
            }
            ourShader = gl_things::Shader("shaders/quad.vs", "shaders/perlin2.fs");

            init_geom();
            init_framebuffer();
            pull();
        }
        window->setActive(false);

        window->resetGLStates();

    }
}

// initializing the window
void init_window() {
    Vec2i screen_resolution = { int(VideoMode::getDesktopMode().width), int(VideoMode::getDesktopMode().height) };

    windowsize = Vec2i(0.5f*screen_resolution.x, 0.9f*screen_resolution.y);

    // placing the window on the desktop
    Vec2i windowpos;
    VideoMode::getDesktopMode().height;

    windowpos = Vec2i(
        screen_resolution.x - windowsize.x - 10,
        screen_resolution.y - windowsize.y - 40
    );
    //auto opengl = cfg.getvar<Vec2i>("opengl");
    // ContextSettings::Core
    //ContextSettings settings(0, 0, 0, 4, 5);
    ContextSettings settings(0, 0, 0, 3, 3);

    window = new sf::RenderWindow(sf::VideoMode(windowsize.x, windowsize.y), "perlin shader");
    //window = new sf::RenderWindow(sf::VideoMode(windowsize.x, windowsize.y), "perlin shader", 7, settings);
    window->setFramerateLimit(60);
    //frame_duration = 1.0f / 60;
    window->setPosition(windowpos);
}
RectangleShape dadaism;

void draw() {

    window->pushGLStates();
    window->draw(dadaism);
    window->popGLStates();
}

void loop() {

    while (window->isOpen())
    {
        sf::Event event;
        while (window->pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::KeyPressed:
                if (event.key.code == sf::Keyboard::Escape)
                    window->close();
                break;
            case sf::Event::Closed:
                window->close();
                break;
            default:
                break;
            }
        }

        window->clear(Color(16, 16, 16));
       
        window->pushGLStates();
        draw();
        window->popGLStates();
       
        window->display();
    }
}
int main(int argc, char*argv[]) {

    dadaism = RectangleShape({ 50,50 });
    init_window();
    perlin_shading::do_things();


    loop();
    return 0;
}
 
fragment shader
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
 
vertex shader
#version 330 core
out vec4 FragColor;
// out float FragColor;

in vec3 ourColor;
in vec2 TexCoord;


void main(){
    vec3 debugged = vec3(TexCoord.xy,0);
    FragColor = vec4(0.34,0,0, 1.0f);
    // FragColor = 0.34;
}
 


« Last Edit: October 12, 2019, 04:21:30 pm by jokoon »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Can you provide a call stack of the crash?
Is your GPU driver up to date?

Also make sure to add checks around your own OpenGL code, so you know if any of your own calls cause errors.

Any reason you reimplement shader support?
« Last Edit: October 14, 2019, 08:43:57 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/