سؤال

I want to draw a texture in my shader but get an exception (see below).

I have following code:

int vertexArray;

//Pointer to Buffers
int vertexBuffer;
int colorBuffer;
int coordBuffer;

int texUniform; //Pointer to Uniform

int texture; //Pointer to Texture

Init

GL.Enable(EnableCap.Texture2D);
texture = LoadPNG("Resources\\Test.png");
//...
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)All.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)All.Nearest);
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);

vertexArray = GL.GenVertexArray();
GL.BindVertexArray(vertexArray);

float[] TexCoords = new float[] {
            0.0f, 0.0f,
            1.0f, 0.0f,
            0.0f, 1.0f,
}; //(Array.Length = 2*3)

//Arrays for Vertex (3*3) and Color (4*3)
//GenBuffer, BindBuffer and BufferData for Color and Vertex

coordBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.TextureBuffer, coordBuffer);
GL.BufferData(BufferTarget.TextureBuffer, (IntPtr)(sizeof(float) * TexCoords.Length), TexCoords, BufferUsageHint.StaticDraw);

//Load shader

texUniform = GL.GetUniformLocation(shaderProgram, "tex");
GL.Uniform1(texUniform, 0);
GL.ActiveTexture(TextureUnit.Texture0);

Draw

GL.UseProgram(shaderProgram);
GL.BindTexture(TextureTarget.Texture2D, texture);

GL.EnableVertexAttribArray(0);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableClientState(ArrayCap.VertexArray);

GL.EnableVertexAttribArray(1);
GL.BindBuffer(BufferTarget.ArrayBuffer, colorBuffer);
GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableClientState(ArrayCap.ColorArray);

GL.BindBuffer(BufferTarget.TextureBuffer, coordBuffer);
GL.TexCoordPointer(2, TexCoordPointerType.Float, Vector2.SizeInBytes, 0);
GL.EnableClientState(ArrayCap.TextureCoordArray);

GL.DrawArrays(PrimitiveType.Triangles, 0, 6); //<------ Exception

GL.DisableVertexAttribArray(0);
GL.DisableVertexAttribArray(1);

I get a System.AccessViolationException at GL.DrawArrays(...);. I suspect that i haven't loaded a buffer correctly or used a pointer in an incorrect way. The exception is caused by changes i did to get a texture with texture coordinates into the shader, that means vertex and color buffer are working.

I'm not sure what i am doing wrong. I tried different things with the shader but it seems it doesn't matter what i am doing with the shader...

At my last try: Vertex Shader

#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 texCoord;

out vec4 vColor;
out vec2 texCoords[];

void main(){
  gl_Position = vec4(position, 1.0);
  texCoords[0] = texCoord;
  vColor = color;
}

Fragment Shader

#version 330 core
in vec4 vColor;
in vec2 texCoords[];

uniform sampler2D tex;

out vec4 fColor;

void main(void)
{
  //fColor = vColor;
  fColor = texture2D(Texture0, texCoords[0].st);
}

GetShaderInfoLog and GetProgramInfoLog do not return any errors when i comment GL.DrawArrays(...) and run the application.

What is wrong with my code?

هل كانت مفيدة؟

المحلول

Do not enable client state vertex arrays.

Replace the following:

GL.EnableClientState(ArrayCap.VertexArray);
...
GL.EnableClientState(ArrayCap.ColorArray);
...
GL.EnableClientState(ArrayCap.TextureCoordArray);

With:

GL.EnableVertexAttribArray(0);
...
GL.EnableVertexAttribArray(1);
...
GL.EnableVertexAttribArray(2);

At present, you are telling GL to source vertex attributes from glVertexPointer (...), glColorPointer (...) and glTexCoordPointer (...), none of which you actually have setup.

You might be able to get away with enabling the client state: ArrayCap.VertexArray because many drivers alias that to attribute 0, but the others are a recipe for disaster. Nevertheless, until you remove the EnableClientState (...) calls you are going to continue crashing.


Update:

I missed something in your texture coordinate setup...

You also need to replace this line:

GL.TexCoordPointer(2, TexCoordPointerType.Float, Vector2.SizeInBytes, 0);

With this:

GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, 0, 0);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top