-1

I am working on a 3D mesh I am storing in an array: each element of the array is a 4D point in homogeneous coordinates (x, y, z, w). I use OpenCL to do some calculations on these data, which later I want to visualise, therefore I set up an OpenCL/GL interop context. I have created a shared buffer between OpenCL and OpenGL by using the clCreateFromGLBuffer function on a GL_ARRAY_BUFFER:

...
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, size_of_data, data, GL_DYNAMIC_DRAW);
vbo_buff = clCreateFromGLBuffer(ctx, CL_MEM_READ_WRITE, vbo, &err);
...

In the vertex shader, I access data this way:

layout (location = 0) in vec4 data;

out VS_OUT
{
  vec4 vertex;
} vs_out;

void main(void)
{
  vs_out.vertex = data;
}

Then in the geometry shader I do something like this:

layout (points) in;
layout (triangle_strip, max_vertices = MAX_VERT) out;

in VS_OUT
{
  vec4 vertex;
} gs_in[];

void main()
{
  gl_Position = gs_in[0].vertex;
  EmitVertex();
  ...etc...
}

This gives me the ability of generating geometry based on the position of each point the stored in the data array.

This way, the geometry I can generate is only based on the current point being processed by the geometry shader: e.g. I am able to construct a small cube (voxel) around each point.

Now I would like to be able to access to the position of other points in the data array within the geometry shader: e.g. I would like to be able to retrieve the coordinates of another point (indexed by another shared buffer of an arbitrary length) besides the one which is currently processed in order to draw a line connecting them.

The problem I have is that in the geometry shader gs_in[0].vertex gives me the position of each point but I don't know which one for at the time (which index?). Moreover I don't know how to access the position of other points besides that one at the same time.

In an hypothetical pseudo-code I would like to be able to do something like this:

point_A = gs_in[0].vertex[index_A];
point_B = gs_in[0].vertex[index_B];
draw_line_between_A_and_B(point_A, point_B);

It is not clear to me whether this is possible or not, or how to achieve this within a geometry shader. I would like to stick to this approach because the calculations I do in the OpenCL kernels implement a cellular automata, hence it is convenient for me to organise my code (neutrino) in terms of central nodes and related neighbours.

All suggestions are welcome.

Thanks.

ezor
  • 1
  • 1

2 Answers2

1

but I don't know which one for at the time (which index?)

See gl_PrimitiveIDIn

I don't know how to access the position of other points besides that one at the same time.

You can bind same source buffer two times, as a vertex source and as GL_TEXTURE_BUFFER. If your OpenGL implementation supports it, you'll then be able to read from there.

Unlike Direct3D, in GL the support for the feature is optional, the spec says GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS can be zero.

Soonts
  • 20,079
  • 9
  • 57
  • 130
0

"This gives me the ability of generating geometry based on the position of each point the stored in the data array."

No it does not. The input to the geometry shader are not all the vertex attributes in the buffer. Let me quote the Geometry Shader wiki page:

Geometry shaders take a primitive as input; each primitive is composed of some number of vertices, as defined by the input primitive type in the shader.

Primitives are a single point, line primitive or triangle primitive. For instance, If the primitive type is GL_POINTS, then the size of the input array is 1 and you can only access the vertex coordinate of the point, or if the primitive type is GL_TRIANGLES, the the size of the input array is 3 and you can only access the 3 vertex attributes (respectively corners) which form the triangle.

If you want to access more data, the you have to use a Shader Storage Buffer Object (or a texture).

Rabbid76
  • 202,892
  • 27
  • 131
  • 174