将SDL2纹理绑定到GLSL着色器

6

我正在尝试将一个 sdl2 纹理绑定到 glsl 着色器上,但我不太确定该怎么做?我正在使用一个叫做 glfx 的库来处理 glsl 着色器,并且我也参与了这个库的开发。我相信其他方面都没问题,但当我调用 SDL_GL_BindTexture 时它会崩溃。有人能看出我哪里做错了吗?

#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;
}

构建一个SDL2的调试版本,并找出在SDL_GL_BindTexture()中它崩溃的位置。 - genpfault
崩溃在这里:data->glEnable(texturedata->type); 不知道为什么。 - SteveDeFacto
1个回答

2

glUniform - 为当前程序对象指定统一变量的值

先使用glUseProgram()再使用glUniform1i(),而不是反过来。

编辑:这看起来像是SDL2中的一个错误。您可以尝试我附加到报告中的演示程序,并查看您的系统是否可以重现。

EDIT2: 看起来Sam已经修复了这个问题


我在实现SDL之前测试了OpenGL部分,并且它正常工作。我无论如何试过你说的方法,但没有任何改变。 - SteveDeFacto
我真的尝试了50种不同的方法,但都没有成功。更新到最新版本的SDL2后,现在它完美地运行了!谢谢! - SteveDeFacto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接