2015-11-08 33 views
0

代碼編譯但運行時崩潰。C使用MinGW分段錯誤

我認爲這是造成問題的VertexShaderSource和FragmentShaderSource,但我似乎無法找到它。

我一直在試圖解決這個問題,所以你的幫助將不勝感激。

如果刪除了以下代碼行,程序似乎按預期運行。

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

這裏是用於編譯的命令行。

GCC -g .. \源\ main.c中.. \源\ Window.c .. \源\ OpenGL.c .. \源\ Shader.c -lopengl32 -lgdi32 -o .. \二進制\ Project.exe

下面是從GDB控制檯的一個片段:

計劃接收信號SIGSEGV,分割過錯。

0x00000000在?? ()

(GDB)其中

在00000000 ?? ()

0x00401991在CreateShader(VertexShaderSource = 0x26f018,> FragmentShaderSource = 0x26f014)在.. \源\ Shader.c:5

在主0x00401432()在.. \源\ MAIN.C:12

這裏是代碼:

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; 
} 
+0

很多混亂的有關文件名,但是,在你的 'window.h中' 文件中,有一份聲明'的#include」 .. \頭\窗口。 h「'這意味着頭文件包含它自己。謝天謝地,你的window.h文件有'包括衛兵',但爲什麼甚至試圖包括自己? – user3629249

+0

在一個源文件中定義/設置的變量(其中變量在頭文件中聲明)在另一個包含相同頭文件的源文件中不可見。而第二個源文件會看到一組未設置的變量。建議在源文件中聲明變量並使頭文件只有'extern'語句。 – user3629249

+0

可以顯示用於編譯的命令行,所以我們可以看到鏈接的確切庫? –

回答

0

忘記調用約定例如

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

應改爲:

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