Click here to Skip to main content
12,761,780 members (41,090 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

2K views
2 bookmarked
Posted 26 Jan 2017

OpenGL 4 with OpenTK in C# Part 3: Passing Data to Shaders

, 27 Jan 2017 CPOL
Rate this:
Please Sign up or sign in to vote.
In this post, we will look at passing data from your application code to the shaders using OpenTK.

In this post, we will look at passing data from your application code to the shaders using OpenTK.

This is part 3 of my series on OpenGL4 with OpenTK.

For other posts in this series:

OpenGL 4 with OpenTK in C# Part 1: Initialize the GameWindow

OpenGL 4 with OpenTK in C# Part 2: Compiling shaders and linking them

OpenGL 4 with OpenTK in C# Part 3: Passing data to shaders

OpenGL 4 with OpenTK in C# Part 4: Refactoring and adding error handling

OpenGL 4 with OpenTK in C# Part 5: Buffers and Triangle

As stated in the previous post, I am in no way an expert in OpenGL. I write these posts as a way to learn, basically by reading up on examples in a book (OpenGL SuperBible, Seventh Edition) and then converting them to OpenTK and perhaps tweaking them a little to fit better to these posts. I really recommend the book if you want to know how it actually works and why things are done. :)

This part will build upon the game window and shaders from the previous post.

Defining in Parameters to our Vertex Shader

For starters, a reminder of our OnRenderFrame method from the previous posts. Added _time to hold total time elapsed as OpenTK seems to be giving the delta time only in the FrameEventArgs.

private double _time;
protected override void OnRenderFrame(FrameEventArgs e)
{
    _time += e.Time;
    Title = $"{_title}: (Vsync: {VSync}) FPS: {1f / e.Time:0}";
    Color4 backColor;
    backColor.A = 1.0f;
    backColor.R = 0.1f;
    backColor.G = 0.1f;
    backColor.B = 0.3f;
    GL.ClearColor(backColor);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    GL.UseProgram(_program);

    // add shader attributes here

    GL.DrawArrays(PrimitiveType.Points, 0, 1);
    GL.PointSize(10);
    SwapBuffers();
}

Float Parameter

So, let's modify our vertex shader to take a parameter, time in this case and calculate a color and forward it to the fragment shader, i.e., out parameter of vertex shader matches the in parameter of fragment shader.

Vertex Shader

#version 440 core

layout (location = 0) in float time;
out vec4 frag_color;

void main(void)
{
 gl_Position = vec4( 0.25, -0.25,  0.5,  1.0);
 frag_color = vec4(sin(time) * 0.5 + 0.5, cos(time) * 0.5 + 0.5, 0.0, 0.0);
}

Fragment Shader

#version 440 core

in vec4 frag_color;
out vec4 color;

void main(void)
{
 color = frag_color;
}

And in our OnRenderFrame, we add the following to pass along our float time to the shader.

// add shader attributes here
GL.VertexAttrib1(0, _time);

This should result in the vertex blending in color over time. The key here is that the first parameter of GL.VertexAttrib1 should match the location definition in our shader.

Vector4 Parameter

Vertex Shader

Here, we add a new in attribute, position that is a vec4. And we just set the gl_Position to whatever value is supplied by our game code.

#version 440 core

layout (location = 0) in float time;
layout (location = 1) in vec4 position;
out vec4 frag_color;

void main(void)
{
 gl_Position = position;
 frag_color = vec4(sin(time) * 0.5 + 0.5, cos(time) * 0.5 + 0.5, 0.0, 0.0);
}

And in our OnRenderFrame, we add the following:

Vector4 position;
position.X = (float)Math.Sin(_time) * 0.5f;
position.Y = (float)Math.Cos(_time) * 0.5f;
position.Z = 0.0f;
position.W = 1.0f;
GL.VertexAttrib4(1, position);

See that the location definition and the first parameter of the GL.VertexAttrib4 match.

This should give an output similar to the picture below (or watch at https://youtu.be/na_96BMN-EA). The dot should be moving on an elliptical path around the center of the window and it should still be changing colors as it moves.

There are a lot of overload versions for the GL.VertexAttrib function. I guess so that we can pass through all that we could possibly need. Just look around and see what overload to use that matches your needs. Head over to the OpenGL API documentation for a full list, and check your Intellisense to figure out what OpenTK overload to use.

Hope this helps someone out there. :)

Thanks for reading. Here's another GIF of 2 of our cats fighting to lighten up your day. (Full video at: https://youtu.be/xkXfk-gV2Vw)

Until next time: Work to Live, Don’t Live to Work

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Eowind
Architect
Sweden Sweden
http://dreamstatecoding.blogspot.com

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionPassing data Pin
Nedeljko Šovljanski3-Feb-17 3:23
memberNedeljko Šovljanski3-Feb-17 3:23 
AnswerRe: Passing data Pin
Eowind3-Feb-17 11:57
memberEowind3-Feb-17 11:57 
GeneralRe: Passing data Pin
Nedeljko Šovljanski3-Feb-17 19:40
memberNedeljko Šovljanski3-Feb-17 19:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170217.1 | Last Updated 27 Jan 2017
Article Copyright 2017 by Eowind
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid