1

I created a library to use with OpenGL whose code is provided here.

It compiles fine and nothing seems to be wrong but when I use it with a test program then it shows an exception, Access violation at location 0x00000000 ( which is obviously due to GLEW not being initialized ).

But GLEW is already initialized in the library see the function definition for LIB_CreateWindow in window.c from the source code in the provided link above.

Also, if I try to draw something using the library with OpenGL it shows just a blank screen.

Code for the test program:- (main.c)

#define GLEW_STATIC
#include <GL/glew.h>
#include <window.h>
#include <stddef.h>
#include <lib_window.h>
#include <lib_test_draw.h>

int main()
{
    // Initialize the library...
    LIB_Initialize();

    // Get center position...
    LIB_Vector2i size; LIB_GetDisplaySize(&size);
    // Create the window...
    LIB_Window * window = LIB_CreateWindow("BLITZ Test", LIB_CreateVector2i((size.x - 1024) / 2, (size.y - 768) / 2),
        LIB_CreateVector2i(1024, 768), LIB_FALSE, LIB_FALSE, LIB_DRAWMODE_FIXED, LIB_USE_DEFAULT_CONTEXT_SETTINGS);

    // Adding these two lines again removes the exception...
    glewExperimental = GL_TRUE;
    glewInit(); // Why initialize GLEW again?

    // Use OpenGL to do cool stuff...
    LIB_TemporaryCreate();

    while (LIB_IsWindowOpened(window))
    {
        LIB_BeginRender(LIB_SetColorRGB(0, 0, 0));
        // Draw it all here...
        LIB_TemporaryRender();
        LIB_EndRender(window);
    }
    // Destroy the current window...
    LIB_DestroyWindow(window);
    // Terminate library...
    LIB_Terminate();
    return 0;
}

I created a test file in the library to test whether it can draw anything if called from the library itself but it just shows blank screen but there is no exception.

lib_test_draw.h

#ifndef LIB_TEST_DRAW
#define LIB_TEST_DRAW

#define GLEW_STATIC
#include <GL/glew.h>
#include <stddef.h>
#include <stdio.h>

const char * vertex_src =
"#version 330 core\n"
"layout (location = 0) in vec3 pos;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(pos, 0.0f);\n"
"}\0";

const char * fragment_src =
"#version 330 core\n"
"out vec4 Color;\n"
"void main()\n"
"{\n"
"Color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
"}\0";

GLuint shdr_prg;
GLuint VAO;
GLuint VBO;

void CreateProgram(const char * vertex_shdr_src, const char * frag_shdr_src, GLuint * prg)
{
    GLuint vertex_shdr = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shdr, 1, &vertex_shdr_src, NULL);
    glCompileShader(vertex_shdr);

    GLuint frag_shdr = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(frag_shdr, 1, &frag_shdr_src, NULL);
    glCompileShader(frag_shdr);

    // Checking if glCreateProgram was successful.
    if (glCreateProgram() == 0)
    {
        printf("Error creating program!\n");
    }

    *prg = glCreateProgram();
    glAttachShader(*prg, vertex_shdr);
    glAttachShader(*prg, frag_shdr);
    glLinkProgram(*prg);

    glDeleteShader(vertex_shdr);
    glDeleteShader(frag_shdr);
}

void LIB_TemporaryCreate()
{
    CreateProgram(vertex_src, fragment_src, &shdr_prg);
    GLfloat vertices[] =
    {
        -0.5f,  -0.5f,  0.0f,
         0.5f,  -0.5f,  0.0f,
         0.0f,   0.5f,  0.0f
    };

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);
}

void LIB_TemporaryRender()
{
    glUseProgram(shdr_prg);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
}

