PDA

View Full Version : How does one interpolate opengl colors yourself?



tomb18
01-10-2017, 06:33 PM
I know that openGl will interpolate colors assuming the fragment shader is set correctly, between two vertices given two starting colors. It does this automatically.
But what if you want to do this yourself?
For example, I want all vertices at -0.5 to be colored as 0,0,0.8f (i.e. blue) and all vertices at 0.0 to be colored 0,0.8f,0 (i.e. green) and those at +0.5 to be colored 0.8f,0,0 (i.e. red). I know if I draw a line for example from <0,-0.5, 0> to <0,0,0> it will be color interpolated between blue and green with nice shades in between.
But, what if I have a line from <0,-0.5 , 0> to <0, -.25, 0>? The final color would have to be set to a color that is some mix of blue and green. Is there a way to do this?
I realize, that perhaps it can't be done as smoothly as opengl, I may have to pick a range such as one color at< 0, -0.4,0> and then another at <0,-0.3,0> etc.
Is there a way?
Thanks, Tom

tomb18
01-10-2017, 11:10 PM
I did find a reference to interpolating colors. Seems you have to convert to HSL values, interpolate and then go back to RGB. I used an online calculator.
So since I need colors for about 200,000 verticies all of which can be different in real time I hard coded ranges of colors as follows:



if (height < 0.1)
{
colorVertex.X = 0.0f;
colorVertex.Y = 0.0f;
colorVertex.Z = 0.08f;

return colorVertex;
}

if (height < 0.2)
etc.....


The problem is that for 200,000 vertices this takes about 18ms. Yikes! i can create a triangle strip with 200,000 vertices and 500,000 or so indices in under 3 ms.
There has to be a better way!
Any suggestions? Is there anything in a fragment shader that will assign colors based on the Y value?
Thanks

Silence
01-10-2017, 11:49 PM
I am not really sure, but you might be interested in this (http://www.mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=24). This is a more common way to render such kind of terrain-like meshes.

If you want to stay with your way, I would suggest you to find a function that will replace all your if and else conditions. Maybe something like:



color.z = height*0.8 + (height-0.2)*0.3 + ...;

GClements
01-11-2017, 02:41 AM
I know that openGl will interpolate colors assuming the fragment shader is set correctly, between two vertices given two starting colors. It does this automatically.

More precisely, any fragment shader input variables which aren't (implicitly or explicitly) "flat"-qualified are obtained by interpolating the corresponding output variables from the vertex/geometry/tessellation shader.



But what if you want to do this yourself?

If you want to perform your own interpolation, the most general) approach is to add a variable for barycentric coordinates.



For example, I want all vertices at -0.5 to be colored as 0,0,0.8f (i.e. blue) and all vertices at 0.0 to be colored 0,0.8f,0 (i.e. green) and those at +0.5 to be colored 0.8f,0,0 (i.e. red).

Bear in mind that, by default, interpolation is performed in clip space (affine to eye space). If you want to interpolate in NDC (affine to screen space), you need to use the "noperspective" qualifier.

If you aren't using a perspective projection (i.e. all vertices' clip coordinates have the same value for the W component), there is no difference between interpolating in clip space and NDC.

tomb18
01-11-2017, 10:15 AM
Both interesting answers.
However, now I am not sure that this will be an issue...
When I initially did the timing tests I got an average of 18ms. However, now that all the code is in place, I find that the OnRender callback where I set vertices for 200,000 vertices and then color all of them takes only 2 ms. This is plenty good enough. I guess this might have been an artifact of the testing. Nonetheless, it always pays to make the code as good as possible so thanks for these hints.

tomb18
01-11-2017, 04:06 PM
I have managed to get things to work with an equation for the colors. However, I believe my approach is not valid overall. One thing that happens is that that if I color a peak whose vector starts at -1 and goes to 1, the color assigned will be blue to red in my setup. However that is not what I want. The midpoint should be green.
Here is an example of what I am trying to do.
https://www.youtube.com/watch?v=hiflzRL7sUY
I have everything working except for the color. How does one do this? Any hints?
Thanks

