How Best To Handle An Opengl Es / Sdl Conversion?


authoreyes

Member
Joined
Oct 2, 2007
Messages
161
Website
www.markandmarina.com
Hey all -

I'm sure by now you are sick of hearing about my situation, but it's forcing me to bother you guys for some advice. Mainly cause the chemo is really making my head cloudy/difficult to really focus, and I feel like am a complete idiot trying to do some comparisons on my own here. I throw myself at the mercy of my intellectual superiors.

Advice I am looking for....I really want to get working on releasing a beta of that side scroller game I have been working on, but it's currently using OpenGL old style immediate mode with SDL. Frankly, I am quite stupid right now, and don't have the capacity to really tear into something new if it is really complex.

What is use opengl for is this: I load images with SDL and then basically paint 32x32 quads with stretched 16 x 16 tiles for the basic tile mode engine. That's it. Would this be a pain to achieve with ES? Steep learning curve? Should I just gut the opengl stuff and go straight sdl? Sorry for being a taker and not giving too much back right now, but this really has me a bit ragged right now.

Thanks so much for all of your help.
 
Disclaimer : dont claim to be an expert in this, but this are things ive observed, but maybe im wrong.

Basically the big problem is that opengles was never really supported in SDL.
Although there is a forked SDL that does support it, but this isnt a real great solution since the pandora image doesnt have this version of the lib
The better solution will be SDL 1.3 which already has opengles support but needs control support added. Also it could require some API changes in the application. Although ive seen some hints that the old 1.2 API is supported and may wotk with opengles. I havnt used it enough to know.
The other option is to do EGL for window interface yourself.
I suppose an option as a last give up resort is to add sw rendering option to your app
 
authoreyes said:
Hey all -

I'm sure by now you are sick of hearing about my situation, but it's forcing me to bother you guys for some advice. Mainly cause the chemo is really making my head cloudy/difficult to really focus, and I feel like am a complete idiot trying to do some comparisons on my own here.
FWIW, i feel the same way during many of those late nights when i sit to do some coding on my pet projects, after a long day of tiring work, and piling sleep deprivaton. the plus side of that is that most code written under such conditions tends to be less fancy and more robust ; ) .. well, except for those rare 'WTF was i thinking? .. oh, yeah, now i remember - i wasn't' moments.

What is use opengl for is this: I load images with SDL and then basically paint 32x32 quads with stretched 16 x 16 tiles for the basic tile mode engine. That's it. Would this be a pain to achieve with ES? Steep learning curve? Should I just gut the opengl stuff and go straight sdl? Sorry for being a taker and not giving too much back right now, but this really has me a bit ragged right now.
are those tiles static, or are they dynamically updated? if the latter - how often? how many tiles do you have? what do you plan to do with those quads - keep them flat-on and axis-alined with the screen plane, or roate and move them back and forth in depth? let's first sort these things out, and then we can see how to do that in ES.
 
Last edited by a moderator:
If youre just drawing tiles with immediate mode, I assume you have some drawTile(x,y) function? In that case the actual conversion from immediate mode itself should be fairly easy(window managers and stuff not-withstanding). You basically just need to make an array of the four vertices, and the four uv's, point openGL to them, and then call glDrawArrays, and thats it. Just google Vertex Array tutorial or something like that, its actually very easy
 
In Penjin I converted my input handling stuff to use direct linux input handling and used ES 1.1 - using egl to create the window.
I still load images using SDL_image, these are then converted to textures. I don't claim to do things the best way, but the source is on google-code should it be of help to you in any capacity.

Note a lot of things going on under the hood are a bit tricky to follow at times... I try and do the complicated stuff so that anyone using Penjin doesn't have to so much... Anyway hope this helps, there is image loading too converting to Textures.

Setup screen Window: http://code.google.com/p/penjin/source/browse/trunk/GFX.cpp#189
Rendering Images: http://code.google.com/p/penjin/source/browse/trunk/Image.cpp#370
Input Handling:http://code.google.com/p/penjin/source/browse/trunk/SimpleJoy.cpp
Textures: http://code.google.com/p/penjin/source/browse/trunk/Texture.cpp
 
Pickle said:
Disclaimer : dont claim to be an expert in this, but this are things ive observed, but maybe im wrong.

Basically the big problem is that opengles was never really supported in SDL.
Although there is a forked SDL that does support it, but this isnt a real great solution since the pandora image doesnt have this version of the lib
The better solution will be SDL 1.3 which already has opengles support but needs control support added. Also it could require some API changes in the application. Although ive seen some hints that the old 1.2 API is supported and may wotk with opengles. I havnt used it enough to know.
The other option is to do EGL for window interface yourself.
I suppose an option as a last give up resort is to add sw rendering option to your app

Couldn't you compile said library and include it inside the pnd? Sure, it won't be portable, but then again, I don't see many other arm devices that will get pnd support any time soon.

Since I'm too interested in using OpenGL ES with SDL, I'd like to confirm. Are you talking about Cpasjuste's fork?
I want to rescale a pc game screen to something smaller, and I'm too green so far to do bigger steps.
 
Last edited by a moderator:
Thanks for the replies all...

1. Yes, the quads are pretty static...Basically, like billboards - they are fixed (in position, space/rotation, and quantity) and really just there to gain the open gl benefits of upstretching images right now (I seem to remember SDL didn't have an efficient way of stretching images...but again, I could be way off here)....Potentially in the future I would have tried some trickery, but right now they are just 32x32 "single sided" billboards in a grid.

2. Yes, there is a render loop that basically does a draw tile for each of the quads based off the sdl_image. What you guys are saying is a great help...Windowing/interplay/library usage seem like the biggest hurdles...

I think I will finish my PandyWordSeek game this week first...I need to learn focus :)
 
