Search code examples
copenglglsl

OpenGL/GLSL in C working on desktop PC but not on laptop


I am trying to simply render one quad currently in OpenGL with a texture of a player on it. It works perfectly on my PC, showing me the texture rendered on a quad. I have attached the texture image to this question in case you want to see (NB: it's a PNG). On my laptop however, it shows me a black screen. I know it is reading every single as black because I did a quick GLSL debug: if (texture(u_Texture, Texcoord).xyz == vec3(.0f, .0f, .0f)) v_Texcoord = vec4(1.0f, 1.0f, 1.0f, 1.0f); and it output a purely white quad, indicating to me that the debug code thinks every pixel is black. I loosely followed The Cherno's tutorial for the GLSL and OpenGL by the way. I changed the hertz and resolution of my PC screen to see if that was the problem, it wasn't. PS: the image file is found and the image is loaded properly on both my PC and laptop. If it wasn't, since the image is stored in the project path, it wouldn't work on my PC either.

Here are some assorted code snippets of my program (written in C): player initialization:

void PlayerInit() {
    playerOrigScale.x /= (float)mode->width / 1000.0f;
    playerOrigScale.y /= (float)mode->height / 1000.0f;
    {
        float playerVerticiesInit[origPlrVertLen] = {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            1.0f, 1.0f,
            -1.0f, 1.0f,
        };
        float texCoordInit[8] = {
            .0f, .0f,
             1.0f, .0f,
            1.0f, 1.0f,
             .0f, 1.0f,
        };
        int i;
        int texCoordLen = lengthOf(texCoordInit);
        for (i = 0; i < texCoordLen; i++) {
            playerVerticies[i + ((i - i / 2) + 1 - (i % 2)) * 2] = texCoordInit[i];
        }
        for (i = 0; i < origPlrVertLen; i++) {
            origPlrPos[i] = playerVerticiesInit[i];
            playerVerticies[i + (i - (i % 2))] = origPlrPos[i] * (i % 2 == 0 ? playerOrigScale.x : playerOrigScale.y);
        }
    }
    verticiesLen = malloc(sizeof(byte));
    *verticiesLen = lengthOf(playerVerticies);
    unsigned int indicies[] = {
        0, 1, 2,
        2, 3, 0
    };
    unsigned int vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    printf("%s\n", glGetString(GL_VERSION));
    unsigned int vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(playerVerticies), playerVerticies, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    int* texAttrib = malloc(sizeof(int));
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (const void*)0);
    unsigned int ibo;
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_DYNAMIC_DRAW);
    ShaderProgramSource shaderSrc;
    {
        char* filepath = "Basic.shader";
        shaderSrc = ParseShader(filepath);
    }
    printf("vertex:\n%s\n", shaderSrc.vertexSource);
    printf("framgent:\n%s\n", shaderSrc.fragmentSource);
    shader = CreateShader(shaderSrc.vertexSource, shaderSrc.fragmentSource);
    glUseProgram(shader);
    glUniform4f(glGetUniformLocation(shader, "u_Color"), .1f, .6f, .9f, 1.0f);
    glUniform1i(glGetUniformLocation(shader, "u_Texture"), 0);
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    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);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glGenerateMipmap(GL_TEXTURE_2D);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, playerAnimator->frames[0][6]);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2));
    shouldDraw = true;
}

main function snippet:

{
    stbi_set_flip_vertically_on_load(1);
    playerAnimator = malloc(sizeof(Animator));
    playerAnimator->frames = malloc(sizeof(unsigned char*) * 1);
    playerAnimator->animFrameNo[idle] = 7;
    *playerAnimator->frames = malloc(sizeof(unsigned char*) * playerAnimator->animFrameNo[idle]);
    Init(playerAnimator);
    {
        QueryPerformanceCounter(&pTime);
        char* save = ReadSaveFile("saves/save 1.txt", 500);
        printf("%s\n", save);
        free(save);
        printf("\nLoading save file took %f seconds. Keep in mind not printing save file will improve save access time to around .00125 seconds with lorem ipsum benchmark. This time will increase however with the encryption and the decryption which is yet to be implemented.\n", deltaTime());
    }
    glfwInit();
    monitor = glfwGetPrimaryMonitor();
    mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    //glfwWindowHint(GLFW_MAXIMIZED, true);
    window = glfwCreateWindow(mode->width, mode->height, title, fullScreen ? monitor : NULL, NULL);
    glfwSetWindowMonitor(window, NULL, 0, 0, mode->width, mode->height, mode->refreshRate);
    glfwMakeContextCurrent(window);
    DWORD frameWaitTime = (DWORD)(1.0f / (float)mode->refreshRate * 1000.0f);
    glfwSwapInterval(vsyncCount);
    if (glewInit() != GLEW_OK) ThrowError("your program is broken");
    PlayerInit();
    float fullScreenET = 0;
    //glUseProgram(0);
    while (!glfwWindowShouldClose(window)) {
        if (!glfwGetWindowAttrib(window, GLFW_FOCUSED)) {
            glfwPollEvents();
            Sleep(frameWaitTime * 10);
            continue;
        }
        if (pressing(GetKeyState(q)) && pressing(GetKeyState(leftControl))) break;
        //37, 39
        if (shouldDraw) {
            glClear(GL_COLOR_BUFFER_BIT);
            shouldDraw = false;
        }
        //glUseProgram(shader);
        //glBindVertexArray(vao);
        //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
        glfwSwapBuffers(window);
        glfwPollEvents();
        Update();
        printf("deltatime is %lf\n", DeltaTime());
        if (fullScreenET > .2f)
        {
            if (pressing(GetKeyState(key_return)) && pressing(GetKeyState(leftAlt))) {
                fullScreen = !fullScreen;
                glfwSetWindowMonitor(window, fullScreen ? monitor : NULL, 0, 0, mode->width, mode->height, mode->refreshRate);
                glfwSwapInterval(vsyncCount);
                fullScreenET = 0;
            }
        }
        else fullScreenET += deltaTime();
        //10000000
        if (shouldDraw) glBufferData(GL_ARRAY_BUFFER, sizeof(playerVerticies), playerVerticies, GL_DYNAMIC_DRAW);
        QueryPerformanceCounter(&pTime);
        //Sleep(frameWaitTime);
    }
    glDeleteTextures(1, &texture);

Basic.shader:

#shader vertex
#version 430 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texcoord;
out vec2 Texcoord;
void main() {
    Texcoord = texcoord;
    gl_Position = position;
}
#shader fragment
#version 430 core
layout(location = 0) in vec4 color;
layout(location = 1) in vec2 Texcoord;
out vec4 v_Texcoord;
uniform vec4 u_Color;
uniform sampler2D u_Texture;
void main() {
    v_Texcoord = texture(u_Texture, Texcoord);
}
//don't add empty line at end of file otherwise it breaks the shader interpretation

Solution

  • It was the manual specification of the layout in my fragment shader. Thank you so much Erdal Küçük and BDL and everyone else that helped. Weird though that there is some sort of different setting on my PC to my laptop. It could be because the version on my PC was very slightly newer.