Geometry shaders & the perennial "Fat Lines" Topic

Hey Everyone!

My end goal is to get the shader outlined here:

Example from Cinder forum link

Working in OF. With the aim of solving the Fat lines isssue which seems to come up here from time to time. I had had some luck with @roymacdonald 's ofxFatLines, however I wish to be able to change the fatness on many thousands of points frame to frame (Text outlines) and some quick experiments with that addon seemed that it may not be ideal for this purpose.

With that in mind then I started looking at the Geometry shader example supplied with OF (of_v0.11.2_vs2017_release\examples\gl\geometryShaderExample) which compiles and runs just fine.

I cannot however seem to successfully make any bold changes to the shader without receiving no output. Here is my edited shader (note the .frag and .vert shader remain unchanged from the example code):

#version 120
#extension GL_EXT_geometry_shader4 : enable

uniform float thickness; //not currently used
uniform vec3 color;

void main()
{
	vec3 pos = gl_PositionIn[0].xyz;

	gl_Position = gl_ModelViewProjectionMatrix * vec4(pos + vec3(-0.2, -0.2, 0.0), 0.0);
	gl_FrontColor = vec4(color, 1.0f); //color is simply set to input
	EmitVertex();
	gl_Position = gl_ModelViewProjectionMatrix * vec4(pos + vec3( 0.2, -0.2, 0.0), 0.0);
	gl_FrontColor = vec4(color, 1.0f);
	EmitVertex();
	gl_Position = gl_ModelViewProjectionMatrix * vec4(pos + vec3(-0.2,  0.2, 0.0), 0.0);
	gl_FrontColor = vec4(color, 1.0f);
	EmitVertex();
	gl_Position = gl_ModelViewProjectionMatrix * vec4(pos + vec3( 0.2, -0.2, 0.0), 0.0);
	gl_FrontColor = vec4(color, 1.0f);
	EmitVertex();
	//top
	gl_Position = gl_ModelViewProjectionMatrix * vec4(pos + vec3( 0.0,  0.4, 0.0), 0.0);
	gl_FrontColor =  vec4(1.0f, 1.0f, 1.0f, 1.0f); // make the peak of the house white, just for fun. 
	EmitVertex();
	//EndPrimitive(); // no effect
}

And here is Setup & Draw

void ofApp::setup(){

	ofSetLogLevel(OF_LOG_VERBOSE);
	ofBackground(50, 50, 50);
	ofSetVerticalSync(false);
	ofEnableAlphaBlending();

	//shader.setGeometryInputType(GL_POINT); //no
	//shader.setGeometryInputType(GL_POINTS); //no
	shader.setGeometryInputType(GL_LINES); //still no
	shader.setGeometryOutputType(GL_TRIANGLE_STRIP);
	shader.setGeometryOutputCount(5);
	shader.load("shaders/vert.glsl", "shaders/frag.glsl", "shaders/geom.glsl");

	ofLog() << "Maximum number of output vertices support is: " << shader.getGeometryMaxOutputCount();

	//vector of glm::vec3 to make Triangle;
	points.push_back(glm::vec3(0.0f , 200.0f,  0.0f));
	points.push_back(glm::vec3(200.0f, -200.0f, 0.0f));
	points.push_back(glm::vec3(-200.0f, -200.0f, 0.0f));
	points.push_back(glm::vec3(0.0f, 200.0f, 0.0f));

	doShader = true;
	ofEnableDepthTest();
}

void ofApp::draw(){
	ofColor(255);

	ofPushMatrix();
	if(doShader) {
		shader.begin();
		shader.setUniform1f("thickness", 10); //not used 
		shader.setUniform3f("color", 1.0f, 0.69f, 0.0f);
	}

	ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2, 0);
	//Draw Tri
	for(unsigned int i=1; i<points.size(); i++) {
		ofDrawLine(points[i-1], points[i]);
	}
	if(doShader) shader.end();
	ofPopMatrix();
	ofDrawBitmapString("fps: " + ofToString((int)ofGetFrameRate()) + "\nPress 's' to toggle shader: " + (doShader ? "ON" : "OFF"), 20, 20);
}

What I’m expecting to see are three “house” shapes on each point descirbed by the incoming triangle as per this link:
Learn Open GL Geometry Shader Example

If anyone could steer me in the right direction, I would be very grateful!

I’ve also tried using a ofMesh to store the vertices, and used:

mesh.setMode(OF_PRIMITIVE_POINTS);

To no avail.

Hi, I don’t think that calling ofDrawLine will work. try with an ofMesh which to which you add the vertices in the setup and you set it to draw lines ```
mesh.setMode(OF_PRIMITIVE_LINES);

Hey Roy,

Thanks for getting back to me, I did try in setup:

    mesh.addVertex(glm::vec3(0.0f, 200.0f, 0.0f));
	mesh.addVertex(glm::vec3(200.0f, -200.0f, 0.0f));
	mesh.addVertex(glm::vec3(-200.0f, -200.0f, 0.0f));
	mesh.addVertex(glm::vec3(0.0f, 200.0f, 0.0f));
	mesh.setMode(OF_PRIMITIVE_POINTS);

with a mesh.draw(); under draw to no avail.

Also just now as you suggest:

mesh.setMode(OF_PRIMITIVE_LINES);

Which also yields nothing with the shader input set to either GL_POINT, GL_POINTS, GL_LINE_STRIP or GL_LINES.

Confusing. I’m going to bed!

Hi, so why don’t you use the example/gl/geometryShaderExample? it does what you describe.
Another approach I have used but can not find example code is using instanced rendering and passing attributes to the shader through a texturebuffer. There are examples of both but you would need to put together

Hey, the one in the example is close, but not quite there.

This quick mockup maybe explains what the current shader is doing, vs the eventual desired effect:

Forgive the crudity…

Also just for fun! I had thought (wrongly) that it might be a good time to mess about with a geometry shader.

if helpful I’ve used vertex shader and this approach for thick lines ( “Screen-Space Projected Lines” )

and it works pretty well