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!
Warum überprüfen Sie nicht die Shader-Kompilierungs- und Linkstatus? – genpfault
Die meisten dieser Code wurde mir von meinem Lehrer zur Verfügung gestellt, einschließlich der CreateShaders() - Funktion .. –