I am trying to start using SDL2 (with CLion as my IDE), but I'm running into errors. I'm on Pop!_OS 19.10 (based on ubuntu)
Here are the relevant project files:
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(sdlpractice)
set(CMAKE_CXX_STANDARD 20)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
add_executable(sdlpractice main.cpp)
target_link_libraries(sdlpractice ${SDL2_LIBRARIES})
Main.cpp
#include "SDL2/SDL.h"
#include "stdio.h"
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char* args[]) {
// The window we will be rendering to
SDL_Window * ptrWindow = NULL;
// The surface contained by the window
SDL_Surface * ptrScreenSurface = NULL;
// Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
} else {
// Create window
ptrWindow = SDL_CreateWindow("SDL Practice",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (ptrWindow == nullptr) {
printf("Window creation failed: %s\n", SDL_GetError());
}
// Get window surface
ptrScreenSurface = SDL_GetWindowSurface(ptrWindow);
// Fill the surface white
SDL_FillRect(ptrScreenSurface, NULL, SDL_MapRGB(ptrScreenSurface->format, 0xFF, 0xFF, 0xFF));
// Update the surface
SDL_UpdateWindowSurface(ptrWindow);
// Wait 2 seconds
SDL_Delay(2000);
// Destroy window, quit SDL subsystems
SDL_DestroyWindow(ptrWindow);
SDL_Quit();
return 0;
}
}
I get the following error:
SDL could not initialize! SDL_Error: No available video device
I have tried setting DISPLAY=:0.0 in CLion's run configurations. Same error results. Futhermore, I ran
echo $DISPLAY
:1
and tried using :1 as well, same error persists.
Removing /usr/local/bin/sdl2-config,/usr/local/include/SDL2 and /usr/local/lib/libSDL2* (as suggested by Botje) solved the problem due to the self-built version of SDL2 missing the required video headers.
Related
I'm trying to run the executable of my application made with CLion and I get the error 0xc000007b (STATUS_INVALID_IMAGE_FORMAT).
If I launch the program from CLion the application start normally without any error, the problem occurs only if I try to launch the EXE.
I use SDL2, SDL2_image and SDL2_ttf. I always had this problem with SDL.
Project structure:
./cmake-build-debug
/SDL2.dll, SDL2_image.dll, SDL2_ttf.dll
/myProgram.exe
./include
/SDL2/
/*.a
./lib
/SDL2/
/*.h
./src
/main.cpp
main.cpp:
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow(
"GameEngine",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
0
);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
bool should_quit = false;
while (!should_quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
should_quit = true;
break;
}
break;
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
CMakeList.txt:
cmake_minimum_required(VERSION 3.21)
project(GameEngine)
set(CMAKE_CXX_STANDARD 20)
set(SDL2_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include/SDL2)
set(SDL2_LIB_DIR ${CMAKE_SOURCE_DIR}/lib/SDL2)
include_directories(${SDL2_INCLUDE_DIR})
link_directories(${SDL2_LIB_DIR})
file(GLOB_RECURSE SOURCES
${PROJECT_SOURCE_DIR}/src/*.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} mingw32 SDL2main SDL2 SDL2_image SDL2_ttf)
While trying to load a .png file with IMG_LoadTexture(renderer, "idle.png")
SDL_GetError() says: "Couldn't open idle.png"
There are no compiler errors, just a black window appears.
This is my main.cpp
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
int main(int argc, char** argv) {
SDL_Event event;
SDL_Renderer *renderer = NULL;
SDL_Texture *texture = NULL;
SDL_Window *window = NULL;
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(
800, 600,
0, &window, &renderer
);
IMG_Init(IMG_INIT_PNG);
texture = IMG_LoadTexture(renderer, "idle.png");
std::cout << SDL_GetError();
while (1) {
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}
SDL_DestroyTexture(texture);
IMG_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
But I guess the problem is the way I link the library. I installed sdl2, sdl2_image and libpng.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(untitled)
set(CMAKE_CXX_STANDARD 17)
add_executable(untitled main.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(untitled ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})
You are loading the image from the current working directory (CWD) of your application. That is not necessarily the same directory as your executable is in (it depends on how it is launched), which you seem to assume.
3 easy ways to fix:
change the cwd at runtime to where the file is and load as you do now.
provide an absolute path to the file when loading, so cwd is irrelevant.
obtain the path to the executable at runtime and then construct a path to the file relative to where the executable is. (best option in my opinion since it's robust against moving your project around/installing to a different location).
I have a Parent CMake project and a Child CMake project, inside the parent cmake project I can call any OpenGL function and it works perfectly fine, but inside the child project I can't call any OpenGL functions directly, only through the parent projects functions will it work.
Parent Project:
cmake_minimum_required (VERSION 3.8)
project(LumiumEngine)
set(CMAKE_DEBUG_POSTFIX "-d")
set(LUMI_DIR "LumiumEngine")
# SDL2
find_package(SDL2 CONFIG REQUIRED)
add_library(${PROJECT_NAME} SHARED "${LUMI_DIR}/System/Window.hpp" "${LUMI_DIR}/System/Window.cpp")
# glad
set(GLAD_DIR "${CMAKE_HOME_DIRECTORY}/external/glad")
add_library("glad" "${GLAD_DIR}/src/glad.c")
target_include_directories("glad" PUBLIC "${GLAD_DIR}/include")
target_include_directories(${PROJECT_NAME} PUBLIC "${SDL2_INCLUDE_DIRS}" "${GLAD_DIR}/include")
target_link_libraries(${PROJECT_NAME} PUBLIC SDL2::SDL2 SDL2::SDL2main "glad" "${CMAKE_DL_LIBS}")
set_target_properties(${PROJECT_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/bin"
)
install(DIRECTORY bin
DESTINATION "${CMAKE_HOME_DIRECTORY}/Lumin"
FILES_MATCHING
PATTERN "*.dll"
PATTERN "*.ilk" EXCLUDE
PATTERN "*.pdb" EXCLUDE
)
Child Project:
cmake_minimum_required (VERSION 3.8)
project(Lumin)
set(CMAKE_DEBUG_POSTFIX "-d")
# find OpenGL
find_package(OpenGL REQUIRED)
add_executable(${PROJECT_NAME} "main.cpp" "${CMAKE_HOME_DIRECTORY}/external/glad/src/glad.c")
target_link_libraries(${PROJECT_NAME} PUBLIC "${OPENGL_LIBRARIES}" LumiumEngine)
set_target_properties(${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/bin"
)
The child project is dependent on parent project, (in the parent-parent directory i just add both of these project as sub directories and add_dependency(Child Parent), the proper .dlls and .libs should be loaded in, from my understanding I load SDL2, SDL2main, glad in the parent project and then load in OpenGL + all the libraries from Parent since they were added with the PUBLIC tag
The code is not the issue, since I created a project with two sub projects in Visual Studio with the same code which worked. Is there a library that i'm missing? It also might be an issue with compiling the OpenGL Loader `glad'.
I think the main issue that is confusing me is why do OpenGL functions hidden by an abstraction layer in my Parent project work fine but when i call OpenGL functions in my Child project I get an "Exception Thrown at 0x00010..." at the OpenGL call. Thanks for any help or guidance.
Edit: Adding a code example:
This is my Window.cpp from the Parent project LumiumEngine
#include "Window.hpp"
#include <glad/glad.h>
lumi::Window::Window()
{
m_shouldClose = true;
}
lumi::Window::~Window()
{
SDL_Quit();
}
bool lumi::Window::createWindow(std::string title, int xPos, int yPos, int width, int height, unsigned int flags)
{
// Set SDL as ready and init SDL
SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init Error", "Could not init SDL2", NULL);
SDL_Quit();
return false;
}
SDL_GL_LoadLibrary(NULL); // Default OpenGL is fine.
// Request an OpenGL 4.5 context (should be core)
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
// Also request a depth buffer
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// create the window
m_pWindow = SDL_CreateWindow(title.c_str(), xPos, yPos, width, height, flags);
if (m_pWindow == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Window Error", "Could not create a window", NULL);
SDL_Quit();
return false;
}
// create the openGL context
m_glContext = SDL_GL_CreateContext(m_pWindow);
if (m_glContext == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Window Error", "Could not create an openGL context with version 4.5", NULL);
SDL_Quit();
return false;
}
printf("OpenGL loaded\n");
gladLoadGLLoader(SDL_GL_GetProcAddress);
printf("Vendor: %s\n", glGetString(GL_VENDOR));
printf("Renderer: %s\n", glGetString(GL_RENDERER));
printf("Version: %s\n", glGetString(GL_VERSION));
m_shouldClose = false;
glViewport(0, 0, width, height);
glClearColor(.2f, .4f, .6f, 1.0f);
return true;
}
bool lumi::Window::isOpen()
{
return !m_shouldClose;
}
Child Project main.cpp
#include <LumiumEngine/System/Window.hpp>
#include <glad/glad.h>
int main(int argc, char **argv)
{
lumi::Window window;
if (window.createWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL))
{
glClearColor(0.2f, 0.4f, 0.6f, 1.0f); // exception occurs here, as you can see it's after i create a valid OpenGL context
while (window.isOpen())
{
//window.display();
}
}
return 1;
}
Notice how i call the same exact OpenGL function glClearColor() inside my createWindow function and it runs perfectly fine. I can verify that it works by calling window.display which calls glClear(GL_COLOR_BUFFER_BIT); then SDL_GL_SwapBuffers()
Side note: I tried just getting rid of the child project and making the Parent project into a executable instead of a library and it works fine, but i really would like to be able to make LumiumEngine a library so i can call it from multiple projects in the future. I'm completely stumped at the moment.
Blahhh!
So for some reason you have to manually load OpenGL through glad again in the Child Project, even though it has already been called in the parent project and we have verified that we had a valid OpenGL Context. The simple fix for this was to add a:
gladLoadGLLoader(SDL_GL_GetProcAddress)
call after the SDL window was created:
#include <LumiumEngine/System/Window.hpp>
#include <glad/glad.h>
int main(int argc, char **argv)
{
lumi::Window window;
if (window.createWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL))
{
gladLoadGLLoader(SDL_GL_GetProcAddress);
glClearColor(0.2f, 0.4f, 0.6f, 1.0f); // THIS WORKS NOW!!
while (window.isOpen())
{
window.display();
}
}
return 1;
}
Such a simple fix for a simple problem that was giving me a major headache.
I am currently attempting to write a very simple 2d game engine using SDL in order to help myself get more comfortable with coding. Unfortunately, I made the mistake of starting with a single source file, and now that my code is getting bigger, I am trying to split the existing code (which works fine before the split) into multiple header and source files. The first major issue I've encountered is that when I try to define SCREEN_HEIGHT, SCREEN_WIDTH, Window, and Renderer in init.cpp after declaring them in init.h, I get error: 'blank' does not name a type (blank being Window, Renderer, etc.). I am also trying to make them global, which may be part of the issue. Included below is the relevant code (I took out all the stuff I think is irrelevant in this case). I suspect I'm just missing something really simple here, but I've been unable to find an existing answer online like I have with my previous problems.
main.cpp
#include "globals.h"
#include "texture.h"
....
globals.h
#ifndef GLOBALS
#define GLOBALS
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
#endif //GLOBALS
texture.h
#ifndef TEXTURE
#define TEXTURE
#include "globals.h"
#include "init.h"
....
#endif // TEXTURE
texture.cpp
#include "texture.h"
....
init.h
#ifndef INIT
#define INIT
#include "globals.h"
//screen dimensions
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
//initiates SDL and creates a window and renderer
bool init();
//the created window
SDL_Window* Window;
//the renderer that will be used
SDL_Renderer* Renderer;
#endif // INIT
init.cpp
#include "init.h"
SCREEN_WIDTH = 640;
SCREEN_HEIGHT = 480;
Window = NULL;
Renderer = NULL;
bool init()
{
bool success = true;
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
{
printf( "SDL was unable to initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf( "Linear texture filtering not enabled!");
}
else
{
Window = SDL_CreateWindow( "Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( Window == NULL)
{
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
Renderer = SDL_CreateRenderer( Window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if( Renderer == NULL)
{
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
SDL_SetRenderDrawColor( Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int PNGImage = IMG_INIT_PNG;
if( !(IMG_Init( PNGImage) & PNGImage))
{
printf( "Image loading not enabled! SDL_Image Error: %s\n", IMG_GetError());
success = false;
}
if( TTF_Init() == -1)
{
printf( "True type fonts not enabled! SDL_TTF Error: %s\n", TTF_GetError());
success = false;
}
}
}
}
}
return success;
}
I get the error in init.cpp at the top of the code before bool init()
Renderer = NULL; is an assignment statement, which you cannot have in global scope. You can only have declarations in global scope. Since you have already declared Renderer in your header file, you don't need to redeclare it either. Just set it to null within one of your initialization functions (e.g. your current init() function).
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;
}
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.
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.