2
votes

The program following, is one that creates a window which does nothing except close when you press esc. When I compile it with cygwin, there are no errors. The GLEW I use is from Cygwin Ports, and the SDL2 is version 2.0.3, from their website's SDL2-devel-2.0.3-mingw.tar.gz download. I have SDL2.dll in the directory of the compiled executable.

Links with: -lSDL2 -lSDL2main -lGLEW -lGLU -lGL -lSDL2 -lSDL2main -lGLEW -lGLU -lGL, twice to ensure everything is linked.

Also compiled with: -std=c++11

On my computer, the following program prints out:

OpenGL Vendor: (null)
OpenGL Renderer: (null)
OpenGL Shading Language Version: (null)
OpenGL Extensions: (null)
Error initializing GLEW! Missing GL version

The program appears to work otherwise. The main problem is that if I try to call, for example glGenVertexArrays, the program will crash with STATUS_ACCESS_VIOLATION. (See the crashing code here. I think this has something to do with GLEW's error Missing GL version.

#include <cstdio>

#include <chrono>
#include <thread>

#include <SDL2/SDL.h>

#include <GL/glew.h>

#include <SDL2/SDL_opengl.h>

#include <GL/glu.h>

const int width = 1000;
const int height = 500;
bool Running = true;

#undef main
int main (int argc, char *argv[]) {
    FILE* cdebug = fopen("cdebug.txt", "w");

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(cdebug, "SDL could not initialize! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }

    #define setAttr(attr, value) \
        if (SDL_GL_SetAttribute(attr, value) < 0) { \
            fprintf(cdebug, "SDL failed to set %s to %s, SDL Error: %s\n", #attr, #value, SDL_GetError()); fflush(cdebug);\
        }
    setAttr(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    setAttr(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    setAttr(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    setAttr(SDL_GL_RED_SIZE, 8);
    setAttr(SDL_GL_GREEN_SIZE, 8);
    setAttr(SDL_GL_BLUE_SIZE, 8);
    setAttr(SDL_GL_DEPTH_SIZE, 24);
    setAttr(SDL_GL_DOUBLEBUFFER, 1);
    #undef setAttr
    /*
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    */
    SDL_Window *window = SDL_CreateWindow(
            "test",
            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
            640, 480,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
    );
    if (window == NULL) {
        fprintf(cdebug, "Window could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }

    SDL_GLContext GLContext = SDL_GL_CreateContext(window);
    if (GLContext == NULL) {
        fprintf(cdebug, "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }
    if (SDL_GL_MakeCurrent(window, GLContext) < 0) {
        fprintf(cdebug, "OpenGL context could not be made current! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }

    fprintf(cdebug, "OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
    fprintf(cdebug, "OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
    fprintf(cdebug, "OpenGL Shading Language Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
    fprintf(cdebug, "OpenGL Extensions: %s\n", glGetString(GL_EXTENSIONS));
    fflush(cdebug);

    glewExperimental = GL_TRUE;
    {
        GLenum glewError = glewInit();
        if (glewError != GLEW_OK) {
            fprintf(cdebug, "Error initializing GLEW! %s\n", glewGetErrorString(glewError)); fflush(cdebug);
        }
    }

    SDL_Event event;
    while (Running) {
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_KEYUP: {
                    switch (event.key.keysym.scancode) {
                        case SDL_SCANCODE_ESCAPE:
                            Running = false;
                            break;
                    }
                    break;
                }

            }
        }

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

        SDL_GL_SwapWindow(window);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }

    SDL_GL_DeleteContext(GLContext);

    SDL_DestroyWindow(window);
    window = NULL;

    SDL_Quit();

    return 0;
}
2
The only scenario where glGetString(GL_VERSION) might return NULL is the case where you don't have a valid GL context at the time of calling. I don;t know how this could happen without your other code printing some error message before that. But I still suggest as a test to comment out the context version and profile attributes and to check if that makes any difference.derhass
@derhass commenting them out do not seem to make a difference. :(Winestone
Wait a minute. YOu said you are using cygwin? You certainly shouldn't mix cygwin and mingw.derhass
@derhass so I should recompile SDL2? Using mingw's SDL2 seemed to work for all other SDL projects I have done (2D games).Winestone

2 Answers

0
votes

You are mixing cygwin and mingw in ways in which you shouldn't.

If you use cygwin's toolchain and -lGL and so on, you link against cygwin's OpenGL - which is not the native OpenGL lib on windows, but the one provided by cygwin's X server, implementing the GLX protocol.

The mingw version of SDL will use the native GL lib (opengl32.dll) on windows, using the wgl API. So SDL might even create a context for you, but the GL functions your programm are calling belong to a completely different GL implementation - for which your program never created a GL context.

The solution is to stick with one or the other: Completely use cygwin, and a cygwin version of SDL, and a cygwin X server. However, that is not the path I would recommend. I don't know if that would even get you some HW acceleration at all.

The more useful solution would be to not use cygwin, but mingw, for the whole project, with a mingw version of GLEW. That will result in a completely native windows binrary which will use the native OpenGL library with all features provided by the driver and not require cygwin's dlls and especially not cygwin's X server.

0
votes

I managed to get things working in a weird way.

I am using a self compiled version of SDL2 but the SDL2-devel-2.0.3-mingw.tar.gz provided by the SDL website seems to work as well and using a combination of them (such as mingw version's libs and self-compiled .dll) seem to work as well.

For GLEW, I am using my own compiled version. To compile this, I used their website's source glew-1.11.0.zip and extracted this. Then I edited glew-1.11.0/Makefile and edited line 24 to SYSTEM = cygming. Then in glew-1.11.0/config/Makefile.cygming on line's 7 and 8, I removed the -mno-cygwin flag (so the line's are CC := gcc and LD := gcc) and added -D_WIN32 to line 10 (so the line becomes CFLAGS.SO = -DGLEW_BUILD -D_WIN32). Then in glew-1.11.0, I ran make all and let it compile. After that, I copied glew-1.11.0/include/GL to my includes directory. Next, I copied glew-1.11.0/lib/libglew32.dll.a to my libs folder. I also copied glew-1.11.0/lib/glew32.dll to my .exe's folder. Then to get it to not produce a linker error, I had to place a #define _WIN32 before my #include <GL/glew.h>.

To link everything, I managed to compile it with a minimum of -lSDL2 -lSDL2main -lglew32.dll -lopengl32.