1

I am trying to generate OpenGL primitives out of a 6 integer Vertex. I.E. the 6 integer value will generate 4 custom line_strip.

First I am trying to move the 6 integer array from Vertex to Shader and in order to do that I am doing a simple test as follows.

This is the code for the Vertex Shader:

#version 330

layout (location = 0) in int inVertex[6];
out int outVertex[6];

void main()
{
    outVertex = inVertex;
}

And for the Geometry Shader, which hardcodes a segment:

#version 330

in int vertex[6];
layout (line_strip, max_vertices = 2) out;

void main()
{

    gl_Position = vec4(-0.2, -0.2, 0.0, 1.0); 
    EmitVertex();    
    gl_Position = vec4(-0.2 +0.4, -0.2, 0.0, 1.0); 
    EmitVertex();    
    EndPrimitive();

}

But I get an empty screen.

enter image description here

If I modify the Vertex shader to this:

#version 330

layout (location = 0) in int inVertex[6];
out int outVertex[6];

void main()
{   
    //outVertex = inVertex;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
}

and the Geometry Shader to this:

#version 330

//in int candle[6];
layout (points) in;
layout (line_strip, max_vertices = 2) out;

void main()
{

    gl_Position = vec4(-0.2, -0.2, 0.0, 1.0); 
    EmitVertex();    
    gl_Position = vec4(-0.2 +0.4, -0.2, 0.0, 1.0); 
    EmitVertex();    
    EndPrimitive();

}

Then I get the segment in the screen:

enter image description here

Is it mandatory to use gl_Position? If so, How can I pass additional variables together to gl_Position to enrich my Vertex?

M.E.
  • 4,955
  • 4
  • 49
  • 128
  • What are this 6 integers? How do you specify the array of generic vertex attribute data? What is the primitive type? – Rabbid76 Apr 06 '20 at 12:21
  • @Rabbid76 The 6 integer represent: open price, close price, high price, low price, volume and timestamp. It is a common representation for financial stock market. From that you build the graphical representation, which implies a rectangle and two whiskers. I am trying to have the GPU processing the data. https://en.wikipedia.org/wiki/Candlestick_chart Hence I am trying to have the geometry shader build the graphic primitives (line segments) – M.E. Apr 06 '20 at 13:48
  • @M.E.: How much data do you have? If it's not literally millions of values, it would probably be better to process them on the CPU into proper vertex data and just submit that. Especially if this data needs to be updated regularly, since you'll have to be streaming data to the GPU anyway. – Nicol Bolas Apr 06 '20 at 15:12
  • I have hundreds of thousands of values, might be a few millions. Data does not need to be updated regularly, that is why I am trying to push that processing part into the GPU. I see that modern GPUs have hundreds of cores. – M.E. Apr 06 '20 at 20:52
  • This link https://www.khronos.org/opengl/wiki/Vertex_Specification is helping me a lot to understand how vertexes are processed by shaders. For example, I did not know that if I send an integer buffer to the Vertex shader, it seems to be converted by default to float. – M.E. Apr 06 '20 at 20:53

2 Answers2

3

Vertex shaders operate on vertices (oddly enough). They have a 1:1 correspondance with vertex data: for each vertex in the rendering operation, you get one output vertex.

Geometry shaders operate on primitives. They have a 1:many relationship with their input primitives. A GS gets a single primitive and it outputs 0 or more primitives, within various restrictions.

A primitive is composed of one or more vertices. So a GS must be able to get multiple pieces of input data, as generated by the VSs that executed to generate the primitive the GS is processing. As such, all GS inputs are arrayed. That is, for any type T which the VS outputs, the GS takes a T[] (or equivalent). This is true even if your GS's input primitive type is points.

So if the VS has this as an output out int outVertex[6];, then the corresponding GS ought to be in int outVertex[][6];. Note that the indices of arrays of arrays are read left-to-right, so this is an array of primitive-count elements, where each element is an array of 6 ints. Also, note that the names need to match. You should have gotten a linker error for the name mismatch.

Alternatively, you can use an interface block, to make the arraying a bit easier:

//VS:
out Prim
{
    int data[6];
};

//GS:
in Prim
{
    int data[6];
} vsData[];

//Access with vsData[primIx].data[X];
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
1

The Vertex Shader is executed for each vertex, hence the inputs and outputs are not an arrays, they are single attribute:

#version 330

layout (location = 0) in vec3 inVertex;
out vec3 vertex;

void main()
{
    vertex = inVertex;
}

The input to the Geometry shader is a primitive. All the outputs of the vertex shader which form a primitive are composed. Thus the inputs of the geometry shader are arrays.
The size of the input array depends on the input primitive type to the geometry shader. e.g for a line the input array size is 2:

#version 330

layout (lines) in;
layout (line_strip, max_vertices = 4) out;

in vec3 vertex[];

void main()
{
    // [...]
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • As far as I know a vertex is a set of data, which can be anything. I am trying to input 6 integers to the GPU and get 6 lines draw after basic computation of those integers. I do not know how can I move extra data from vertex to geometry. Is that even possible? – M.E. Apr 06 '20 at 12:18
  • The [refrence](https://learnopengl.com/Advanced-OpenGL/Geometry-Shader) I provided in a comment to a previous question has links to [vertex shader](https://learnopengl.com/code_viewer_gh.php?code=src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.vs) and [geometry shader](https://learnopengl.com/code_viewer_gh.php?code=src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.gs) examples that do exactly what you want (I think). Search for `VS_OUT`. – G.M. Apr 06 '20 at 12:38
  • Thanks for your patience and help @G.M. After re-reading the reference I will try again another thing with VS_OUT. – M.E. Apr 06 '20 at 13:49