(I'm a pretty new Coder (at least in Graphics programming), so don't be too harsh with me :( )
Today I tried to render a simple triangle using the C# implementation of OpenGL (GLFW), I followed the web tutorial from "LearnOpenGL.com" specifically the hello triangle tutorial.
I've completed the entire tutorial and expect the program to run and show me a beautifull triangle, instead it gives out the Error message:
_glDrawElements(mode, count, type, indices) System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'"
I searched for a solution, but sadly couldn't find any, I completely checked my code with the tutorial (which is where the error probably is, since I need to "transpose" it from C++ to C#) and couldn't find any errors.
Here's My Code:
class Implementation : App.Game
{
uint VBO;
uint VAO;
uint EBO;
uint VertexShader;
uint FragmentShader;
uint ShaderProgram;
float[] vertices =
{
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f
};
uint[] indices =
{
0, 1, 2,
1, 2, 3
};
public Implementation(int windowWidth, int windowHeight, string windowTitle) : base(windowWidth, windowHeight, windowTitle)
{
// StartUp Code hier
}
protected override void Initialize()
{
// Startet Komponenten und das Spiel
}
protected unsafe override void LoadResources()
{
// Lädt die hier angegebene Ressourcen
// ShaderProgram initiieren
// -
// Vertex Shader
VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, Shader.vertexShader);
glCompileShader(VertexShader);
// Shader-Kompilationsfehler Check
int[] succes = glGetShaderiv(VertexShader, GL_COMPILE_STATUS, 1);
if (succes[0] == 0)
{
string Error = glGetShaderInfoLog(VertexShader);
Debug.WriteLine("VERTEX SHADER COMPILATION ERROR | " + Error);
}
// -
// Fragment Shader
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, Shader.fragmentShader);
glCompileShader(FragmentShader);
// Shader-Kompilationsfehler Check
succes = glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, 1);
if (succes[0] == 0)
{
string Error = glGetShaderInfoLog(FragmentShader);
Debug.WriteLine("FRAGMENT SHADER COMPILATION ERROR | " + Error);
}
// -
// Shader zusammenlinken
ShaderProgram = glCreateProgram();
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
// Linker-Fehler Check
succes = glGetProgramiv(ShaderProgram, GL_LINK_STATUS, 1);
if (succes[0] == 0)
{
string Error = glGetProgramInfoLog(ShaderProgram);
Debug.WriteLine("SHADER PROGRAM LINKING ERROR | " + Error);
}
// Unbenutzte Variablen entfernen
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
// Vertex- u. Bufferdaten laden und die Vertex Attribute konfigurieren
glGenVertexArrays(1, (uint*)VAO);
glGenBuffers(1, (uint*)VBO);
glGenBuffers(1, (uint*)EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
fixed (float* v = &vertices[0])
{
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.Length, v, GL_STATIC_DRAW);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
fixed (uint* i = &indices[0])
{
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * indices.Length, i, GL_STATIC_DRAW);
}
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
protected unsafe override void Render()
{
// Render Code hier
// -
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// -
// Erstes Dreieck
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
Glfw.SwapBuffers(WindowManager.Window);
Glfw.PollEvents();
}
protected override void Update()
{
// Führt auf allen Komponenten und auf dem Spiel die Update funktion durch
}
}
And here´s the Shader Code:
public static string vertexShader = @"#version 330 core
layout (location = 0) in vec3 aPosition;
void main()
{
gl_Position = vec4(aPosition.x, aPosition.y, aPosition.z, 1.0);
}";
public static string fragmentShader = @"#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}";
Just for clarification, the background code (LoadResources, Update, Render, Init) all works, I've checked multiple times.
The issue are the lines
v
andi
are just a pointer to the 1st elements of the managed arrays.You have to created Fixed Size Buffers to transfer the data arrays to the GPU. For instance use
Marshal.StructureToPtr
to marshal data from a managed object to an unmanaged block of memory: