Thanks for the great response. Not developing for mobile. I’m not sure how I would approach the triangles, since there is a lot going on with it. I’m not sure how to translate the normals, textures, vertexAttribs, and vertex shader to apply to 18 vertexs instead of 8. Also, I used 1000 lines as an example, but the reason I’m doing this is because I’m trying to draw many more lines than that and the performance of GL_LINE is slow on most systems (not hardware accelerated). I could be running 20,000 lines, so if I were to do full triangles, that would be 360,000 vertexs (that doesn’t count normals, textures, colors, or the attribs). I’m currently running on 40,000 vertexes since I’m using GL_LINE, but I wanted to try use a texture to simulate a volumetric line (described here). That would put it to 160,000 vertexes, but I was hoping that cached textures would be a lot faster, which has been my experience (I’ve run 500,000 textured sprites with no issue, but 20,000 lines kills it).
At a basic level, this is what is going on. To render a volumetric line you send the line start point 4 times and then the line end point 4 times also. Then, the vertex shader will handle the extrusion of the vertices along the line direction and orthogonal direction in screen space based on the weight you give to each vertices using glVertexAttrib4f.
gl.glBegin(gl.GL_TRIANGLE_STRIP);
gl.glNormal3fv(vline_vertexOffset[0], 0);
gl.glTexCoord2fv(vline_texCoord[0], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p2[0], p2[1], p2[2], 1.0f);
gl.glVertex3fv(p1, 0);
gl.glNormal3fv(vline_vertexOffset[1], 0);
gl.glTexCoord2fv(vline_texCoord[1], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p2[0], p2[1], p2[2], 1.0f);
gl.glVertex3fv(p1, 0);
gl.glNormal3fv(vline_vertexOffset[2], 0);
gl.glTexCoord2fv(vline_texCoord[2], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p2[0], p2[1], p2[2], 1.0f);
gl.glVertex3fv(p1, 0);
gl.glNormal3fv(vline_vertexOffset[3], 0);
gl.glTexCoord2fv(vline_texCoord[3], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p2[0], p2[1], p2[2], 1.0f);
gl.glVertex3fv(p1, 0);
gl.glNormal3fv(vline_vertexOffset[4], 0);
gl.glTexCoord2fv(vline_texCoord[4], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p1[0], p1[1], p1[2], 1.0f);
gl.glVertex3fv(p2, 0);
gl.glNormal3fv(vline_vertexOffset[5], 0);
gl.glTexCoord2fv(vline_texCoord[5], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p1[0], p1[1], p1[2], 1.0f);
gl.glVertex3fv(p2, 0);
gl.glNormal3fv(vline_vertexOffset[6], 0);
gl.glTexCoord2fv(vline_texCoord[6], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p1[0], p1[1], p1[2], 1.0f);
gl.glVertex3fv(p2, 0);
gl.glNormal3fv(vline_vertexOffset[7], 0);
gl.glTexCoord2fv(vline_texCoord[7], 0);
gl.glVertexAttrib4f(this.gpuProgVolumeLine_other, p1[0], p1[1], p1[2], 1.0f);
gl.glVertex3fv(p2, 0);
gl.glEnd();
vertex shader
attribute vec4 other;
uniform float lineWidth;
varying vec4 color;
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
color = gl_Color;
vec4 vMVP = gl_ModelViewProjectionMatrix * gl_Vertex;
vec4 otherMVP = gl_ModelViewProjectionMatrix * other;
vec2 lineDirProj = lineWidth * normalize( (vMVP.xy/vMVP.w) - (otherMVP.xy/otherMVP.w) );
if( sign(otherMVP.w) != sign(vMVP.w) ) {
lineDirProj = -lineDirProj;
}
vMVP.x = vMVP.x + lineDirProj.x * gl_Normal.x;
vMVP.y = vMVP.y + lineDirProj.y * gl_Normal.x;
vMVP.x = vMVP.x + lineDirProj.y * gl_Normal.y;
vMVP.y = vMVP.y - lineDirProj.x * gl_Normal.y;
gl_Position = vMVP;
}