Проблема с запуском OpenGL в Windows / MinGW - PullRequest
0 голосов
/ 17 октября 2018

Ранее я работал с OpenGL 3.3 в Ubuntu 16.04, используя glew и glfw (тоже glm).С тех пор мне пришлось начать использовать машину с Windows 10, и у меня возникли некоторые проблемы с запуском моих программ.Я установил MinGW (64 бит), потому что я слышал, что это лучший способ запуска, но каждый раз, когда я запускаю свою программу, я не получаю ошибок (время компиляции и выполнения), но моя программа генерирует окно только с цветом bg, который яустановить и больше ничего.Кажется, он застревает, когда я создаю структуру / объект GLFWwindow (Printfs / couts после этого не печатается).У меня есть функция обратного вызова, которая закрывает окно, когда я нажимаю ESC, который работает.Когда окно закрывает выходные сообщения после этого создания структуры / объекта, все триггеры (включая выходные данные загрузки шейдера, которые объяснили бы отсутствие polys).Я думаю, что проблема в моем make-файле, возможно, с glfw, но я не знаю, что.

GL_LIBS = `pkg-config --static --libs glfw3` -lopengl32 -lglfw3 -lglew32 -        
std=gnu++11
EXT =
CPPFLAGS = `pkg-config --cflags glfw3` -std=gnu++11

CC = g++
EXE = my_program
SHADER_PATH = external_files/Shader.cpp

CPPFILES = $(wildcard *.cpp)
OBJS = $(CPPFILES:%.cpp=%.o)
OBJS += Shader.o

all: $(EXE)

$(EXE): $(OBJS) $(SHADER)
    $(CC) -o $(EXE) $(OBJS) $(GL_LIBS)

Shader.o:
    $(CC) $(CPPFLAGS) -c $(SHADER_PATH)

%.o: %.cpp
    $(CC) $(CPPFLAGS) -c $<

Я пытался следовать этому ответу, но он не может обнаружить glfw.dll, и я незнать, правильно ли я делаю: Настройка GLFW с MinGW

Если это имеет значение, это мои включения для glew и glfw: #include <GL/glew.h> #include <GLFW/glfw3.h>

Если есть более простой вариант (кроме двойной загрузки, это мое последнее средство), я хочу попробовать это вместо этого.

Редактировать Вот функция main () моего основного файла.Я удалил некоторые не очень важные функции, чтобы уменьшить стену текста:

#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>    // std::all_of

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "external_files/Shader.hpp"
#include "myModels.hpp"
#include "collision.hpp"

#define STB_IMAGE_IMPLEMENTATION
#include "external_files/stb_image.h"

#define TINYOBJLOADER_IMPLEMENTATION
#include "external_files/tiny_obj_loader.h"

//Array to store program IDs
unsigned int ProgramIDs[2];

//Skybox stuff
unsigned int skyTexHandle;

// Maze and player variables
int** maze;
int mazeSize;
static float exitSpin = 0.0f;

float playerXPos;
float playerYPos;
float playerZPos;
static float playerVerticalRot = 0.0f;
static float playerHorizontalRot = 0.0f;
static float playerRunSpeed = 0.045f;

bool heldButtons[5];
bool controllerPressButtons[2];
bool inputMode = true;  //true = controller, false = keyboard/mouse
int joystickPresent;
bool firing = false;    //Is true when doing the recoil animation for the mega buster
float fireStart = 0.0f; //When the shot was fired

int count;
const float* axes;
const unsigned char* buttons;

//The myModels object
myModels my_models;

//.obj model vectors and handles
std::vector<tinyobj::shape_t> shapesToiletp0;
std::vector<tinyobj::material_t> materialsToiletp0;
std::vector<tinyobj::shape_t> shapesToiletp1;
std::vector<tinyobj::material_t> materialsToiletp1;
std::vector<tinyobj::shape_t> shapesToiletp2;
std::vector<tinyobj::material_t> materialsToiletp2;

