PDA

View Full Version : How to make your own primitive?

Cubby208
12-26-2015, 05:59 PM
So I am having serious cpu power issues. I am having to create a lot of rectangles on the cpu. These rectangles are built based on two points and a weight. Basically I make a rectangle between two endpoints with a specific width (because OpenGL es 2.0 doesn't allow line weight).

Is their a way I could just pass the two points and weight to some sort of shader and have the shader calculate its vertices then draw the triangle for it?

I know their is something called a "geometry shader" that I think is the part that decides what fragments to color based on the vertices. Is it possible, and how would one overload it?

GClements
12-27-2015, 01:35 AM
Is their a way I could just pass the two points and weight to some sort of shader and have the shader calculate its vertices then draw the triangle for it?

A geometry shader can do that. But OpenGL ES 2 doesn't have geometry shaders.

One option is to render triangles whose vertex positions are simply the endpoints of the line, and which have additional attributes containing the other endpoint and a scalar indicating the side of the line to which the vertex belongs. The vertex shader can then compute the perpendicular and offset the vertex accordingly. E.g.

attribute vec2 a_position;
attribute vec2 a_other;
attribute float a_side; // -1 or +1

uniform float u_width;

void main()
{
vec2 direction = normalize(a_other - a_position);
vec2 normal = direction.yx * vec2(-1,1);
vec2 position = a_position + (a_side * u_width) * normal;
gl_Position = vec4(position, 0, 1);
}

For a line segment from x0,y0 to x1,y1, you would specify four vertices and two triangles like:

float[4][2] position = {{x0,y0}, {x0,y0}, {x1,y1}, {x1,y1}};
float[4][2] other = {{x1,y1}, {x1,y1}, {x0,y0}, {x0,y0}};
float[4] side = {-1, 1, 1, -1};
unsigned short indices[6] = {0,1,2, 2,1,3};

This offloads the computations to the vertex shader, at the expense of specifying four times as much data as is actually needed.