2017-01-21 2 views
-2

So habe ich eine grundlegende OpenGL-Anwendung gemacht und alles war in Ordnung, bis ich einen Geometrieshader implementierte.OpenGL: glDrawArrays() löst Ausnahme aus (nvoglv32.dll) Zugriffsverletzungsleseposition 0x00000000

Der Fehler im bekommen ist Ausnahme bei 0x6A67F00A geworfen (nvoglv32.dll) in Demo.exe: 0xC0000005: Zugriffsverletzung Leseort 0x00000000.

Nun weiß ich nicht, ob der Shader ist was das Problem verursacht, aber es hat gut funktioniert, bis ich es implementiert habe.

Ich habe ein wenig gegoogelt und es scheint eine Reihe von verschiedenen Gründen dafür zu geben, von denen viele mit den VAOs zu tun haben, die unverändert geblieben sind.

Der Fehler tritt bei glDrawArrays(GL_TRIANGLES, 0, 6);

Dies ist mein C++ Code:

//-------------------------------------------------------------------------------------- 
// BTH - Stefan Petersson 2014. 
//-------------------------------------------------------------------------------------- 
#include <windows.h> 

#include <string> 
#include <fstream> 
#include <streambuf> 

#include <gl/glew.h> 
#include <gl/GL.h> 
#include "glm/glm/glm.hpp" 
#include "glm/glm/gtc/matrix_transform.hpp" 
#include "glm/glm/gtc/type_ptr.hpp" 

#pragma comment(lib, "opengl32.lib") 
#pragma comment(lib, "glew32.lib") 

using namespace std; 

HWND InitWindow(HINSTANCE hInstance); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
HGLRC CreateOpenGLContext(HWND wndHandle); 

GLuint gVertexBuffer = 0; 
GLuint gVertexAttribute = 0; 
GLuint gShaderProgram = 0; 

//is bad but ok 
glm::mat4 World = glm::mat4(1.0f); 
glm::mat4 View; 
glm::mat4 Projection; 
// 

#define BUFFER_OFFSET(i) ((char *)nullptr + (i)) 


void CreateMatrices() { 


    glm::mat4 View = glm::lookAt(
     glm::vec3(0, 0, 3), // Camera is at (4,3,3), in World Space 
     glm::vec3(0, 0, 0), // and looks at the origin 
     glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down) 
    ); 

    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units 
    glm::mat4 Projection = glm::perspective(glm::radians(45.0f), (float)640/(float)480, 0.1f, 100.0f); 

    World = glm::rotate(World, 0.01f, glm::vec3(0, 1, 0)); 



    glm::mat4 mvp = Projection * View * World; 

    GLuint MatrixID = glGetUniformLocation(gShaderProgram, "MVP"); 
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]); 
} 


void CreateTriangleData() 
{ 
    // this is how we will structure the input data for the vertex shader 
    // every six floats, is one vertex. 
    struct TriangleVertex 
    { 
     float x, y, z; 
     float r, g, b; 
    }; 
    // create the actual data in plane Z = 0 
    TriangleVertex triangleVertices[6] = 
    { 
     // pos and color for each vertex 
     //first triangle 
     { -0.5f, 0.5f, -0.0f, 1.0f, 0.0f, 0.0f }, 
     { 0.5f, 0.5f, -0.0f, 0.0f, 1.0f, 0.0f }, 
     { 0.5f, -0.5f, -0.0f, 0.0f, 0.0f, 1.0f }, 
     //second triangle 
     { 0.5f, -0.5f, -0.0f, 0.0f, 0.0f, 1.0f }, 
     { -0.5f, -0.5f, -0.0f, 0.0f, 1.0f, 0.0f }, 
     { -0.5f, 0.5f, -0.0f, 1.0f, 0.0f, 0.0f } 
    }; 

    // Vertex Array Object (VAO) 
    glGenVertexArrays(1, &gVertexAttribute); 
    // bind == enable 
    glBindVertexArray(gVertexAttribute); 
    // this activates the first and second attributes of this VAO 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    // create a vertex buffer object (VBO) id 
    glGenBuffers(1, &gVertexBuffer); 
    // Bind the buffer ID as an ARRAY_BUFFER 
    glBindBuffer(GL_ARRAY_BUFFER, gVertexBuffer); 
    // This "could" imply copying to the GPU, depending on what the driver wants to do... 
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW); 

    // query where which slot corresponds to the input vertex_position in the Vertex Shader 
    GLuint vertexPos = glGetAttribLocation(gShaderProgram, "vertex_position"); 
    // specify that: the vertex attribute "vertexPos", of 3 elements of type FLOAT, not normalized, with STRIDE != 0, 
    //    starts at offset 0 of the gVertexBuffer (it is implicitly bound!) 
    glVertexAttribPointer(vertexPos, 3, GL_FLOAT, GL_FALSE, sizeof(TriangleVertex), BUFFER_OFFSET(0)); 

    // query where which slot corresponds to the input vertex_color in the Vertex Shader 
    GLuint vertexColor = glGetAttribLocation(gShaderProgram, "vertex_color"); 
    // specify that: the vertex attribute "vertex_color", of 3 elements of type FLOAT, not normalized, with STRIDE != 0, 
    //    starts at offset (12 bytes) of the gVertexBuffer 
    glVertexAttribPointer(vertexColor, 3, GL_FLOAT, GL_FALSE, sizeof(TriangleVertex), BUFFER_OFFSET(sizeof(float) * 3)); 

} 