std::vector<tinyobj::shape_t> shapesMegaBuster;
std::vector<tinyobj::material_t> materialsMegaBuster;
std::vector<tinyobj::shape_t> shapesSpaceCraft;
std::vector<tinyobj::material_t> materialsSpaceCraft;

unsigned int toilet0VaoHandle;
unsigned int toilet1VaoHandle;
unsigned int toilet2VaoHandle;
unsigned int megaBusterVaoHandle;
unsigned int spaceCraftVaoHandle;

//Collision boxes
std::vector<float> boxes;

static double FOV = 1.0;
static int winX = 640;  //Width
static int winY = 480;  //Height

#define NUM_TEXTURES 10 //Update this when adding new models
GLuint TexID[NUM_TEXTURES];

int createObjVAO(std::vector<float> vertex_positions, std::vector<float> vertex_normals,
            std::vector<float> vertex_texture_coordinates, std::vector<unsigned int> indexed_triangles, unsigned int &handle){

    // The usual code to send data to GPU and link it to shader variables.    
    glGenVertexArrays(1, &handle);
    glBindVertexArray(handle);

    unsigned int buffer[4];
    glGenBuffers(4, buffer);

    // Set vertex attribute
    glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertex_positions.size(), &vertex_positions[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Normals (This block MUST be done before the texture block)
    glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertex_normals.size(), &vertex_normals[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Texture attributes
    glBindBuffer(GL_ARRAY_BUFFER, buffer[2]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertex_texture_coordinates.size(), &vertex_texture_coordinates[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);

    // Array of vertex indices
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[3]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexed_triangles.size(), &indexed_triangles[0], GL_STATIC_DRAW);

    // Un-bind
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    return 0;
}

// Load the 6 skymap textures for the cube map and set parameters
void createSkyMap(){
    glGenTextures(1, &skyTexHandle);
    glActiveTexture(GL_TEXTURE0);

    int width, height, nrChannels;

    glBindTexture(GL_TEXTURE_CUBE_MAP, skyTexHandle);

    std::vector<std::string> faces;

    faces.push_back("external_files/skybox/totality_rt.png");
    faces.push_back("external_files/skybox/totality_lf.png");
    faces.push_back("external_files/skybox/totality_up.png");
    faces.push_back("external_files/skybox/totality_dn.png");
    faces.push_back("external_files/skybox/totality_bk.png");
    faces.push_back("external_files/skybox/totality_ft.png");

    for(unsigned int i = 0; i < faces.size(); i++){
        unsigned char *data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
        if(data){
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
            stbi_image_free(data);
        }
        else{
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
            stbi_image_free(data);
        }
    }

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    return;
}

// Load an image from file as texture "ID"
int loadTexture(std::string fileName, int ID){
    glActiveTexture(GL_TEXTURE0);

    int x, y, n;
    stbi_set_flip_vertically_on_load(true);
    unsigned char *data = stbi_load(fileName.c_str(), &x, &y, &n, 0);
    if(!data){
        printf("Texture not loaded\n");
        return 1;
    }

    glBindTexture(GL_TEXTURE_2D, TexID[ID]);
    if(n == 3){
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    }
    else if(n == 4){    //For pictures with an alpha channel
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    }
    else {
        printf("Channels: %d\n", n);
        fprintf(stderr, "Image pixels are not RGB. Texture may not load correctly.\n");
    }
    stbi_image_free(data);

    glGenerateMipmap(GL_TEXTURE_2D);

    return 0;
}

//Load in the obj models
void loadObjModels(){
    std::string toiletp0 = "external_files/objModels/toilet/Toilet.obj";
    std::string toiletp1 = "external_files/objModels/toilet/ToiletLid1.obj";
    std::string toiletp2 = "external_files/objModels/toilet/ToiletLid2.obj";
    std::string megaBuster = "external_files/objModels/megaBuster/blaster.obj";
    std::string spaceCraft = "external_files/objModels/spaceCraft/Craft2.obj";

    std::string toiletBasePath = "external_files/objModels/toilet/";
    std::string megaBusterBasePath = "external_files/objModels/megaBuster/";
    std::string spaceCraftBasePath = "external_files/objModels/spaceCraft/";

    std::string loadErr;
    if(!LoadObj(shapesToiletp0, materialsToiletp0, loadErr, toiletp0.c_str(), toiletBasePath.c_str(), true)){
        printf("Failed to load first toilet obj file\n");
        exit(1);
    }
    if(!loadErr.empty()){
        std::cerr << loadErr << std::endl;
        loadErr = "";
    }
    if(!LoadObj(shapesToiletp1, materialsToiletp1, loadErr, toiletp1.c_str(), toiletBasePath.c_str(), true)){
        printf("Failed to load second toilet obj file\n");
        exit(1);
    }
    if(!loadErr.empty()){
        std::cerr << loadErr << std::endl;
        loadErr = "";
    }
    if(!LoadObj(shapesToiletp2, materialsToiletp2, loadErr, toiletp2.c_str(), toiletBasePath.c_str(), true)){
        printf("Failed to load third toilet obj file\n");
        exit(1);
    }
    if(!loadErr.empty()){
        std::cerr << loadErr << std::endl;
        loadErr = "";
    }
    if(!LoadObj(shapesMegaBuster, materialsMegaBuster, loadErr, megaBuster.c_str(), megaBusterBasePath.c_str(), true)){
        printf("Failed to load the megaBuster obj file\n");
        exit(1);
    }
    if(!loadErr.empty()){
        std::cerr << loadErr << std::endl;
        loadErr = "";
    }
    if(!LoadObj(shapesSpaceCraft, materialsSpaceCraft, loadErr, spaceCraft.c_str(), spaceCraftBasePath.c_str(), true)){
        printf("Failed to load the space craft obj file\n");
        exit(1);
    }
    if(!loadErr.empty()){
        std::cerr << loadErr << std::endl;
        loadErr = "";
    }

    //In our case each model there is only 1 shape and 1 material, so we can reduce the amount of code with this assumption
    createObjVAO(shapesToiletp0[0].mesh.positions, shapesToiletp0[0].mesh.normals, shapesToiletp0[0].mesh.texcoords, shapesToiletp0[0].mesh.indices, toilet0VaoHandle);
    createObjVAO(shapesToiletp1[0].mesh.positions, shapesToiletp1[0].mesh.normals, shapesToiletp1[0].mesh.texcoords, shapesToiletp1[0].mesh.indices, toilet1VaoHandle);
    createObjVAO(shapesToiletp2[0].mesh.positions, shapesToiletp2[0].mesh.normals, shapesToiletp2[0].mesh.texcoords, shapesToiletp2[0].mesh.indices, toilet2VaoHandle);
    createObjVAO(shapesMegaBuster[0].mesh.positions, shapesMegaBuster[0].mesh.normals, shapesMegaBuster[0].mesh.texcoords, shapesMegaBuster[0].mesh.indices, megaBusterVaoHandle);
    createObjVAO(shapesSpaceCraft[0].mesh.positions, shapesSpaceCraft[0].mesh.normals, shapesSpaceCraft[0].mesh.texcoords, shapesSpaceCraft[0].mesh.indices, spaceCraftVaoHandle);

    //Our transparent spinning cube defaults to the last texture for some reason, so we must set these all before it
    int retSum = 0;
    retSum += loadTexture(toiletBasePath + materialsToiletp0[0].diffuse_texname, 5);
    retSum += loadTexture(toiletBasePath + materialsToiletp1[0].diffuse_texname, 6);
    retSum += loadTexture(toiletBasePath + materialsToiletp2[0].diffuse_texname, 7);
    retSum += loadTexture(megaBusterBasePath + materialsMegaBuster[0].diffuse_texname, 8);
    retSum += loadTexture(spaceCraftBasePath + materialsSpaceCraft[0].diffuse_texname, 9);
    if(retSum != 0){
        printf("RetSum isn't zero: %d\n", retSum);
        exit(1);
    }
}

int createSlot(){
    glActiveTexture(GL_TEXTURE0);  //Texture slot zero

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    glGenTextures(NUM_TEXTURES, TexID); //Basically telling it we'll use 10 textures and our array of unsigned ints (The textures)

    return 0;
}

int setProjection(){
    // Perspective projection matrix
    glm::mat4 projection;
    projection = glm::perspective(FOV, double(winX) / double(winY), 0.001, 30.0);

    // Load it to the shader program
    int projHandleMain = glGetUniformLocation(ProgramIDs[0], "projection_matrix");
    int projHandleSkybox = glGetUniformLocation(ProgramIDs[1], "projection_matrix");
    if(projHandleMain == -1 || projHandleSkybox == -1){
        fprintf(stderr, "Error updating proj matrix\n");
        return 1;
    }
    glUseProgram(ProgramIDs[0]);
    glUniformMatrix4fv(projHandleMain, 1, false, glm::value_ptr(projection));
    glUseProgram(ProgramIDs[1]);
    glUniformMatrix4fv(projHandleSkybox, 1, false, glm::value_ptr(projection));

    return 0;
}

//Sets the resolution to either the size of the primary screen or whats described in the config file
void setResolution(){
    const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    std::ifstream config;
    config.open("config");
    if(!config){
        printf("Config file not found\n");
        winX = mode->width;
        winY = mode->height;
        config.close();
        return;
    }
    else{   //No config file, just fullscreen instead
        printf("Config file found\n");
    }
    std::string name;
    std::string value;
    while(config >> name >> value){
        if(name.compare("Width:")){
            if(!std::all_of(value.begin(), value.end(), ::isdigit)){
                winX = mode->width;
                continue;
            }
            winX = atoi(value.c_str());
            if(winX < 1){
                winX = mode->width;
            }
        }
        else if(name.compare("Height:")){
            if(!std::all_of(value.begin(), value.end(), ::isdigit)){
                winY = mode->height;
                continue;
            }
            winY = atoi(value.c_str());
            if(winY < 1){
                winY = mode->height;
            }
        }
    }
    config.close();
    return;
}

void controller_buttons(GLFWwindow* window){
    if(buttons[6] == GLFW_PRESS){   //Back is pressed
        glfwSetWindowShouldClose(window, GL_TRUE);
    }
    if(buttons[3] == GLFW_PRESS && inputMode){   //Press Y to reset
        if(!controllerPressButtons[1]){
            playerXPos = 1.0;
            playerYPos = 0.0;
            playerZPos = 1.0;
        }
        controllerPressButtons[1] = true;
    }
    else{
        controllerPressButtons[1] = false;
    }
    if(buttons[7] == GLFW_PRESS){  //Start is pressed
        if(!controllerPressButtons[0]){
            inputMode = !inputMode;
        }
        controllerPressButtons[0] = true;
    }
    else{
        controllerPressButtons[0] = false;
    }
    if(buttons[2] == GLFW_PRESS && inputMode){   //Press X to fire and do recoil animation
        if(!firing){
            firing = true;
            fireStart = glfwGetTime();
            system("aplay -q external_files/blaster.wav &");
        }
    }
}

void reshape_callback(GLFWwindow *window, int x, int y){
    winX = x;
    winY = y;

    setProjection();
    glViewport(0, 0, (GLsizei)x, (GLsizei)y); 
}

//This code seems right, but for some reason the keyboard behaves very strangely
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
    if(action == GLFW_PRESS){
        switch(key){
            case GLFW_KEY_ESCAPE:
                glfwSetWindowShouldClose(window, GL_TRUE);
                break;
            case GLFW_KEY_G:    //Press G to switch between keyboard/mouse and controller controls
                inputMode = !inputMode;
                break;
            case GLFW_KEY_Y:
                if(!inputMode || !joystickPresent){  //Press Y to reset
                    playerXPos = 1.0;
                    playerYPos = 0.0;
                    playerZPos = 1.0;
                }
                break;
            default:
                break;
        }
    }

    int state = glfwGetKey(window, GLFW_KEY_X);
    if(state == GLFW_PRESS || state == GLFW_REPEAT){    //Why is it bugged? Sometimes it holds longer and fires an extra shot. The keyboard is weird
        if((!inputMode || !joystickPresent) && !firing){  //Press X to fire and do recoil animation
            firing = true;
            fireStart = glfwGetTime();
            system("aplay -q external_files/blaster.wav &");
        }
    }

    if(action == GLFW_PRESS && key == GLFW_KEY_W){
        heldButtons[0] = true;
    }
    if(action == GLFW_PRESS && key == GLFW_KEY_A){
        heldButtons[1] = true;
    }
    if(action == GLFW_PRESS && key == GLFW_KEY_S){
        heldButtons[2] = true;
    }
    if(action == GLFW_PRESS && key == GLFW_KEY_D){  //For some reason the D key is buggy
        heldButtons[3] = true;
    }

    //And releasing keys doesn't update them all at once...
    if(action == GLFW_RELEASE && key == GLFW_KEY_W){
        heldButtons[0] = false;
    }
    if(action == GLFW_RELEASE && key == GLFW_KEY_A){
        heldButtons[1] = false;
    }
    if(action == GLFW_RELEASE && key == GLFW_KEY_S){
        heldButtons[2] = false;
    }
    if(action == GLFW_RELEASE && key == GLFW_KEY_D){
        heldButtons[3] = false;
    }
}

static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos){
    float centreX = winX/2;
    float centreY = winY/2;

    if(!joystickPresent || !inputMode){
        //Use the distance between xpos/ypos and the origin to modify the rotation

        playerVerticalRot += 0.005 * (ypos - centreY);
        playerHorizontalRot += 0.005 * (xpos - centreX);

        if(playerVerticalRot > M_PI/2){    //If beyond looking straight down, undo changes
            playerVerticalRot = M_PI/2;
        }

        if(playerVerticalRot < -M_PI/2){    //If beyond looking straight down, undo changes
            playerVerticalRot = -M_PI/2;
        }
    }

    glfwSetCursorPos(window, centreX, centreY); //Reset the cursor to the centre of the screen so we don't hit the boarders of the window
}

