Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: OpenGL + SFML : problème pour passer un texture array vers mon shader  (Lu 1027 fois)

0 Membres et 1 Invité sur ce sujet

Stellaris

  • Newbie
  • *
  • Messages: 8
    • Voir le profil
    • E-mail
Bonjour,
Pour les besoins de mon jeu (un raycaster à la wolf3d) je dois passer un tableau de textures à mon fragment shader qui s'occupe du rendu (chose qui n'est pas possible de base avec sf::Shader)
Je passe donc par OpenGL pour ça, sauf que ca marche pas  :-\
Au niveau du shader je n'ai qu'un sampler2DArray vide (0 couches)
si j'envoie n'importe quel autre type au shader via glUniformxx ca marche sans pb...

Le code :

ShaderRenderSurface::ShaderRenderSurface(const sf::Vector2f &t_size)
{
    if (!sf::Shader::isAvailable())
    {
        throw_shader_error("Shaders are not supported on this machine !");
    }

    m_drawTexture.create(t_size.x, t_size.y);

    if (!m_renderShader.loadFromFile(c_glRenderShader, sf::Shader::Fragment))
    {
        throw_shader_error("Error loading shader '" + std::string(c_glRenderShader) + "' !");
    }

    m_drawSurface.setTexture(m_drawTexture);

    glCheck(glGenTextures(1, &m_texArray));

    sf::Shader::bind(&m_renderShader);

    glCheck(glUniform1i(glGetUniformLocation(m_renderShader.getNativeHandle(), "u_textures"), 0)); // Texture unit 0

}

void ShaderRenderSurface::update(const sf::Time &)
{
    updateUniforms();
}

void ShaderRenderSurface::setSize(const sf::Vector2f &t_size)
{
    m_drawTexture.create(t_size.x, t_size.y);
}

void ShaderRenderSurface::loadTextureArray(const std::vector<sf::Image> &t_textures)
{
    sf::Shader::bind(&m_renderShader);
    Utility::createTextureArray(m_texArray, t_textures);
}

void ShaderRenderSurface::draw(sf::RenderTarget &t_target, sf::RenderStates t_states) const
{
    t_states.shader = &m_renderShader;
    t_target.draw(m_drawSurface, t_states);
}

void ShaderRenderSurface::updateUniforms()
{
    m_renderShader.setUniform("u_resolution", sf::Vector2f(m_drawTexture.getSize()));
    m_renderShader.setUniform("u_pos", info.pos);
    m_renderShader.setUniform("u_dir", info.dir);
}

void createTextureArray(GLuint t_tex, const std::vector<sf::Image> &t_textures)
{
    assert(!t_textures.empty());

    auto size_x = std::max_element(t_textures.cbegin(), t_textures.cend(),
                                   [](const sf::Image& a, const sf::Image& b)
    {
        return a.getSize().x < b.getSize().x;
    })->getSize().x;

    auto size_y = std::max_element(t_textures.cbegin(), t_textures.cend(),
                                   [](const sf::Image& a, const sf::Image& b)
    {
        return a.getSize().y < b.getSize().y;
    })->getSize().y;

    glCheck(glActiveTexture(GL_TEXTURE0 + 0));

    glCheck(glBindTexture(GL_TEXTURE_2D_ARRAY, t_tex));

    glCheck(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, size_x, size_y, t_textures.size()));

    for (size_t i { 0 }; i < t_textures.size(); ++i)
    {
        glCheck(glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, t_textures[i].getSize().x, t_textures[i].getSize().y,
                                1, GL_RGBA, GL_UNSIGNED_BYTE, t_textures[i].getPixelsPtr()));
    }

    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    glCheck(glTexParameterf(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
    glCheck(glTexParameterf(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR));
    glCheck(glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE));
    glCheck(glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE));

    glCheck(glBindTexture(GL_TEXTURE_2D_ARRAY, 0));
}

Le shader de test :
#version 330
uniform vec2 u_resolution;
uniform vec2 u_pos = vec2(7.5, 7.5);
uniform vec2 u_dir = vec2(0, 1);
uniform sampler2DArray u_textures;

void main()
{
    gl_FragColor = texture(u_textures, vec3(gl_FragCoord.xy / u_resolution.xy, 1));
}

Du noir à chaque fois (et j'ai testé aussi la taille de la texture, 1x1 et 0 couches)

Le github du projet au besoin : https://github.com/Stellaris-code/Rayfun
« Modifié: Août 25, 2016, 07:42:09 pm par Stellaris »

 

anything