简体   繁体   中英

Segmentation fault in C using MinGW

The code compiles but crashes when run.

I think it is VertexShaderSource and FragmentShaderSource that are causing problems but I can't seem to find it.

I have been trying to solve this for days now, so your help would be much appreciated.

If the following lines of code are removed the program seems to run as intended.

GLuint RedShader = CreateShader();
glUseProgram(RedShader);

Here is the command line used to compile.

gcc -g ..\\Source\\main.c ..\\Source\\Window.c ..\\Source\\OpenGL.c ..\\Source\\Shader.c -lopengl32 -lgdi32 -o ..\\Binary\\Project.exe

Here is a snippet from the GDB console:

Program received signal SIGSEGV, Segmentation fault.

0x00000000 in ?? ()

(gdb) where

0x00000000 in ?? ()

0x00401991 in CreateShader (VertexShaderSource=0x26f018, >FragmentShaderSource=0x26f014) at ..\\Source\\Shader.c:5

0x00401432 in main () at ..\\Source\\Main.c:12

Here is the Code:

Main.c

#include "..\Header\Window.h"
#include "..\Header\Shader.h"


int main()
{
    Project_CreateWindow("Project", 512, 512);

    float Vertices[] = {-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f};

    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint RedShader = CreateShader();
    glUseProgram(RedShader);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    for(;;)
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        Project_UpdateWindow();
    }

    glDisableVertexAttribArray(0);

    Project_DestroyWindow();

    return 0;
}

Window.h

#ifndef WINDOW_HEADER
#define WINDOW_HEADER

#include <windows.h>
#include <GL\GL.h>
#include "..\Header\OpenGL.h"

void Project_CreateWindow(const char * Title, const unsigned short Width, const unsigned short Height);
void Project_DestroyWindow();
void Project_UpdateWindow();

#endif

Window.c

#include "..\Header\Window.h"

static HDC DeviceContext;
static HWND Window;
static HGLRC RenderContext;

LRESULT CALLBACK EventHandler(HWND Window, UINT Message, WPARAM WordParameter, LPARAM LongParameter);

void Project_CreateWindow(const char * Title, const unsigned short Width, const unsigned short Height)
{
    WNDCLASSEX WindowClass = {sizeof(WNDCLASSEX), CS_OWNDC, EventHandler, 0, 0, GetModuleHandle(0), 0, 0, 0, 0, "WindowClass", 0};
    RegisterClassEx(&WindowClass);
    Window = CreateWindowEx(0, WindowClass.lpszClassName, Title, WS_OVERLAPPEDWINDOW, (GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2), Width, Height, 0, 0, WindowClass.hInstance, 0);
    PIXELFORMATDESCRIPTOR PixelFormat = {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0};
    if ((DeviceContext = GetDC(Window)) == 0)
    {
        //TODO: Device Context Creation Failed
    }
    SetPixelFormat(DeviceContext, ChoosePixelFormat(DeviceContext, &PixelFormat), &PixelFormat);
    if ((RenderContext = wglCreateContext(DeviceContext)) == 0)
    {
        //TODO: Render Context Creation Failed
    }
    if ((wglMakeCurrent(DeviceContext, RenderContext)) == 0)
    {
        //TODO: Make Context Current Failed
    }
    ShowWindow(Window, SW_SHOW);
    GetOpenGLFunctionPointers();
}

void Project_DestroyWindow()
{
    wglMakeCurrent(0, 0);
    wglDeleteContext(RenderContext);
    ReleaseDC(Window, DeviceContext);
    DestroyWindow(Window);
}