static void error_callback(int error, const char* description){
    fputs(description, stderr);
}

int main(int argC, char *argV[]){

    std::cout << "A bunch of printf's\n\n";

    GLFWwindow* window; //Starts to mess up after here
    std::cout << "TEster\n";
    glfwSetErrorCallback(error_callback);

    if(!glfwInit()){
        exit(1);
    }

    // Specify that we want OpenGL 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    loadMazeFile();

    joystickPresent = glfwJoystickPresent(GLFW_JOYSTICK_1); //Detects if a Joystick is plugged in (Controls change if true)

    // Create the window and OpenGL context
    setResolution();    //Set the resolution to the screen size
    window = glfwCreateWindow(winX, winY, "Megaman and the Legend of the Dark and Dank Toilet", NULL, NULL);
    if(!window){
        glfwTerminate();
        exit(1);
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    // Initialize GLEW
    glewExperimental = true; // Needed for core profile
    if(glewInit() != GLEW_OK){
        fprintf(stderr, "Failed to initialize GLEW\n");
        exit(1);
    }

    // These shaders use supplied tex coords to texture surface
    ProgramIDs[0] = LoadShaders("main_shader.vert", "main_shader.frag");
    ProgramIDs[1] = LoadShaders("skybox_shader.vert", "skybox_shader.frag");

    if(ProgramIDs[0] == 0 || ProgramIDs[1] == 0){
        fprintf(stderr, "Error loading shaders\n");        
        exit(1);
    }

    // Set up OpenGL parameters and data
    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    my_models.initSky(); //Creates the skybox mesh
    createSkyMap();
    setProjection();
    my_models.initCube(ProgramIDs[0]); //Creates the cube mesh
    my_models.initFrame(ProgramIDs[0]); //Creates the frame mesh

    // Load the 3 textures to change between
    createSlot();   //Slot created after skymap is made
    loadTexture("external_files/textures/wall.png", 0);
    loadTexture("external_files/textures/floor.png", 1);
    loadTexture("myTextures/exit.png", 2);
    loadTexture("external_files/textures/metalCreate.png", 3);
    loadTexture("myTextures/exitTrans.png", 4);

    loadObjModels();

    //Set all the held/pressed buttons to zero
    for(int i = 0; i < 2; i++){
        controllerPressButtons[i] = false;
        heldButtons[2 * i] = false;
        heldButtons[2 * i + 1] = false;
    }
    heldButtons[4] = false;

    // Define callback functions and start main loop
    glfwSetKeyCallback(window, key_callback);
    glfwSetFramebufferSizeCallback(window, reshape_callback);
    glfwSetCursorPosCallback(window, cursor_position_callback);

    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);  //This hides the mouse cursor

    //Starting coords
    playerXPos = 1;
    playerYPos = 0;
    playerZPos = 1;

    addCollisionBoxes(boxes);

    while(!glfwWindowShouldClose(window)){
        joystickPresent = glfwJoystickPresent(GLFW_JOYSTICK_1); //Detects if a Joystick is plugged in (Controls change if true)
        if(joystickPresent){
            axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count);
        }

        exitSpin = glfwGetTime();
        updateCollisionBox(9.5, 8.5, 0.5 * glm::sin(exitSpin), 0.5 * glm::sin(exitSpin) - 1.0, 2.5, 1.5, boxes, 0); //Update the moving block's collision
        move();

        if(joystickPresent){
            if(inputMode){
                controller_look();
            }
            buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count);
            controller_buttons(window);
        }

        //Render code
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        renderSpaceCraft();
        renderToilet();
        renderMaze();
        renderSkybox();

        glClear(GL_DEPTH_BUFFER_BIT);   //Need to reset the depth buffer for HUD stuff like the blaster
        renderMegaBuster();

        glBindVertexArray(0);
        glFlush();

        //Swap buffers and get inputs
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Clean up
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

Обратите внимание, что некоторое время назад я попробовал свой код в Ubuntu 18.04 и получил аналогичные результаты, поэтому я думаю, что есть проблема сlibrary.

Edit 2

Это то, что происходит, когда я запускаю make на исходном коде glew

$ make
gcc -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.dll.a    -o lib/glew32.dll tmp/mingw/default/shared/glew.o -L/mingw/lib -nostdlib -lopengl32 -lgdi32 -luser32 -lkernel32
strip -x lib/glew32.dll
sed \
    -e "s|@prefix@|/usr|g" \
    -e "s|@libdir@|/usr/lib|g" \
    -e "s|@exec_prefix@|/usr/bin|g" \
    -e "s|@includedir@|/usr/include/GL|g" \
    -e "s|@version@|2.1.0|g" \
    -e "s|@cflags@||g" \
    -e "s|@libname@|glew32|g" \
    -e "s|@requireslib@|glu|g" \
    < glew.pc.in > glew.pc
gcc -fno-builtin -O2 -Wall -W -Iinclude -fno-builtin -fno-stack-protector -o bin/glewinfo.exe tmp/mingw/default/shared/glewinfo.o -Llib  -lglew32 -L/mingw/lib -nostdlib -lopengl32 -lgdi32 -luser32 -lkernel32
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x3a): undefined reference to `fprintf'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x1a6): undefined reference to `strlen'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x1db): undefined reference to `fprintf'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x205c9): undefined reference to `sscanf'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x205ee): undefined reference to `strcmp'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x20602): undefined reference to `strcmp'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x206ff): undefined reference to `strtol'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x2071c): undefined reference to `strcmp'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x20789): undefined reference to `memset'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text+0x1f1): undefined reference to `fflush'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text.startup+0x13): undefined reference to `__main'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text.startup+0x80): undefined reference to `fopen'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text.startup+0x87): undefined reference to `__imp___acrt_iob_func'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text.startup+0xaa): undefined reference to `fprintf'
tmp/mingw/default/shared/glewinfo.o:glewinfo.c:(.text.startup+0x19f7): undefined reference to `fprintf'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:181: bin/glewinfo.exe] Error 1

Кажется, он не включает некоторые библиотеки, но в glewinfo.c, похоже, включены правильные библиотеки ... (Я обрезал вывод, чтобы он соответствовал пределу в 30000 символов)

...