error c0000: syntax error, unexpected '?' at token '?' - c#

Alright I searched other peoples questions and could not find a solution to my problem. I am using OpenTK in C# and GLSL 330. It is producing the error message
error c0000: syntax error, unexpected '?' at token '?'
For some reason it doesn't like something I'm doing. So, here is my code I hope someone can tell
me what I'm doing wrong.
public static string vertexShaderSource = #"
#version 330
uniform mat4 pvm;
in vec4 Position;
in vec2 texCoord;
out vec2 texCoordV;
void main()
{
texCoordV = texCoord;
gl_Position = Position * pvm;
}";
public static string fragmentShaderSource = #"
#version 330
in vec2 texCoordV;
out vec4 colorOut;
void main()
{
colorOut = vec4(texCoord, 0.0, 0.0);
}";
public void Initalize()
{
style = GUI_Skin.styles[0];
vertices = new Vector3[6];
vertices[0] = new Vector3(0, 0, 0f);
vertices[1] = new Vector3(100, 0, 0f);
vertices[2] = new Vector3(0, 100, 0f);
vertices[3] = new Vector3(100, 0, 0f);
vertices[4] = new Vector3(0, 100, 0f);
vertices[5] = new Vector3(100, 100, 0f);
GL.GenBuffers(1, out vertHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertHandle);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
new IntPtr(vertices.Length * Vector3.SizeInBytes),
vertices, BufferUsageHint.StaticDraw);
texCoords = new Vector2[6];
texCoords[0] = new Vector2(0,0);
texCoords[1] = new Vector2(1, 0);
texCoords[2] = new Vector2(0, 1);
texCoords[3] = new Vector2(1, 0);
texCoords[4] = new Vector2(0, 1);
texCoords[5] = new Vector2(1, 1);
GL.GenBuffers(1, out texHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer, texHandle);
GL.BufferData<Vector2>(BufferTarget.ArrayBuffer,
new IntPtr(texCoords.Length * Vector2.SizeInBytes),
texCoords, BufferUsageHint.StaticDraw);
}
public void Draw()
{
GL.EnableVertexAttribArray(vertHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertHandle);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
GL.EnableVertexAttribArray(texHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer, texHandle);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vector2.SizeInBytes, 0);
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
GL.DisableVertexAttribArray(vertHandle);
GL.DisableVertexAttribArray(texHandle);
}

Alright so the issues have been fixed. Thanks to the helpful comments above.
Lets start with the shader. The # symbol before the string declaration had to be removed and after every line \n had to be inserted. Also, I was calling transpose when I draw with the shader. Which could be fixed by changing the order of matrices.
public static void Run()
{
int uniformLocation = GL.GetUniformLocation(shaderProgramHandle, "pvm");
Matrix4 mat;
GL.GetFloat(GetPName.ProjectionMatrix, out mat);
GL.UniformMatrix4(uniformLocation, false, ref mat);
GL.UseProgram(shaderProgramHandle);
}
I changed from GL.UniformMatrix4(uniformLocation, true, ref mat); to GL.UniformMatrix4(uniformLocation, false, ref mat); and in the shader itself the order of gl_Position was changed from Position * pvm; to pvm * Position;
public static string vertexShaderSource = "#version 330\n" +
"uniform mat4 pvm;\n" +
"in vec4 Position;\n" +
"in vec2 texCoord;\n" +
"out vec2 texCoordV;\n" +
"void main()\n" +
"{\n" +
"texCoordV = texCoord;\n" +
"gl_Position = pvm * Position;\n" +
"}\n";
public static string fragmentShaderSource = "#version 330\n" +
"in vec2 texCoordV;\n" +
"out vec4 colorOut;" +
"void main()\n" +
"{\n" +
"colorOut = vec4(texCoordV, 0.0, 0.0);\n" +
"}\n" ;
After this was fixed I was getting an error where the rendering surface went white. The error was located within the Draw() function. Basically I wasn't assigning the array locations properly.
public void Draw()
{
GL.EnableVertexAttribArray(0);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertHandle);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
GL.EnableVertexAttribArray(1);
GL.BindBuffer(BufferTarget.ArrayBuffer, texHandle);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vector2.SizeInBytes, 0);
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
GL.DisableVertexAttribArray(0);
GL.DisableVertexAttribArray(1);
}

Related

Using a frame buffer yields strange results?

I am very new to OpenGL (OpenTK), and I tried to get my first frame buffer working so I could apply post processing effects. However, when I try to draw the frame buffer it draws in the wrong place.
My rendering code is here:
protected override void OnRenderFrame(FrameEventArgs args)
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, this._frameBufferObject);
//GL.BindTexture(TextureTarget.Texture2D, 0);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
GL.UseProgram(this._shaderProgramHandle);
GL.BindVertexArray(this._vertexArrayHandle);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, this._elementBufferObject);
GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, 0);
// Draw frame buffer
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, this._frameBufferTextureColorHandle);
GL.ActiveTexture(TextureUnit.Texture0);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.UseProgram(this._frameBufferProgramHandle);
int screenTextureLocation = GL.GetUniformLocation(this._frameBufferProgramHandle, "screenTexture");
GL.Uniform1(screenTextureLocation, 0);
GL.BindVertexArray(this._rectangleVertexArrayObject);
GL.Disable(EnableCap.DepthTest);
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
this.Context.SwapBuffers();
base.OnRenderFrame(args);
}
And the code that creates the array object is here:
this._rectangleVertexArrayObject = GL.GenVertexArray();
this._rectangleVertexBufferObject = GL.GenBuffer();
GL.BindVertexArray(this._rectangleVertexArrayObject);
GL.BindBuffer(BufferTarget.ArrayBuffer, this._rectangleVertexBufferObject);
GL.BufferData(BufferTarget.ArrayBuffer, rectangleVertices.Length * sizeof(float), rectangleVertices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * sizeof(float), 0);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * sizeof(float), 2 * sizeof(float));
GL.EnableVertexAttribArray(0);
GL.EnableVertexAttribArray(1);
GL.BindVertexArray(0);
My shader code if it makes a difference:
string vertexShaderCode =
#"
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec4 aColor;
layout (location = 2) in vec2 aTexCoord;
layout (location = 3) in float aTexId;
out vec4 vColor;
out vec2 texCoord;
out float texId;
void main(void)
{
vColor = aColor;
texCoord = aTexCoord;
texId = aTexId;
gl_Position = vec4(aPosition, 1.0);
}
";
string fragmentShaderCode =
#"
#version 330 core
in vec4 vColor;
in vec2 texCoord;
in float texId;
uniform sampler2D[2] textures;
out vec4 pixelColor;
void main()
{
if (texId == 0) {
pixelColor = texture(textures[int(0)], texCoord) * vColor;
}
else if (texId == 1) {
pixelColor = texture(textures[int(1)], texCoord) * vColor;
}
}
";
string frameBufferVertexShadeCode =
#"
#version 330 core
layout (location = 0) in vec2 aPosition;
layout (location = 1) in vec2 aTexCoord;
out vec2 texCoord;
void main()
{
gl_Position = vec4(aPosition.x, aPosition.y, 0.0, 1.0);
texCoord = aTexCoord;
}
";
string frameBufferFragmentShaderCode =
#"
#version 330 core
in vec2 texCoord;
out vec4 pixelColor;
uniform sampler2D screenTexture;
void main()
{
pixelColor = texture(screenTexture, texCoord);
}
";
And here is the list of the rectangle vertices:
float[] rectangleVertices =
{
// Coords // texCoords
+1.0f, -1.0f, +1.0f, +0.0f,
-1.0f, -1.0f, +0.0f, +0.0f,
-1.0f, +1.0f, +0.0f, +1.0f,
+1.0f, +1.0f, +1.0f, +1.0f,
+1.0f, -1.0f, +1.0f, +0.0f,
-1.0f, +1.0f, +0.0f, +1.0f,
};
The result created is also here

vTextCoord value is not working - c# OPENTK

My app is displaying an image in full screen by using OpenGL shader code as shown below. The vertex shader I used here is copied from somewhere. Can anyone explain why here used vTexCoord = (a_position.xy+1)/2;? When I'm trying with vTexCoord = a_position.xy, my OpenGL output is split into four rectangles and only it's top right portion is showing the image. Other three sides are seem as blurred. What change should I do to work it with vTexCoord = a_position.xy ?
Some important functions used in the project are shown below. Please check and help to correct.
float[] vertices = {
// Left bottom triangle
-1f, -1f, 0f,
1f, -1f, 0f,
1f, 1f, 0f,
// Right top triangle
1f, 1f, 0f,
-1f, 1f, 0f,
-1f, -1f, 0f
};
private void CreateShaders()
{
/***********Vert Shader********************/
vertShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertShader, #"attribute vec3 a_position;
varying vec2 vTexCoord;
void main() {
vTexCoord = (a_position.xy+1)/2;
gl_Position = vec4(a_position, 1);
}");
GL.CompileShader(vertShader);
/***********Frag Shader ****************/
fragShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragShader, #"precision highp float;
uniform sampler2D sTexture;varying vec2 vTexCoord;
void main ()
{
vec4 color= texture2D (sTexture, vTexCoord);
gl_FragColor =color;
}");
GL.CompileShader(fragShader);
}
private void InitBuffers()
{
buffer = GL.GenBuffer();
positionLocation = GL.GetAttribLocation(program, "a_position");
positionLocation1 = GL.GetUniformLocation(program, "sTexture");
GL.EnableVertexAttribArray(positionLocation);
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 0, 0);
}
public void DrawImage(int image)
{
GL.Viewport(new Rectangle(0, 0, ScreenWidth, ScreenHeight));
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
GL.LoadIdentity();
//GL.Ortho(0, 1920, 0, 1080, 0, 1);
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix();
GL.LoadIdentity();
GL.Disable(EnableCap.Lighting);
GL.Enable(EnableCap.Texture2D);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, image);
GL.Uniform1(positionLocation1, 0);
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(0, 1);
GL.Vertex3(0, 0, 0);
GL.TexCoord2(0, 0);
GL.Vertex3(1920, 0, 0);
GL.TexCoord2(1, 1);
GL.Vertex3(1920, 1080, 0);
GL.TexCoord2(1, 0);
GL.Vertex3(0, 1080, 0);
GL.End();
RunShaders();
GL.Disable(EnableCap.Texture2D);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Modelview);
glControl1.SwapBuffers();
}
private void RunShaders()
{
GL.UseProgram(program);
GL.DrawArrays(PrimitiveType.Triangles, 0, vertices.Length / 3);
}
Can anyone explain why here used vTexCoord = (a_position.xy+1)/2;?
The vertex coordinates in you example are in range [-1, 1], for the x and component. This matches to the normalized device space. The normalized device space is a cube from the left-lower-front (-1, -1, -1), to the right-top-back (1, 1, 1), this is the area wich is "visible". This area is mapped to the viewport.
This causes that the vertex coordinates, in your example, form a rectangle, which covers the entire viewport.
If the texture coordinates should wrap the entire texture to the quad, then the texture coordinates (u, v) have to be in range [0, 1]. (0, 0) is the lower left of the texture and (1, 1) the upper right.
See also How do OpenGL texture coordinates work?
So the x and y component of a_position have to be mapped form the range [-1, 1], to the range [0, 1], to be used as uv coordinates for the texture lookup:
u = (a_position.x + 1) / 2
v = (a_position.y + 1) / 2
What change should I do to work it with vTexCoord = a_position.xy?
This is not possible, but you can generate a separate texture coordinate attribute, which is common:
attribute vec3 a_position;
attribute vec2 a_texture;
varying vec2 vTexCoord;
void main() {
vTexCoord = a_texture;
gl_Position = vec4(a_position, 1);
}
float[] vertices = {
// x y z u v
// Left bottom triangle
-1f, -1f, 0f, 0f, 0f
1f, -1f, 0f, 1f, 0f
1f, 1f, 0f, 1f, 1f
// Right top triangle
1f, 1f, 0f, 1f, 1f
-1f, 1f, 0f, 0f, 1f
-1f, -1f, 0f 0f, 0f
};
buffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
positionLocation = GL.GetAttribLocation(program, "a_position");
tetureLocation = GL.GetAttribLocation(program, "a_texture");
GL.EnableVertexAttribArray(positionLocation);
GL.EnableVertexAttribArray(tetureLocation);
int stride = sizeof(float) * 5; // 5 because of (x, y, z, u, v)
int offsetUV = sizeof(float) * 3; // 3 because the u and v coordinates are the 4th and 5th coordinate
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, stride, 0);
GL.VertexAttribPointer(tetureLocation, 2, VertexAttribPointerType.Float, false, stride, (IntPtr)(offsetUV));

Unable to find entry point 'glCreateShader' in 'OpenGL32.dll

I am getting the error "Unable to find an entry point named 'glCreateShader' in DLL 'opengl32.dll'." Does anyone know what could be causing these errors? Here is the class that is causing the error
class PixelBlocks
{
private static ShaderProgram program;
public static void generateBlock(ref objStructs.Block Block)
{
Texture blockTex = Block.Texture;
VBO<Vector3> square;
VBO<int> elements;
float Scale = clientInfo.curScale;
Matrix4 trans;
Matrix4 SclFct;
program = new ShaderProgram(VertexShader, FragmentShader);
program.Use();
program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)Program.width / Program.height, 0.1f, 1000f));
program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, Vector3.Up));
program["light_direction"].SetValue(new Vector3(0, 0, 1));
program["enable_lighting"].SetValue(Program.lighting);
square = new VBO<Vector3>(new Vector3[] {
new Vector3(-1, 1, 0),
new Vector3(1, 1, 0),
new Vector3(1, -1, 0),
new Vector3(-1, -1, 0) });
elements = new VBO<int>(new int[] { 0, 1, 2, 3 }, BufferTarget.ElementArrayBuffer);
trans = Matrix4.CreateTranslation(new Vector3(Block.Blk.x, Block.Blk.y, 0));
SclFct = Matrix4.CreateScaling(new Vector3(Scale, Scale, 0f));
Block.corners = square;
Block.elements = elements;
Block.trans = trans;
Block.Scale = SclFct;
}
public static bool drawBlocks(objStructs.Block[] Blocks)
{
for(int i = 0; i < Blocks.Length; i++)
{
try
{
Gl.UseProgram(program);
// set up the model matrix and draw the cube
program["model_matrix"].SetValue(Blocks[i].trans * Blocks[i].Scale);
Gl.BindBufferToShaderAttribute(Blocks[i].corners, program, "vertexPosition");
Gl.BindBuffer(Blocks[i].elements);
#pragma warning disable CS0618 // Type or member is obsolete
Gl.DrawElements(BeginMode.Quads, Blocks[i].elements.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
#pragma warning restore CS0618 // Type or member is obsolete
}
catch(Exception e)
{
Console.WriteLine(e);
return false;
}
}
return true;
}
public static string VertexShader = #"
#version 130
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexUV;
out vec3 normal;
out vec2 uv;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(void)
{
normal = normalize((model_matrix * vec4(floor(vertexNormal), 0)).xyz);
uv = vertexUV;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";
public static string FragmentShader = #"
#version 130
uniform sampler2D texture;
uniform vec3 light_direction;
uniform bool enable_lighting;
in vec3 normal;
in vec2 uv;
out vec4 fragment;
void main(void)
{
float diffuse = max(dot(normal, light_direction), 0);
float ambient = 0.3;
float lighting = (enable_lighting ? max(diffuse, ambient) : 1);
fragment = lighting * texture2D(texture, uv);
}
";
}
I know that's a lot of code but I don't what is causing this error.
I am using this library: https://github.com/giawa/opengl4csharp which is why it's not like any other questions
Graphics: Intel Iris Pro Graphics Experimental Version and Recommended Version both Tried
Processor: Intel i5
IDE: Visual Studio 2015 Community

Beginner troubles with 2D projection and textures in OpenGL

Lately I have been trying to learn/use OpenGL 3+. I have looked through tutorials and examples but I've run into a wall trying to get textures and 2D projection to work without problems.
The goal for now is to have a function which can draw a textured quad to the screen with it's position specified by pixels (not [-1,1]).
For readability and testing I made a new barebones program with the knowledge I currently have, and it exhibits nearly the same problems. Help would be appreciated since i'm starting to go bald over this :(..
The current code shows a garbled texture instead of the image itself (texture is 128x128px).
[Program.cs]
namespace OpenGLTester
{
static class Program
{
public static GameWindow window;
public static String programDirectory = Directory.GetCurrentDirectory();
public static int testTexture;
public static int uniform_fragment_texture;
public static int shaderProgram;
[STAThread]
static void Main()
{
window = new GameWindow(1024, 768, new GraphicsMode(new ColorFormat(8, 8, 8, 8), 0, 8), "OpenGLTester", GameWindowFlags.Default, DisplayDevice.Default, 3, 1, GraphicsContextFlags.Default);
GL.Viewport(new Size(1024,768));
shaderProgram = GL.CreateProgram();
int vertexShader = GL.CreateShader(ShaderType.VertexShader);
int fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(vertexShader, File.ReadAllText(programDirectory + #"\vertex.vert"));
GL.ShaderSource(fragmentShader, File.ReadAllText(programDirectory + #"\fragment.frag"));
GL.CompileShader(vertexShader);
GL.CompileShader(fragmentShader);
GL.AttachShader(shaderProgram, vertexShader);
GL.AttachShader(shaderProgram, fragmentShader);
GL.LinkProgram(shaderProgram);
if (GL.GetError() != ErrorCode.NoError) { System.Diagnostics.Debugger.Break(); }
Console.WriteLine(GL.GetProgramInfoLog(shaderProgram));
GL.UseProgram(shaderProgram);
Matrix4 projectionMatrix = Matrix4.CreateOrthographic(1024, 768, 0, 1);
GL.UniformMatrix4(GL.GetUniformLocation(shaderProgram, "vertex_projection"), false, ref projectionMatrix);
uniform_fragment_texture = GL.GetUniformLocation(shaderProgram, "fragment_texture");
testTexture = loadTexture(programDirectory + #"\test.png");
GL.Disable(EnableCap.DepthTest);
GL.Disable(EnableCap.Lighting);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
window.UpdateFrame += window_UpdateFrame;
window.RenderFrame += window_RenderFrame;
window.Resize += window_Resize;
window.TargetRenderFrequency = 60;
window.Run();
}
static void window_Resize(object sender, EventArgs e)
{
//Don't allow resizing for now.
window.Size = new Size(1024, 768);
}
static void window_UpdateFrame(object sender, FrameEventArgs e)
{
ErrorCode currentError = GL.GetError();
if (currentError != ErrorCode.NoError)
{
Console.WriteLine(Enum.GetName(typeof(ErrorCode), currentError));
System.Diagnostics.Debugger.Break();
}
}
static void window_RenderFrame(object sender, FrameEventArgs e)
{
GL.ClearColor(0, 0, 0, 0);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.StencilBufferBit);
//test texture is 128x128pixels.
drawTexRect(100, 228, 100, 228, testTexture);
window.SwapBuffers();
}
static int loadTexture(String filePath)
{
GL.Enable(EnableCap.Texture2D);
int id = GL.GenTexture();
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, id);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
Bitmap bmp = new Bitmap(filePath);
BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, bmp_data.Scan0);
bmp.UnlockBits(bmp_data);
bmp.Dispose();
return id;
}
static void drawTexRect(float top, float bottom, float left, float right, int texture)
{
//topLeft,bottomLeft,bottomRight,topRight
float[] vertices = new float[] {
left, top, 0, 0,
left, bottom, 0, 1,
right, bottom, 1, 1,
right, top, 1, 0,
};
int buffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
GL.BufferData<float>(BufferTarget.ArrayBuffer, new IntPtr(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
//vec2 - screen position
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4, 0);
//vec2 - texture coordinates
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4, 2 * sizeof(float));
GL.Enable(EnableCap.Texture2D);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, texture);
GL.Uniform1(uniform_fragment_texture, 0);
GL.DrawArrays(PrimitiveType.Quads, 0, 4);
GL.DeleteBuffer(buffer);
}
}
}
[vertex.vert]
#version 330
in vec2 vertex_position;
in vec2 vertex_texturePosition;
uniform mat4 vertex_projection;
out vec2 fragment_texturePosition;
void main()
{
gl_Position = vec4(vertex_position,0.0,1.0) * vertex_projection;
fragment_texturePosition = vertex_texturePosition;
}
[fragment.frag]
#version 330
in vec2 fragment_texturePosition;
uniform sampler2D fragment_texture;
out vec4 output_color;
void main()
{
output_color = texture(fragment_texture,fragment_texturePosition);
}
After changes suggested by #j-p one problem remains:
After texture position change suggested by #j-p:
The projection is also wrong given the position i expect it to be 100 px from the left and 100 px from the top, don't see how i can fix this..
The stride parameter is in byte:
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * sizeof(float), 0);
//vec2 - texture coordinates
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * sizeof(float), 2 * sizeof(float));
Also,the corresponding opengl pixel format for windows argb bitmap is BGRA. (link)
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,**OpenTK.Graphics.OpenGL.PixelFormat.Bgra**, PixelType.UnsignedByte, data.Scan0);
And finally, your texture coordinates should be adjusted as follow:
float[] vertices = new float[] {
left, top, 0, 1,
left, bottom, 0, 0,
right, bottom, 1, 0,
right, top, 1, 1
};

OpenTK basic triangle not drawing as it should

I am trying to draw the triangle with the colours and verticies specified but currently it seems like its picking some colour numbers for the positions and is not doing what its supposed to do
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
namespace newTriangle
{
class Program
{
static void Main(string[] args)
{
MyWindow myWindow = new MyWindow();
myWindow.Run();
}
}
class MyWindow : GameWindow
{
private uint[] vertexBufferObjectIDs = new uint[2];
private int vertexArrayID, vertexShaderID, fragmentShaderID, shaderProgramID;
public MyWindow()
: base(800, // Width
600, // Height
GraphicsMode.Default,
"My OpenTK Window",
GameWindowFlags.Default,
DisplayDevice.Default,
3, // major
0, // minor
GraphicsContextFlags.ForwardCompatible) { }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
GL.ClearColor(Color4.CornflowerBlue);
GL.GenVertexArrays(1, out vertexArrayID);
GL.BindVertexArray(vertexArrayID);
ushort[] indices = new ushort[] { 0, 1, 2 };
float[] vertices = new float[] {-1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.0f, -1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 0.0f, 1.0f };
GL.GenBuffers(vertexBufferObjectIDs.Length, vertexBufferObjectIDs);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjectIDs[0]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, vertexBufferObjectIDs[1]);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(ushort)), indices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, true, 5 * sizeof(float), 0);
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, 5 * sizeof(float), 2 * sizeof(float));
GL.EnableVertexAttribArray(1);
vertexShaderID = GL.CreateShader(ShaderType.VertexShader);
string vertShaderText =
#"
#version 150
in vec3 position;
in vec3 colour;
out vec3 Colour;
void main()
{
Colour = colour;
gl_Position = vec4(position, 1) ;
}";
GL.ShaderSource(vertexShaderID, vertShaderText);
GL.CompileShader(vertexShaderID);
fragmentShaderID = GL.CreateShader(ShaderType.FragmentShader);
string fragShaderText =
#"
#version 150
in vec3 Colour;
out vec4 outputF;
void main()
{
outputF = vec4(Colour, 1.0);
}";
GL.ShaderSource(fragmentShaderID, fragShaderText);
GL.CompileShader(fragmentShaderID);
shaderProgramID = GL.CreateProgram();
GL.AttachShader(shaderProgramID, fragmentShaderID);
GL.AttachShader(shaderProgramID, vertexShaderID);
GL.LinkProgram(shaderProgramID);
GL.UseProgram(shaderProgramID);
}
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
GL.DeleteBuffers(vertexBufferObjectIDs.Length, vertexBufferObjectIDs);
GL.DeleteVertexArrays(1, ref vertexArrayID);
GL.UseProgram(0); GL.DetachShader(shaderProgramID, vertexShaderID);
GL.DetachShader(shaderProgramID, fragmentShaderID);
GL.DeleteShader(fragmentShaderID);
GL.DeleteShader(vertexShaderID);
GL.DeleteProgram(shaderProgramID);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.DrawElements(BeginMode.Triangles, 3, DrawElementsType.UnsignedShort, IntPtr.Zero);
this.SwapBuffers();
}
}
}
can anyone see my mistake?
You didn't link up the locations of the attributes. You can fix it by using the appropriate calls to BindAttribLocation​, or use layout qualifiers with locations. Also, position is a vec3 but you give it only 2 floats.
Using layout qualifiers is an easy fix:
layout(location = 0) in vec2 position;
layout(location = 1) in vec3 colour;
That gives me this picture: http://i.imgur.com/H9FEXZ0.png which looks like it's probably what you had in mind.
vec4(position, 1)
In GLSL integers are not automatically type-promoted.
Kinda weird, because you got it right in your fragment shader.
Try this:
vec4(position, 1.0)

Categories

Resources