2017-01-21 16 views
-2

Итак, я создал базовое приложение OpenGL, и все было в порядке, пока я не реализовал шейдер Geometry.OpenGL: исключение glDrawArrays() throws (nvoglv32.dll) Место обнаружения нарушения доступа 0x00000000

И.М. ошибка получаю Исключение брошено в 0x6A67F00A (nvoglv32.dll) в demo.exe: 0xC0000005: Нарушение прав доступа чтения местоположение 0x00000000.

Теперь я не знаю, является ли шейдер причиной возникновения проблемы, но он работал нормально, пока я его не реализовал.

Ive сделал некоторые поисковые запросы, и, похоже, существует множество причин, многие из которых связаны с VAO, которые остались неизменными.

Ошибка возникает при glDrawArrays(GL_TRIANGLES, 0, 6);

Вот мой C++ код:

//-------------------------------------------------------------------------------------- 
// 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; 
} 

Вот мои шейдеры:

Vertex Shader (сквозная)

#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 (избыточный, но необходимо для назначения)

#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(); 
} 

Фрагмент Shader

#version 400 
in vec3 pass_color; 
out vec4 fragment_color; 

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

Его изрядное количество коды .. Я хотел бы спросить свой учитель о но он не доступен в выходные дни.

Если вам нужна любая другая информация, дайте мне знать.

Заранее благодарен!

+0

Почему вы не проверяете компиляцию шейдеров и статусы ссылок? – genpfault

+0

Этот код был предоставлен мне моим учителем, включая CreateShaders() - функцию. –

ответ

0

Обычно эта ошибка возникает, когда вы используете failed to initialize function pointers для функций GL. Основываясь на вашем коде, я вижу, что ваша установка Windows для контекста GL выглядит неполной для меня. Вы не инициализируете промежуточный "dummy" context. В Интернете есть много примеров правильного GL настройка контекста с помощью Windows, API.And необходимо улучшить свою ошибку handling.For пример, проверить на наличие ошибок при вызове:

glewInit() 

на основании того, как вы настроите свой контекст OpenGL, вы, вероятно, работать с версией по умолчанию GL (1.1, если я правильно помню). Но вы хотите использовать GS, который требует OpenGL 4.0, и вы не запрашиваете его при создании контекста. См. ссылку, которую я предоставил, чтобы показать, как запросить конкретной версии GL. Как я уже упоминал выше, ваша установка является неполной для современного контекста OpenGL.

+0

Ну, это большая часть этого кода моего учителя, я почти не знаю, что происходит в main() at все (кроме цикла). Но, как я уже сказал, все прошло отлично, я не сильно изменился, просто добавил геометрический шейдер. –

+0

Геометрический шейдер требует современной установки OpenGL. В вашем случае, основываясь на том, как вы создаете контекст, у вас нет активной версии OpenGL, поддерживающей GS (4.0) –

+0

@EliasFinoli см. Мое обновление –

 Смежные вопросы

  • Нет связанных вопросов^_^