#endif /* LIB_TEST_DRAW */
Ruks
  • 3,886
  • 1
  • 10
  • 22
  • Try checking what GLEW says inside of Your library (right after the call to `glewInit`) by using the routine `glewGetErrorString`. – Dori Mar 27 '18 at 06:32
  • 3
    also GLEW initialized is not a guarantee that you have the extensions you are using ... you should check which gl function is crashing and check if your GL implementation has it or not... If the case than you need update your drivers or gfx card or use only stuff you got at your disposal. – Spektre Mar 27 '18 at 07:28
  • @Matso What should I put in the parameter GLenum mode for the function glewGetErrorString. – Ruks Apr 01 '18 at 08:26
  • @Spektre The function 'glCreateShader()' is crashing. I have OpenGL 4.3, by the way. – Ruks Apr 01 '18 at 08:26
  • @Ruks try to cross check with this: [complete GL+GLSL+VAO/VBO C++ example](https://stackoverflow.com/a/31913542/2521214) btw I do not see `glCreateShader` in code you posted. I think the problem is that you are including `glew.h` instead of `glew.c` but if that is the point the code would not even compile due to unresolved externals... (h is for dynamic linkage and c is for static lib at least in the GLEW version I use) – Spektre Apr 01 '18 at 08:33
  • Also how did you check the GL version? if by external app than that is wrong you need to use [glGetString](https://stackoverflow.com/a/35826975/2521214) for this... – Spektre Apr 01 '18 at 08:54
  • @Ruks The value returned by glewInit – Dori Apr 01 '18 at 09:03
  • @Spektre I just added the code for a temporary shader program to describe the problem. – Ruks Apr 01 '18 at 09:24
  • @Ruks `*prg=` seems suspicious (but that is probably just mine paranoia). I would use `GLuint &prg` in the header and `prg=...` in the code. Your way should work but I had some problems with those in the past accessing pointer of pointer instead of the variable (due to bug in compiler) so I avoid such statements from then ... You can also check `if (glCreateProgram==NULL) error message...` to check if you got problem with pointers or do not actually have shaders at disposal ... – Spektre Apr 01 '18 at 09:32
  • @Spektre I changed the code and avoided the use of `*prg=`. I cannot use `GLuint &prg` , I am doing it in C. – Ruks Apr 01 '18 at 09:52
  • @Matso I checked using glewGetErrorString and it did not give any errors! – Ruks Apr 01 '18 at 09:54
  • and is the `glCreateShader` not null pointer? if your GL version (inside your GL context) is low GLEW will not expose it ... – Spektre Apr 01 '18 at 10:00
  • @Spektre No it is not, and also I have added a code in the library itself to draw a triangle on the screen but when I call the function in the test program it just shows a white screen without any triangle. – Ruks Apr 01 '18 at 10:26
  • with the new GL api all rendering goes through shaders and when they are not compiled/linked/used and connected through the right locations nothing is rendered .... As I mentioned before try to cross check with mine example I linked it is working so go step by step and find the difference .... – Spektre Apr 01 '18 at 10:54
  • @Spektre Okay I found it out, I initialized GLEW in the c file ( not the header! ). When I use it, then the library can use all OpenGL functions to draw but I have to initialize it again to draw it anything again outside of the library. – Ruks Apr 04 '18 at 06:44
  • @Ruks that suggest you got separate OpenGL contexts so you should investigate because one should be enough for you ... I suspect one is unused and just eating resources. It might also be a multithreading problem check your `wglMakeCurrent` or different OS counterparts calls (each thread should have it before rendering) – Spektre Apr 04 '18 at 06:50
  • @Spektre Nah, nothing like that! I didn't even want to use OpenGL in my test program anyways, I was just testing why it was not rendering with my library(not giving exception, just a blank window). But I figured it out. I guess I should close this question here. By the way, can you write a proper answer for this question(not forcing). – Ruks Apr 06 '18 at 10:56
  • @Ruks I think you are more qualified to write the answer as you know what was the problem now ... (yes you can answer your own questions) – Spektre Apr 06 '18 at 14:23
  • @Spektre Thanks for helping me out. – Ruks Apr 07 '18 at 02:49

1 Answers1

2

Okay,... figured out the problem,

The GLEW library needs to be initialized outside the source file(which is not accessible by the program which is using it!).

That is why you need to initialize GLEW again because once it is compiled, the program can't find(nor access) the initialization done inside the source file of the library.

You can!, however initialize it in the header file to work!

Thanks to @Spektre for helping me point out this problem.

Ruks
  • 3,886
  • 1
  • 10
  • 22