void Project_UpdateWindow()
{
    MSG Message;
    if (PeekMessage(&Message, 0, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    SwapBuffers(DeviceContext);
}

LRESULT CALLBACK EventHandler(HWND Window, UINT Message, WPARAM WordParameter, LPARAM LongParameter)
{
    return DefWindowProc(Window, Message, WordParameter, LongParameter);
}

OpenGL.h

#ifndef OPENGL_HEADER
#define OPENGL_HEADER

#include <stddef.h.>
#include <GL\GL.h>
#include <windows.h>
#include <Wingdi.h>

#define GL_ARRAY_BUFFER                   0x8892
#define GL_STATIC_DRAW                    0x88E4
#define GL_VERTEX_SHADER                  0x8B31
#define GL_FRAGMENT_SHADER                0x8B30

typedef char GLchar;
typedef ptrdiff_t GLsizeiptr;

extern void (* glGenBuffers) (GLsizei n, GLuint *buffers);
extern void (* glBindBuffer) (GLenum target, GLuint buffer);
extern void (* glBufferData) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
extern void (* glEnableVertexAttribArray) (GLuint index);
extern void (* glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
extern void (* glDisableVertexAttribArray) (GLuint index);
extern GLuint (* glCreateProgram) (void);
extern GLuint (* glCreateShader) (GLenum type);
extern void (* glShaderSource) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
extern void (* glCompileShader) (GLuint shader);
extern void (* glAttachShader) (GLuint program, GLuint shader);
extern void (* glLinkProgram) (GLuint program);
extern void (* glUseProgram) (GLuint program);

void GetOpenGLFunctionPointers();

#endif

OpenGL.c

#include "..\Header\OpenGL.h"

#include <stdio.h>

void *GetOpenGLFunctionAddress(const char *name);

void (* glGenBuffers) (GLsizei n, GLuint *buffers);
void (* glBindBuffer) (GLenum target, GLuint buffer);
void (* glBufferData) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
void (* glEnableVertexAttribArray) (GLuint index);
void (* glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
void (* glDisableVertexAttribArray) (GLuint index);
GLuint (* glCreateProgram) (void);
GLuint (* glCreateShader) (GLenum type);
void (* glShaderSource) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
void (* glCompileShader) (GLuint shader);
void (* glAttachShader) (GLuint program, GLuint shader);
void (* glLinkProgram) (GLuint program);
void (* glUseProgram) (GLuint program);

void GetOpenGLFunctionPointers()
{
    glGenBuffers = (void *)GetOpenGLFunctionAddress("glGenBuffers");
    glBindBuffer = (void *)GetOpenGLFunctionAddress("glBindBuffer");
    glBufferData = (void *)GetOpenGLFunctionAddress("glBufferData");
    glEnableVertexAttribArray = (void *)GetOpenGLFunctionAddress("glEnableVertexAttribArray");
    glVertexAttribPointer = (void *)GetOpenGLFunctionAddress("glVertexAttribPointer");
    glDisableVertexAttribArray = (void *)GetOpenGLFunctionAddress("glDisableVertexAttribArray");
    glCreateProgram = (void *)GetOpenGLFunctionAddress("glCreateProgram");
    glCreateShader = (void *)GetOpenGLFunctionAddress("glCreateShader");
    glShaderSource = (void *)GetOpenGLFunctionAddress("glShaderSource");
    glCompileShader = (void *)GetOpenGLFunctionAddress("glCompileShader");
    glAttachShader = (void *)GetOpenGLFunctionAddress("glAttachShader");
    glLinkProgram = (void *)GetOpenGLFunctionAddress("glLinkProgram");
    glUseProgram = (void *)GetOpenGLFunctionAddress("glUseProgram");
}

void *GetOpenGLFunctionAddress(const char *FunctionName)
{
  void *FunctionPointer = (void *)wglGetProcAddress(FunctionName);

  if(FunctionPointer == 0 || (FunctionPointer == (void*)0x1) || (FunctionPointer == (void*)0x2) || (FunctionPointer == (void*)0x3) || (FunctionPointer == (void*)-1))
  {
        HMODULE Module = LoadLibraryA("opengl32.dll");
        FunctionPointer = (void *)GetProcAddress(Module, FunctionName);

        if(FunctionPointer == 0 || (FunctionPointer == (void*)0x1) || (FunctionPointer == (void*)0x2) || (FunctionPointer == (void*)0x3) || (FunctionPointer == (void*)-1))
        {
            printf("%s %i", "Invalid OpenGL Function Pointer, Last Error:", GetLastError());
        }
  }

  return FunctionPointer;
}

Shader.h

#ifndef SHADER_HEADER
#define SHADER_HEADER

#include "..\Header\OpenGL.h"

GLuint CreateShader();

#endif

Shader.c

    #include "..\Header\Shader.h"

GLuint CreateShader()
{
    const GLchar * VertexShaderSource  = "#version 330 core\n layout(location = 0) in vec3 vertexPosition_modelspace;\n void main(){\n gl_Position.xyz = vertexPosition_modelspace;\n gl_Position.w = 1.0;\n }";
    const GLchar * FragmentShaderSource = "#version 330 core\n out vec3 color;\n void main(){\n color = vec3(1.0f, 0.55f, 0.0f);\n }";

    GLuint ShaderProgram = glCreateProgram();

    GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(VertexShader, 1, &VertexShaderSource, 0);
    glShaderSource(FragmentShader, 1, &FragmentShaderSource, 0);

    glCompileShader(VertexShader);
    glCompileShader(FragmentShader);

    glAttachShader(ShaderProgram, VertexShader);
    glAttachShader(ShaderProgram, FragmentShader);

    glLinkProgram(ShaderProgram);

    return ShaderProgram;
}

Forgot the calling convention eg

extern void (* glGenBuffers) (GLsizei n, GLuint *buffers);

Should be changed to:

extern void (__stdcall * glGenBuffers) (GLsizei n, GLuint *buffers);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM