Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind SDL2 texture to GLSL shader

Tags:

opengl

glsl

sdl

I'm trying to bind a sdl2 texture to a glsl shader though I'm not entirely sure how? I'm using a library called glfx to handle the glsl shaders and I've been helping with the development of this library as well. I'm pretty sure I've got everything else right but it crashes when I call SDL_GL_BindTexture. Can anyone see what I've done wrong?

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <GL/glew.h>
#include <GL/glfx.h>
#include <SDL2/SDL.h>
#include <FreeImage.h>

int main()
{
    SDL_Window *mainwindow;
    SDL_Renderer *renderer;
    SDL_GLContext maincontext;

    SDL_Init( SDL_INIT_VIDEO );

    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );

    SDL_CreateWindowAndRenderer( 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN, &mainwindow, &renderer );

    maincontext = SDL_GL_CreateContext( mainwindow );

    glewExperimental = GL_TRUE;
    glewInit( );
    fprintf( stdout, "%s\n", glGetString(GL_VERSION) );
    fprintf( stdout, "%s\n", glGetString(GL_SHADING_LANGUAGE_VERSION) );

    FIBITMAP* dib = FreeImage_Load( FIF_PNG, "test.png" );
    uint32_t w = FreeImage_GetWidth( dib );
    uint32_t h = FreeImage_GetHeight( dib );

    dib = FreeImage_ConvertTo32Bits( dib );

    BYTE* pixeles = FreeImage_GetBits( dib );
    GLubyte* textura = new GLubyte[4*w*h];

    SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, w, h );

    const SDL_Rect rect = { 0, 0, w, h };
    int pitch = 32;
    SDL_LockTexture( texture, &rect, (void**)&textura, &pitch );

    for( uint32_t j = 0; j < w * h; j++ )
    {
        textura[j*4+0] = pixeles[j*4+2];
        textura[j*4+1] = pixeles[j*4+1];
        textura[j*4+2] = pixeles[j*4+0];
        textura[j*4+3] = pixeles[j*4+3];
    }
    SDL_UnlockTexture( texture );

    FreeImage_Unload( dib );

    delete [] textura;

    int effect = glfxGenEffect( );

    std::string shader;

    shader ="struct VSinput\n"
            "{\n"
            "    vec3 Position;\n"
            "};\n"

            "shader VSmain(in VSinput VSin, out vec2 TexCoord)\n"
            "{\n"
            "    gl_Position = vec4(VSin.Position, 1.0);\n"
            "    TexCoord = vec2( 0.8, 0.8 );\n"
            "};\n"

            "uniform sampler2D gColorMap;\n"

            "shader FSmain(in vec2 TexCoord, out vec4 FragColor)\n" 
            "{\n"
            "    FragColor = texture(gColorMap, TexCoord);\n"
            "}\n"   

            "program SimpleTechnique\n"
            "{\n"
            "    vs(150) = VSmain();\n"
            "    fs(150) = FSmain();\n"
            "};\0";

    glfxParseEffectFromMemory( effect, shader.c_str() );
    int shaderProg = glfxCompileProgram( effect, "SimpleTechnique" );
    if (shaderProg < 0)
    {
        std::string log = glfxGetEffectLog(effect);
        fprintf( stderr, "%s\n", log.c_str() );
    }

    glClearColor ( 0.0, 0.0, 1.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );

    float* vert = new float[9];

    vert[0] = 0.0; vert[1] = 0.5; vert[2] =-1.0;
    vert[3] =-1.0; vert[4] =-0.5; vert[5] =-1.0;
    vert[6] = 1.0; vert[7] =-0.5; vert[8] =-1.0;

    unsigned int m_vaoID;
    unsigned int m_vboID;

    glGenVertexArrays( 1, &m_vaoID );
    glBindVertexArray( m_vaoID );

    glGenBuffers( 1, &m_vboID );

    glBindBuffer( GL_ARRAY_BUFFER, m_vboID );
    glBufferData( GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), vert, GL_STATIC_DRAW );

    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
    glEnableVertexAttribArray( 0 );

    glEnable( GL_TEXTURE_2D );

    int loc = glGetUniformLocation( shaderProg, "gColorMap" );

    glActiveTexture( GL_TEXTURE0 );

    SDL_GL_BindTexture(texture, NULL, NULL );

    glUniform1i( loc, 0 );

    glUseProgram( shaderProg );

    glDrawArrays( GL_TRIANGLES, 0, 3 );

    glDisableVertexAttribArray( 0 );

    glBindVertexArray( 0 );

    delete[] vert;

    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    glDeleteBuffers( 1, &m_vboID );
    glDeleteVertexArrays( 1, &m_vaoID );

    SDL_GL_SwapWindow( mainwindow );
    SDL_Delay( 2000 );

    SDL_GL_DeleteContext( maincontext );
    SDL_DestroyWindow( mainwindow );
    SDL_Quit( );

    return 0;
}
like image 556
SteveDeFacto Avatar asked Jun 17 '13 20:06

SteveDeFacto


1 Answers

glUniform - Specify the value of a uniform variable for the current program object

glUseProgram() then glUniform1i(), not the other way around.

EDIT: This is looking like a bug in SDL2. You might try the demo program I attached to the report and see if you can repro on your system.

EDIT2: Looks like Sam has a fix in already.

like image 54
genpfault Avatar answered Oct 14 '22 03:10

genpfault