tomb18
01-11-2017, 08:49 PM
Ok, so this is a beginners forum....I'm a beginner! I just read about textures in particular 1D and 2D.
I understand how to apply a 2D texture to a quad for example. But I have triangle vertices that were generated in a X,Z grid programatically (left to right, then the next row etc) and then I have indices to tell the drawing sequence.. I then draw this with glDrawElements, triangleStrip etc.
Now I understand that I need to provide UV vectors which in this case should be just each vertex all with the Y value. For example if I have a vertex at 0,0.5,0 then the UV should be 0.5,0.5,0.5. Am I correct? It would then pick up the texture color at u = 0.5. Am I doing this correctly?
Also how does one make a 1D texture out of my jpg, which is just a gradient of colors? Or can I actually use a 2D texture in this case?
Thanks

Silence
01-11-2017, 11:46 PM
I have managed to get things to work with an equation for the colors. However, I believe my approach is not valid overall. One thing that happens is that that if I color a peak whose vector starts at -1 and goes to 1, the color assigned will be blue to red in my setup. However that is not what I want. The midpoint should be green.
Here is an example of what I am trying to do.
https://www.youtube.com/watch?v=hiflzRL7sUY
I have everything working except for the color. How does one do this? Any hints?
Thanks

Well. Hard to tell. Color gradients (https://en.wikipedia.org/wiki/Color_gradient) might be what you're looking for.

Silence
01-11-2017, 11:49 PM
Ok, so this is a beginners forum....I'm a beginner! I just read about textures in particular 1D and 2D.
I understand how to apply a 2D texture to a quad for example. But I have triangle vertices that were generated in a X,Z grid programatically (left to right, then the next row etc) and then I have indices to tell the drawing sequence.. I then draw this with glDrawElements, triangleStrip etc.
Now I understand that I need to provide UV vectors which in this case should be just each vertex all with the Y value. For example if I have a vertex at 0,0.5,0 then the UV should be 0.5,0.5,0.5. Am I correct? It would then pick up the texture color at u = 0.5. Am I doing this correctly?
Also how does one make a 1D texture out of my jpg, which is just a gradient of colors? Or can I actually use a 2D texture in this case?
Thanks

If I understood your post correctly, the color will change according to the height, and not the "plane location". In that case you might use a simple 1D texture (depicting gradient colors), and in your fragment shader just get the color from your texture according to the height, so no need to deal with texture coordinates (as a vertex attribute meaning) at all. You'll certainly have to normalize the height between [0..1].

john_connor
01-12-2017, 02:50 AM
Here is an example of what I am trying to do.
https://www.youtube.com/watch?v=hiflzRL7sUY

what you want is a functionality to get a vec4 (RGBA) out of a float (height value, normalized), you can use a pre-calculated color texture:

unsigned char mytexturedata[] = {
0x00, 0xFF, 0x00, 0xFF, // green
0xFF, 0xFF, 0x00, 0xFF, // yellow
0xFF, 0x00, 0x00, 0xFF, // red
};

mytexturedata[0] = green, that means if you sample from the 1D texture with "float u = 0.0f;" you'll get green
mytexturedata[max = 2] = red, that means if you sample from the 1D texture with "float u = 1.0f;" you'll get red

these are the boundaries

if you sample from the 1D texture with "float u = 0.5f;" you'll get yellow

but what if you sample from the 1D texture with "float u = 0.249999f;" ??
that depends on what "texture parameters" or "sampler parameters" you've set for your texture
the parameter responsible for that is GL_TEXTURE_WRAP_S:
-- setting it to GL_NEAREST will give you exactly green, because green is the nearest texel to your texture coordinate
-- setting it to GL_LINEAR will give you a linear interpolation between green and yellow (thats what you want)

but what if you sample from the 1D texture with "float u = -5.2f;" or "float u = +5.2f;" ?? (in other words: out of scope [0;1])
that depends on what "texture parameters" or "sampler parameters" you've set for your texture
the parameter responsible for that is (i think) GL_TEXTURE_MIN_FILTER: (or ..MAG_FILTER ?)
however, setting it to GL_CLAMP_TO_EDGE will give you either green or red, depending on what border texel it next to the coordinate, setting it to GL_REPEAT will give you the same as if you'd have selected float u = +/-0.2f

https://www.khronos.org/opengl/wiki/Texture

example 1D texture:
http://alfonse.bitbucket.org/oldtut/Texturing/Tutorial%2014.html
you'd have to use "GL_RGBA8" as internal format instead if "GL_R8"

tomb18
01-12-2017, 06:59 AM
Great! This should be everything I need. Off to work!

tomb18
01-12-2017, 09:53 AM
@Silence, @John,
I'm having no success here.
So the first question is do you I need to supply texture coordinates? If so what format are they in?
What I have is vertices (Vector3) for the triangle strip where z and z are regularly spaced and a Y value that varies.

This is what I have for the shaders:


#region Shaders
public static string VertexShader = @"
#version 130
in vec3 vertexPosition;
in vec4 myTextureData;
out vec4 myTextureData;

uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(void)
{
myTextureData = myTextureData;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";

public static string FragmentShader = @"
#version 130
uniform sampler1D texture;
in vec4 myTextureData;

out vec4 fragment;
void main(void)
{
fragment = texture1D(texture, myTextureData);
}
";

and the texture is:


//here is the texture for the spectrum

myTextureData[0].X = 0x00; //blue
myTextureData[0].Y = 0x00;
myTextureData[0].Z = 0xFF;
myTextureData[0].W = 0xFF;

myTextureData[0].X = 0xFF; //yellow
myTextureData[0].Y = 0xFF;
myTextureData[0].Z = 0x00;
myTextureData[0].W = 0xFF;

myTextureData[0].X = 0xFF; //red
myTextureData[0].Y = 0x00;
myTextureData[0].Z = 0x00;
myTextureData[0].W = 0xFF;

I'm sure the error is in the fragment shader..

john_connor
01-12-2017, 01:13 PM
I'm sure the error is in the fragment shader..

its in the vertex shader ^^


#version 130
in vec3 vertexPosition;
in vec4 myTextureData;
out vec4 myTextureData;


ou cannot have 2 variables with he same name

by the way, shader error checking works like this
https://www.khronos.org/opengl/wiki/Shader_Compilation#Example

and your indices where you setup the texturedata are also wrong

sending a vec4 to the vertexshader makes so sense, i personally would do it like tis:
-- send 2 uniform float to the vertexshader: "lowerlimit" and "upperlimit"
-- calculate the relation of your vertex-z-value to those limits
-- send the relation to the fragmentshader
in the fragmentshader:
-- use the relation (a float) to sample from your 1D texture


#version 450 core

in layout (location = 0) vec3 vertexposition;

uniform mat4 MVP = mat4(1);

uniform float upperlimit = 10.0f;
uniform float lowerlimit = -10.0f;

out float texcoord;

void main()
{
gl_Position = MVP * vec4(vertexposition, 1);

// calculate the texture coordinate
texcoord = (vertexposition.z - lowerlimit) / (upperlimit - lowerlimit);
}




#version 450 core

in float texcoord;

layout (binding = 3) uniform sampler1D tex1;

out layout (location = 0) vec4 fragmentcolor;

void main()
{
fragmentcolor = texture(tex1, texcoord);
}



note: i explicitly set the texture unit to 3 in the shader code, that means you have to bind your 1Dtexture to that unit like this:

glActiveTexture(GL_TEXTURE0 + 3);
glBindTexture(GL_TEXTURE_1D, mytexture);

tomb18
01-12-2017, 08:46 PM
Hi
Ok now i'm totally confused. In a previous message you mentioned a 1d texture as


unsigned char mytexturedata[] = {
0x00, 0xFF, 0x00, 0xFF, // green
0xFF, 0xFF, 0x00, 0xFF, // yellow
0xFF, 0x00, 0x00, 0xFF, // red
};



and then mentioned that a mytexture[2] would give red.???
As far as I can see an index into that array gives 0 at [2]. So I assumed you missed something there. So I looked on the web and saw a number of references to setting up a [3,3] array to do this. So I assumed that a vector 4 would work. I guess not. So what is the right way to do this? If a multi-dimensional array is wrong what's right for a 1d texture?

The next thing is you mention that I should calculate my "vertex z" values? Did you mean Y values? I'm plotting a surface grid with vertices placed at x and z in x-z plane and the height at that point is given by Y not Z.
Also everything I send is between 0 and 1. Everything, vertices and all. So what is the -10 and + 10?
So at this point I'm totally confused.

john_connor
01-13-2017, 02:29 AM
Ok now i'm totally confused. In a previous message you mentioned a 1d texture as


unsigned char mytexturedata[] = {
0x00, 0xFF, 0x00, 0xFF, // green
0xFF, 0xFF, 0x00, 0xFF, // yellow
0xFF, 0x00, 0x00, 0xFF, // red
};




oops! you're right!
what i means is something like that:


struct Texel { unsigned char r, g, b, a; };

Texel mytexturedata[] = {
{0x00, 0xFF, 0x00, 0xFF}, // green
{0xFF, 0xFF, 0x00, 0xFF}, // yellow
{0xFF, 0x00, 0x00, 0xFF}, // red
};




The next thing is you mention that I should calculate my "vertex z" values? Did you mean Y values? I'm plotting a surface grid with vertices placed at x and z in x-z plane and the height at that point is given by Y not Z.
Also everything I send is between 0 and 1. Everything, vertices and all. So what is the -10 and + 10?
So at this point I'm totally confused.

depends on your coordinate system, you're right
these min/max values are the limits of your "y-values" (!), the range in which they all are, if your range is [0;1] for all y-coordinate, then its all fine, just pass the y-value as "texcoord"

texcoord = (vertexposition.z - lowerlimit) / (upperlimit - lowerlimit);
... is just a more general description of the same, lets say your vertices y-coordinate are all in the range of [-5;+20], then you'd have to set the uniform values to -5 / +20, you can set / override uniform values from your application:

GLint location = glGetUniformLocation(program, "lowerlimit");
gl [Program] Uniform1f(location, -5.0f);

location = glGetUniformLocation(program, "upperlimit");
gl [Program] Uniform1f(location, +20.0f);

https://www.opengl.org/sdk/docs/man/html/glProgramUniform.xhtml
https://www.opengl.org/sdk/docs/man/html/glUniform.xhtml

Silence
01-13-2017, 03:58 AM
[QUOTE=tomb18;1285440]

public static string FragmentShader = @"
#version 130
uniform sampler1D texture;
in vec4 myTextureData;

out vec4 fragment;
void main(void)
{
fragment = texture1D(texture, myTextureData);
}
";


texture1D expects the texture coordinate as the second argument. So just give it the current height which should be given as a varying by the vertex shader (then a simple float should suffice).

tomb18
01-13-2017, 10:53 AM
I've spent the last 5 hours on this with no luck at all. There are no basic tutorials anywhere on how to do this. So this is what I have at the moment. It's everything related to the texture. Texel is just a class that replaces the C++ struc


byte[] data = new byte[]
{
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255
};

Gl.Enable(EnableCap.Texture1D);
Gl.PixelStorei(PixelStoreParameter.UnpackAlignment , 1);

// Create a texture name
var textureID = Gl.GenTexture();

IntPtr myTexturePtr = Marshal.AllocHGlobal(data.Length);
Marshal.Copy(data, 0, myTexturePtr, data.Length);

Gl.BindTexture(TextureTarget.Texture1D, textureID);

Gl.TexParameteri(TextureTarget.Texture1D, TextureParameterName.TextureWrapS, TextureParameter.Repeat);
Gl.TexParameteri(TextureTarget.Texture1D, TextureParameterName.TextureWrapT, TextureParameter.Repeat);

Gl.TexParameteri(TextureTarget.Texture1D, TextureParameterName.TextureMinFilter, TextureParameter.Linear);
Gl.TexParameteri(TextureTarget.Texture1D, TextureParameterName.TextureMagFilter, TextureParameter.Linear);
Gl.TexImage1D(TextureTarget.Texture1D, 0, PixelInternalFormat.Three, 3, 0, PixelFormat.Rgb, PixelType.UnsignedByte, myTexturePtr);

//texture
plottingProgram.Use();

Gl.Uniform1i(3, 0);
Gl.ActiveTexture(TextureUnit.Texture0);
Gl.BindTexture(TextureTarget.Texture1D, textureID);

uint samplerLocation = Gl.GetUniformLocation(plottingProgram, "ColorRamp");
Gl.Uniform1i(samplerLocation, 0);
Gl.ActiveTexture(TextureUnit.Texture0);
Gl.BindTexture(TextureTarget.Texture1D, textureID);



The vertex shader


public static string VertexShader = @"
#version 130
in vec3 vertexPosition;
out float height;

uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(void)
{
height = vertexPosition.y;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";

and the fragment shader



public static string FragmentShader = @"
#version 130
layout (binding = 3) uniform sampler1D colorRamp;
in float height;

out vec4 fragment;
void main(void)
{
fragment = texture(colorRamp, height);
}
";

I'm finding it real difficult to find ANY info on the code used in the fragment and vertex shaders.
I'm a total beginner at this, so when you don't find a tutorial it's really difficult.

GClements
01-13-2017, 10:51 PM
in vec3 vertexPosition;

height = position.y;


This shouldn't even compile, as you don't have a variable named "position".

Ensure that you're checking for compilation and linking errors: glGetShader(GL_COMPILE_STATUS) and glGetProgram(GL_LINK_STATUS) for the status, glGetShaderInfoLog() and glGetProgramInfoLog() for the messages.

john_connor
01-14-2017, 07:45 AM
I'm finding it real difficult to find ANY info on the code used in the fragment and vertex shaders.
I'm a total beginner at this, so when you don't find a tutorial it's really difficult.

maybe you find this example useful
https://sites.google.com/site/john87connor/texture-object/1-2-texture-1d

tomb18
01-14-2017, 08:07 AM
Hi I updated the program above with an example I found for c#. However, the last couple of lines gives an error in this line that the parameters are incorrect.

uint samplerLocation = Gl.GetUniformLocation(plottingProgram, "colorRamp");

Anyways, I will check out your example. Nice and clear.
Thanks

tomb18
01-14-2017, 08:33 AM
It seems that my code is messing up a different texture I have for text in my application. Can you use more than one texture in an application?
However, my starting point now will be getting you 1d texture working is c#. That will be a good starting point.

tomb18
01-14-2017, 09:30 AM
Well I was trying out the 1d texture example and just ran into this:

Unsupported GLSL type layout when I attempt to create the shader programs.

Otherwise everything was OK to this point!

tomb18
01-14-2017, 10:11 AM
I have the latest opengl drivers for the intel HD4000 on Windows. Version 4.3 as determined by glGetString....

john_connor
01-14-2017, 10:47 AM
post the shader source code, otherwise we can only guess the error

tomb18
01-14-2017, 01:56 PM
It is identical to what you posted. Here it is:


public static string VertexShader = @"
#version 450 core\n

in layout (location = 0) vec3 in_position;
in layout (location = 1) float in_texcoord;
out float texcoord;
void main () {
gl_Position = vec4(in_position, 1);
texcoord = in_texcoord;
}
}";

public static string FragmentShader = @"
#version 450 core\n
in float texcoord;
uniform layout (binding = 3) sampler1D tex1;
out layout (location = 0) vec4 out_color;
void main () {
out_color = texture(tex1, texcoord);
}
}";

So close....I also tried changing the version to 430 - no difference.

tomb18
01-14-2017, 08:17 PM
Hi,
Well I've spent at least 20 hours on this, trying various examples from the web and yours and I have had no luck. The closest I got is using your example except for the error on creating the program. If I comment out the in layout (location) lines it will compile otherwise not.
So if you can suggest something for this I'm all ears. I'm not sure if it's something messed up in the libraries I use or not and the developer of the libraries is not available.

However, I do have a 2D texture working the way I want. It colors the peaks in the 3d spectrum correctly. The only issue is that I have to send the texture coordinates for the color. Now this means I have to send all the coordinates over and there are about 200,000 every few milliseconds. It works fine, but this is very inefficient. It does have one advantage, in that I can change the colors of the graph by just supply a bitmap.
I am wondering however, if this is really necessary. The vertex shader gets a vector3 that has my vertices for the graph anyways. The vertexCoordinate.y value is all I need to plot the data since the x and z coordinate are always the same. Can I not just pass this to the fragment shader without sending all the vector2 coordinates over?

So here is a snippet of the code.


Gl.UseProgram(plottingProgram);
Gl.BindTexture(myTexture); //this is the 2D texture

plottingProgram["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));

UpdateSpectrum();

spectrumVBO.BufferSubData(vertexBuffer); //vertexBuffer is an array with x,y,z data. x, is always the same
myUV.BufferSubData(colorBuffer); //colorBuffer is a vector2 with x always the same and y the same as vertexBuffer.y values

Gl.BindBufferToShaderAttribute(spectrumVBO, plottingProgram, "vertexPosition");
Gl.BindBufferToShaderAttribute(myUV, plottingProgram, "vertexUV");

Gl.BindBuffer(spectrumIndicesVBO);
Gl.DrawElements(BeginMode.TriangleStrip, spectrumIndicesVBO.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);



And here are the vertex and fragment shaders


public static string VertexShader = @"
#version 130
in vec3 vertexPosition;
in vec2 vertexUV;
out vec2 uv;


uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(void)
{
uv = vertexUV;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);

}
";

public static string FragmentShader = @"
#version 130

uniform sampler2D texture;
in vec2 uv;

out vec4 fragment;

void main(void)
{
fragment = texture2D(texture,uv);
}
";

So is it possible to not send the vec2 which contains the texture coordinates and instead just send something from the vertex shader to the fragment shader? I could even get the coordinates as vertexPosition.x and vertexPosition.y. I tried a bunch of things and it didn't work.
Thanks a bunch for your help..

Silence
01-15-2017, 06:32 AM
#version 450 core




I also tried changing the version to 430 - no difference.




#version 130


Why so many different versions ? At some starting point, supporting a single version is the way to do.

What OpenGL version are you running ? I'm not totally sure but I have doubts that intel HD 4000 could run OpenGL 4.5 (at least on a machine I have, I'm stuck with OpenGL 3.3, but that's true, under Linux).

Last thing, do things simply. Start again with a simple program, make it run, and then insert it into your bigger project.

tomb18
01-15-2017, 11:32 AM
Hi,
Still learning. I thought that the version was specific to one version and was just trying the code provided.
I did start simple, just trying what John provided but the shaders would not compile and the error message was "Unsupported GLSL type layout". There is NO reference to this error anywhere. Sigh....
Anyhow look at my next answer. I solved my requirements with a 2D texture with no need to send texture coordinates from my application.

tomb18
01-15-2017, 11:43 AM
I finally have a solution to provide colors to my height map in C#. The code is quite simple and I use the vertex shader to send the texture coordinates to the fragment shader. I no longer need to send 200k texture coordinates. Here is the code:


Gl.UseProgram(plottingProgram);
Gl.BindTexture(myTexture); //this is the 2D texture

plottingProgram["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));

UpdateSpectrum();

spectrumVBO.BufferSubData(vertexBuffer); //vertexBuffer is an array with x,y,z data. x, is always the same

// This is no longer needed
// myUV.BufferSubData(colorBuffer); //colorBuffer is a vector2 with x always the same and y the same as vertexBuffer.y values

Gl.BindBufferToShaderAttribute(spectrumVBO, plottingProgram, "vertexPosition");

// This is no longer needed
// Gl.BindBufferToShaderAttribute(myUV, plottingProgram, "vertexUV");

Gl.BindBuffer(spectrumIndicesVBO);
Gl.DrawElements(BeginMode.TriangleStrip, spectrumIndicesVBO.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);

And now the shaders:


public static string VertexShader = @"
#version 130

in vec3 vertexPosition;

out vec2 textureCoordinate;

uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(void)
{
textureCoordinate = vertexPosition.xy;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";

public static string FragmentShader = @"
#version 130

uniform sampler2D texture;

in vec2 textureCoordinate;

out vec4 fragment;

void main(void)
{
fragment = texture2D(texture,textureCoordinate);
}
";

This works really nice with the added benefit that I can just change the bitmap to change the colors drawn.
The whole program will now draw 200,000 vertices in one opengl call. If I turn off vertical sync, it takes roughly 3 ms to plot and render a frame.

Many thanks to everyone who has helped out here, John GClements and Silence. First for pushing me towards Modern openGL and then guiding me in the right directions.
Best regards, Tom

john_connor
01-15-2017, 12:23 PM
... the error message was "Unsupported GLSL type layout". There is NO reference to this error anywhere. Sigh...

maybe its not really "correct" in my example, bt here you can find another example:
https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)#Binding_points

maybe you have to put "layout (... some qualifiers etc...)" right ip front (before "uniform")

"layout" is not a type, its a keyword to be able to provide some specifications, like the (texture) "binding" from which to sample