2
votes

I couldn't find a question about similar issue so after being a long time Stackoverflow lurker I decided to finally ask a question. The issue I faced with SDL + OpenGL on Ubuntu 14.04 LTS is that sometimes when I draw texture and text on screen the coordinates are bit off. I have a picture here showing how the correct drawing looks like (the program opens full screen but I have clipped the image)

And below is how the drawing of the texture and texts are sometimes shown

As you can see the fps text is not shown here and also the mousecoords and the texture are also too high up. When I move my mouse to the top left corner in any case the coordinates shown are 0,0 as they should be.

The code what I have used for drawing this is below

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_opengl.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <sstream>
#include <iostream>

#define WINDOW_WIDTH 1366
#define WINDOW_HEIGHT 768


void drawText(const float x, const float y, const std::string text){

    int i;

    glColor4f(1.0, 1.0, 1.0, 1.0);
    glRasterPos2f(x,y);
    glDisable(GL_TEXTURE);
    glDisable(GL_TEXTURE_2D);

    for(i=0; i<text.length(); ++i){
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, (int)text.at(i));
    }

    glEnable(GL_TEXTURE_2D);
    glEnable(GL_TEXTURE);

}

int main(int argc, char* argv[]){

    SDL_Window* window = NULL;
    SDL_GLContext context;
    SDL_Surface* image = NULL;
    SDL_Event event;

    GLuint        texture;
    const Uint8  *keyState;
    Uint32        mouseState;

    bool               run        = true;
    unsigned long int  frameCount = 0;
    unsigned long int  lastTicks  = 0;
    unsigned short int fps        = 0;
    int                mouseX     = 0;
    int                mouseY     = 0;

    std::stringstream buffer;
    std::stringstream mouseCoords;

    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
        printf("SDL_Error 1: %s\n", SDL_GetError());
        exit(1);
    }

    glutInit(&argc, NULL);

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);

    if (window == NULL) {
        printf("SDL_Error 2: %s\n", SDL_GetError());
        exit(1);
    }

    image = SDL_LoadBMP("resources/images/test.bmp");
    context = SDL_GL_CreateContext(window);

    gluOrtho2D(0.0f, (float)WINDOW_WIDTH, (float)WINDOW_HEIGHT, 0.0f);

    glEnable(GL_TEXTURE_2D);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, image->format->BytesPerPixel, image->w, image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    while(run){

        glClear(GL_COLOR_BUFFER_BIT);

        glBindTexture(GL_TEXTURE_2D, texture);
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f);
            glVertex2f(10.0f, 50.0f);
            glTexCoord2f(1.0f, 0.0f);
            glVertex2f(74.0f, 50.0f);
            glTexCoord2f(1.0f, 1.0f);
            glVertex2f(74.0f, 114.0);
            glTexCoord2f(0.0f, 1.0f);
            glVertex2f(10.0f, 114.0f);
        glEnd();

        keyState   = SDL_GetKeyboardState(NULL);
        mouseState = SDL_GetMouseState(&mouseX, &mouseY);

        while(SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_QUIT:
                    run = false;
                break;
            }
        }

        if(keyState[SDL_SCANCODE_ESCAPE]){
            run = false;
        }

        mouseCoords << "mouseCoords=";
        mouseCoords << mouseX;
        mouseCoords << ",";
        mouseCoords << mouseY;

        ++frameCount;

        if(SDL_GetTicks()-lastTicks >= 1000){
            fps        = frameCount;
            frameCount = 0;
            lastTicks  = SDL_GetTicks();
        }

        buffer << "fps=";
        buffer << fps;
        drawText(10, 20, buffer.str());
        drawText(10, 40, mouseCoords.str());
        mouseCoords.str("");
        buffer.str("");

        SDL_GL_SwapWindow(window);
    }

    glDeleteTextures(1, &texture);  
    SDL_FreeSurface(image);
    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
1
Well, glRasterPos will use the transformation matrices. However, You only set the matrices once during init, so there is no real reason for the behaviour you are reporting in that source code. How is this shifting triggered? - derhass
This drawing mishap happens randomly after executing the program. Once the mishap happens the program does not show the fps printing at all and the mousecoords text and the texture are too high up. Usually exiting and running the program again the drawing is fine. - sjn

1 Answers

2
votes

It seems that by adding the flag SDL_WINDOW_BORDERLESS to the SDL_CreateWindow() function call the issue disappears.

So by modifying the line

window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);

to this format

window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL);

this issue can be fixed.