void SetViewport() 
{ 
    glViewport(0, 0, 640, 480); 
} 

void CreateShaders() 
{ 

    //create vertex shader 
    GLuint vs = glCreateShader(GL_VERTEX_SHADER); 
    // open glsl file and put it in a string 
    ifstream shaderFile("VertexShader.glsl"); 
    std::string shaderText((std::istreambuf_iterator<char>(shaderFile)), std::istreambuf_iterator<char>()); 
    shaderFile.close(); 
    // make a double pointer (only valid here) 
    const char* shaderTextPtr = shaderText.c_str(); 
    // ask GL to load this 
    glShaderSource(vs, 1, &shaderTextPtr, nullptr); 
    // ask GL to compile it 
    glCompileShader(vs); 

    //create fragment shader | same process. 
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); 
    shaderFile.open("Fragment.glsl"); 
    shaderText.assign((std::istreambuf_iterator<char>(shaderFile)), std::istreambuf_iterator<char>()); 
    shaderFile.close(); 
    shaderTextPtr = shaderText.c_str(); 
    glShaderSource(fs, 1, &shaderTextPtr, nullptr); 
    glCompileShader(fs); 

    ///create geometry shader | same process. 
    GLuint gs = glCreateShader(GL_GEOMETRY_SHADER); 
    shaderFile.open("Geometry.glsl"); 
    shaderText.assign((std::istreambuf_iterator<char>(shaderFile)), std::istreambuf_iterator<char>()); 
    shaderFile.close(); 
    shaderTextPtr = shaderText.c_str(); 
    glShaderSource(gs, 1, &shaderTextPtr, nullptr); 
    glCompileShader(gs); 

    //link shader program (connect vs and ps) 
    gShaderProgram = glCreateProgram(); 
    glAttachShader(gShaderProgram, fs); 
    glAttachShader(gShaderProgram, vs); 
    glAttachShader(gShaderProgram, gs); 
    glLinkProgram(gShaderProgram); 
    glUseProgram(gShaderProgram); 


} 

void Render() 
{ 
    CreateMatrices(); 
    // set the color TO BE used 
    glClearColor(0.2, 0.2, 0.2, 1); 
    // use the color to clear the color buffer 
    glClear(GL_COLOR_BUFFER_BIT); 

    glDrawArrays(GL_TRIANGLES, 0, 6); 

} 

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 
{ 
    MSG msg = { 0 }; 
    HWND wndHandle = InitWindow(hInstance); //1. Skapa fönster 

    if (wndHandle) 
    { 
     HDC hDC = GetDC(wndHandle); 
     HGLRC hRC = CreateOpenGLContext(wndHandle); //2. Skapa och koppla OpenGL context 

     glewInit(); //3. Initiera The OpenGL Extension Wrangler Library (GLEW) 

     CreateShaders(); 

     SetViewport(); //4. Sätt viewport 

     CreateTriangleData(); //6. Definiera triangelvertiser, 7. Skapa vertex buffer object (VBO), 8.Skapa vertex array object (VAO) 



     ShowWindow(wndHandle, nCmdShow); 

     while (WM_QUIT != msg.message) 
     { 
      if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 
      { 
       TranslateMessage(&msg); 
       DispatchMessage(&msg); 
      } 
      else 
      { 
       Render(); //9. Rendera 

       SwapBuffers(hDC); //10. Växla front- och back-buffer 

      } 
     } 

     wglMakeCurrent(NULL, NULL); 
     ReleaseDC(wndHandle, hDC); 
     wglDeleteContext(hRC); 
     DestroyWindow(wndHandle); 
    } 

    return (int) msg.wParam; 
} 

HWND InitWindow(HINSTANCE hInstance) 
{ 
    WNDCLASSEX wcex = { 0 }; 
    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style   = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = WndProc; 
    wcex.hInstance  = hInstance; 
    wcex.lpszClassName = L"BTH_GL_DEMO"; 
    if(!RegisterClassEx(&wcex)) 
     return false; 

    RECT rc = { 0, 0, 640, 480 }; 
    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE); 

    HWND handle = CreateWindow(
     L"BTH_GL_DEMO", 
     L"BTH OpenGL Demo", 
     WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     rc.right - rc.left, 
     rc.bottom - rc.top, 
     nullptr, 
     nullptr, 
     hInstance, 
     nullptr); 

    return handle; 
} 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     break;  
    } 

    return DefWindowProc(hWnd, message, wParam, lParam); 
} 

HGLRC CreateOpenGLContext(HWND wndHandle) 
{ 
    //get handle to a device context (DC) for the client area 
    //of a specified window or for the entire screen 
    HDC hDC = GetDC(wndHandle); 

    //details: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318286(v=vs.85).aspx 
    static PIXELFORMATDESCRIPTOR pixelFormatDesc = 
    { 
     sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 
     1,        // version number 
     PFD_DRAW_TO_WINDOW |    // support window 
     PFD_SUPPORT_OPENGL |    // support OpenGL 
     PFD_DOUBLEBUFFER |    // double buffered 
     PFD_DEPTH_DONTCARE,    // disable depth buffer <-- added by Stefan 
     PFD_TYPE_RGBA,     // RGBA type 
     32,        // 32-bit color depth 
     0, 0, 0, 0, 0, 0,     // color bits ignored 
     0,        // no alpha buffer 
     0,        // shift bit ignored 
     0,        // no accumulation buffer 
     0, 0, 0, 0,      // accum bits ignored 
     0,        // 0-bits for depth buffer <-- modified by Stefan  
     0,        // no stencil buffer 
     0,        // no auxiliary buffer 
     PFD_MAIN_PLANE,     // main layer 
     0,        // reserved 
     0, 0, 0       // layer masks ignored 
    }; 

    //attempt to match an appropriate pixel format supported by a 
    //device context to a given pixel format specification. 
    int pixelFormat = ChoosePixelFormat(hDC, &pixelFormatDesc); 

    //set the pixel format of the specified device context 
    //to the format specified by the iPixelFormat index. 
    SetPixelFormat(hDC, pixelFormat, &pixelFormatDesc); 

    //create a new OpenGL rendering context, which is suitable for drawing 
    //on the device referenced by hdc. The rendering context has the same 
    //pixel format as the device context. 
    HGLRC hRC = wglCreateContext(hDC); 

    //makes a specified OpenGL rendering context the calling thread's current 
    //rendering context. All subsequent OpenGL calls made by the thread are 
    //drawn on the device identified by hdc. 
    wglMakeCurrent(hDC, hRC); 

    return hRC; 
} 

Hier sind meine Shadern:

Vertex-Shader (Pass-Through)

#version 400 
layout(location = 0) in vec3 vertex_position; 
layout(location = 1) in vec3 vertex_color; 

out vec3 color; 

void main() { 
    color = vertex_color; 
    gl_Position = vec4(vertex_position, 1.0); 
} 

Geometry Shader (redundant, aber für die Zuordnung erforderlich)

#version 400 
layout(triangles) in; 
layout(triangle_strip, max_vertices=3) out; 

uniform mat4 MVP; 

in vec3 color[]; 
out vec3 pass_color[]; 
void main() 
{ 
    for(int i=0; i<3; i++) 
    { 
    gl_Position = MVP * gl_in[i].gl_Position; 
    pass_color[i] = color[i]; 
    EmitVertex(); 
    } 
    EndPrimitive(); 
} 

Fragment Shader

#version 400 
in vec3 pass_color; 
out vec4 fragment_color; 

void main() { 
    fragment_color = vec4 (pass_color, 1.0); 
} 

Es ist eine ganze Menge Code .. Ich würde mein Lehrer fragen über es ist aber an den Wochenenden nicht erreichbar.

Wenn Sie weitere Informationen benötigen, lassen Sie es mich wissen.

Vielen Dank im Voraus!

+0

Warum überprüfen Sie nicht die Shader-Kompilierungs- und Linkstatus? – genpfault

+0

Die meisten dieser Code wurde mir von meinem Lehrer zur Verfügung gestellt, einschließlich der CreateShaders() - Funktion .. –

Antwort

0

Regel, dass Fehler passiert, wenn Sie failed to initialize function pointers auf Ihren Code functions.Based GL Ich kann Ihre Windows-Einstellungen für GL Kontext sehen sieht unvollständig me.You initialisieren nicht Zwischen "dummy" context .Die Bahn hat viele Beispiele für richtige GL Kontext-Setup mit Windows API.And Sie Ihre Fehler handling.For Beispiel verbessern müssen, auf Fehler überprüfen beim Aufruf:

glewInit() 

Basierend auf, wie Sie Setup Ihren OpenGL-Kontext, werden Sie wahrscheinlich mit der Standard-GL-Version ausgeführt werden (1.1, wenn ich mich richtig erinnere). Aber du willst GS benutzen, das OpenGL 4.0 benötigt, und es nicht anfordern, wenn du den Kontext erstellst.Siehe den Link, den ich zeige, wie man einen spezifische GL version.Wie ich oben erwähnt, ist Ihre Einrichtung für moderne OpenGL-Kontext unvollständig.

+0

Nun, die Sache ist das meiste davon ist von meinem Lehrer codiert, ich habe fast keine Ahnung, was in main() an alle (außer der Schleife) .. Aber wie ich schon sagte, alles hat früher gut funktioniert, ich habe nicht viel geändert, nur den Geometrie-Shader hinzugefügt .. –

+0

Der Geometrieshader erfordert eine moderne OpenGL-Konfiguration. In Ihrem Fall haben Sie, basierend auf der Erstellung des Kontexts, keine OpenGL-Version, die GS (4.0) unterstützt. –

+0

@EliasFinoli siehe mein Update –

Verwandte Themen