I could be missing something, but if these quads are essentially static, wouldn't it be simpler to just blit them directly to the screen and drop the OGL stuff? You could either scale them up when loading or scale the whole screen once they're all drawn.
 
SteveM said:
I could be missing something, but if these quads are essentially static, wouldn't it be simpler to just blit them directly to the screen and drop the OGL stuff? You could either scale them up when loading or scale the whole screen once they're all drawn.

Yup, that is a def possibility, and a route I most likely will take :)

I added the opengl stuff for future coolness/lighting/transforms (and as a learning experience) But if I keep things simple the way they are, I think I may just nix the opengl stuff for now...
 
Last edited by a moderator:
authoreyes said:
Yup, that is a def possibility, and a route I most likely will take :)

I added the opengl stuff for future coolness/lighting/transforms (and as a learning experience) But if I keep things simple the way they are, I think I may just nix the opengl stuff for now...
future coolness is good. i assume that includes fancy animated lead-ins/outs for the individual tiles, etc. if that's the plan, then you can start with the following minimal functionality:

create your quad mesh like this:
Code:
    struct Vertex
    {
        GLfloat pos[2];
        GLfloat txc[2];
    }
    static arr[4] =
    {
        { { -1.f, -1.f }, { 0.f, 0.f } },
        { { -1.f,  1.f }, { 0.f, 1.f } },
        { {  1.f, -1.f }, { 1.f, 0.f } },
        { {  1.f,  1.f }, { 1.f, 1.f } }
    };

    GLuint vbo;
    glGenBuffers(1, &vbo);
    
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(arr), arr, GL_STATIC_DRAW);

    { 
        const float (Vertex::* const offs)[2] = &Vertex::pos;
        glVertexAttribPointer(attr_vertex, 2, GL_FLOAT, GL_FALSE, sizeof(arr[0]), *reinterpret_cast< const GLvoid* const* >(&offs));
    }

    {   
        const float (Vertex::* const offs)[2] = &Vertex::txc;
        glVertexAttribPointer(attr_tcoord, 2, GL_FLOAT, GL_FALSE, sizeof(arr[0]), *reinterpret_cast< const GLvoid* const* >(&offs));
    }

draw each one like this:
Code:
    glUseProgram(shader_prog);

    const GLfloat origin_scale[4] = { pos_x_ndc, pos_y_ndc, scale_x_ndc, scale_y_ndc }; // where NDC spans [-1, 1] along all axes

    glUniform4fv(uni_origin_and_scale, 1, origin_scale);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tile_tex[i]); // i-th tile texture, assuming you have individual tile textures

    glUniform1i(sampler_tile, 0);

    glEnableVertexAttribArray(attr_vertex);
    glEnableVertexAttribArray(attr_tcoord);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableVertexAttribArray(attr_vertex);
    glDisableVertexAttribArray(attr_tcoord);

set up your shader program like this:
Code:
    static const GLchar* src_v =
       "uniform vec4 origin_and_scale;

        attribute vec2 at_Vertex;
        attribute vec2 at_MultiTexCoord0;

        varying vec2 tc_i;

        void main()
        {
            gl_Position = vec4(at_Vertex * vec2(origin_and_scale.zw) + vec2(origin_and_scale.xy), 0.0, 1.0);

            tc_i = at_MultiTexCoord0.xy;
        }";

    const GLint src_v_len = strlen(src_v);

    static const GLchar* src_f =
       "precision lowp float;

        uniform sampler2D tile_tex;

        varying vec2 tc_i;

        void main()
        {
            gl_FragColor = texture2D(tile_tex, tc_i);
        }";

    const GLint src_f_len = strlen(src_f);

    GLint success;

    GLuint shader_v = glCreateShader(GL_VERTEX_SHADER);

    glShaderSource(shader_v, 1, &src_v, &src_v_len);
    glCompileShader(shader_v);

    glGetShaderiv(shader_v, GL_COMPILE_STATUS, &success);
    assert(GL_TRUE == success);

    GLuint shader_f = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(shader_f, 1, &src_f, &src_f_len);
    glCompileShader(shader_f);

    glGetShaderiv(shader_f, GL_COMPILE_STATUS, &success);
    assert(GL_TRUE == success);

    shader_prog = glCreateProgram();

    glAttachShader(shader_prog, shader_v);
    glAttachShader(shader_prog, shader_f);

    glLinkProgram(shader_prog);

    glGetProgramiv(shader_prog, GL_LINK_STATUS, &success);
    assert(GL_TRUE == success);

    uni_origin_and_scale = glGetUniformLocation(shader_prog, "origin_and_scale");

    sampler_tile = glGetUniformLocation(shader_prog, "tile_tex");

    attr_vertex = glGetAttribLocation(shader_prog, "at_Vertex");
    attr_tcoord = glGetAttribLocation(shader_prog, "at_MultiTexCoord0");

you'll notice there are some variables used across two or more code snippets but never declared - those are indeed semantically the same variables. you will need to properly declare and provide them as visible to the snippets, e.g. as globals. also, setting up the texture objects is left out as an exercise.
 
Last edited by a moderator:
Ive just updated the wiki to include a way to use GLES with the standard SDL 1.2. I havent been able to test it directly on the pandora but it works with GLES emulation and i dont see any reason for it not to run correctly. You should at least be able to use SDL with very few changes (with the exception of changing your immediate mode gl calls of course).

Edit: Oops. Heres the link http://pandorawiki.org/Combining_OpenGL_ES_1.1_and_SDL_to_create_a_window_on_the_Pandora
 
Back
Top