How to Discard One of the Line Segments? - opengl

I'm using GL_LINES to draw lots of lines. But some of the lines should be hidden. Is there any way to discard a specific line segment?
I can implement this by putting lines in different buffers. However, the performance is bad when I have too many buffers. So currently I want to put them into a single buffer and discard the unnecessary one.

There is a discard keyword in GLSL. You can use it in the Fragment Stage to discard pixels you don't want to render. Here is an example that discards all red pixels:
sampled_color = texture(tex_sampler, tex_coords_FS_in);//Can be any way of obtaining pixels
if(color.rgb == vec3(1.0, 0.0, 0.0))
{
discard;
}

Related

how to render only two end points when using GL_LINES in OpenGL?

I'm working on a picking function with OpenGL. I know that I can render 3 lines using glPolygonMode(GL_FRONT_AND_BACK, GL_Lines); when the model is a triangle:
I also know that I can render 3 points using glPolygonMode(GL_FRONT_AND_BACK, GL_Points); when the model is a triangle:
Now I'm running into this problem: I cannot find a way to render 2 endpoints when rendering a line using GL_LINES.
Is there anything similar to glPolygonMode() that controls how GL_LINES works?
GL_LINES describes how the primitive (triangle) is filled in this case.
You can vaguely make out the original primitive even if it is represented as a series of lines or unconnected points rather than a filled triangle. However, for lines, if you simplify them to nothing but points you loose critical information necessary to make any sense of what you are seeing (how those points were connected).
A line mode would make no sense in light of this, and the closest thing that really ever existed would probably be line stippling.
Just use GL_POINTS as your primitive instead, you clearly do not require lines for whatever you are trying to accomplish.
Is there anything similar to glPolygonMode() that controls how GL_LINES works?
In one word: No. You'll have to implement this yourself (by simply submitting just the endpoints).
You can render them as GL_POINTS primitives rather than GL_LINES. Of course, you will need to apply a point size for them to be larger more than just a single dot.
As was already pointed out, there is no such thing as a glLineMode() call that would allow you to turn lines into points with a simple state setting.
If you can change the draw calls, you can obviously use GL_POINTS as the primitive type when you want to draw points.
Contrary to what the other answers claim, I believe there is a way to do this, even if hypothetically you can't modify the draw calls. You could use a geometry shader that has lines as the input primitive type, and points as the output primitive type. The geometry shader could look like this:
layout(lines) in;
layout(points, max_vertices = 2) out;
void main() {
gl_Position = gl_in[0].gl_Position;
EmitVertex();
gl_Position = gl_in[0].gl_Position;
EmitVertex();
EndPrimitive();
}

Efficiently draw polygons (one color per polygon) in OpenGL 3+

In an application I have to draw lots of disjoint polygons of variable lengths. Colours vary between polygons but all vertices in a single polygon will have the same colour. How can I draw them efficiently?
I started by drawing all polygons with the same colour. This was easy to do with glMultiDrawArrays and a colour uniform; for example (using GL_LINE_LOOP to keep things simple):
glUniform4f(shaderColourLocation, red, blue, green, alpha);
glMultiDrawArrays(GL_LINE_LOOP, pFirstIndices, pPolygonSizes, polygonCount);
This worked well with the data I have, but the only ways I can see to add per-polygon colours are:
break this down into multiple glDrawArrays calls, setting the colour each time (lots of extra API calls);
buffer per-vertex colour data (duplicates a lot of colour data);
buffer polygon indices and use a uniform array of colours (more complex, and still some redundant data).
Is there a better way to achieve per-polygon colours, while still using glMultiDrawArrays or something similar?
What you want to achieve (one color per polygon) is called flat shading.
You probably can do it width a shader by using the flat qualifier.
You also can take a look to glShadeModel parameter, by using GL_FLAT mode and smartly define the first vertex of your triangles you may avoid to duplicate data in your buffers.
You can find documentation in the OpenGl compatibility specs (p482 #507/953 ยง13.4).
Use instanced attributes.
Call
glVertexAttribDivisor(color_attrib_location, 1);
once when initializing your vertex arrays.
With this setting you will only need one copy of color value per point/line/polygon.
Also, you should use flat interpolation qualifier for this attribute in your shaders, but it's not necessary.

GLSL - how to force rendering a fragment?

is there any way to force rendering a particuar fragment. As far as I know, fragment shaders are called only for pixels within rasterized triangles. What I need to do is to draw a mark(say a single red pixel) in a constant position on the viewport. I mean something like this:
void main(void) {
if(gl_FragCoord.x == vec2(300.5, 300.5)){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
else {
gl_FragColor = getColorFromSampler();
}
,while there's no quad nor nothing behind fragment (300.5, 300.5). I don't want to affect performance (no fake background and stuff). How to proceed in such situation?
Is there anything speaking against just rendering a single point on top of the other stuff?
So just render a single GL_POINTS primitive at the given pixel. Either use an appropriate orthographic projection to specify the vertex position directly in window space, or just compute the clip space position of the pixel and use an identity vertex transformation. And then all that you need is a simple passthrough fragment shader writing your color of choice.
While you say you want "nothing behind the fragment", I still think that single fragment rendered under the red mark doesn't hurt anyone, at least not more (rather less) than your branch inside the fragment shader just for a single pixel (or any other more elaborate technique using the stencil buffer). If you have any other more strict reason why you cannot render anything else at that position except for the mark, you might want to clarify your problem a bit more.

Does glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) produce fragments for the rest of the polygon?

I wanted to see the wireframe of my triangle mesh, so rather than constructing a whole new VBO I'm trying to use glPolygonMode and draw it again with the exact same draw call. This is because I can't find a draw command that will let me make GL_LINE_LOOP primitives out of every 3 indices from my IBO.
But when I draw the wireframe, the insides of the triangles become black again. Is this because when a fragment is discarded, its color value is set to zero (black)? How could I set it so that a discarded fragment does not get written or blended? Are the fragments actually getting discarded?
I solved it. I set glPolygonMode(GL_FRONT_AND_BACK,GL_LINE) then neglected to set it back to GL_FILL, so all subsequent draws in my loop were wireframe. So it's obvious why the polygons ended up not filled.

What color does a fragment get if there are two vertices at the very same position with two different colors?

I have a question concerning the OpenGL rendering pipeline.
I have recently been reading theory about the GLSL's Geometry Shader. I think I do understand the basics of how to emit new geometry and assign colors to the new vertices. I am, however, not sure what color a fragment would get if one of those new vertices would have the very same position as one coming in from the Vertex shader.
Consider this example:
I far as I understand it, I am able to handle a single vertex with the Vertex shader. I make some transformation and store the position in glPosition. It is furthermore possible to assign a color to that vertex, e.g. by storing it to glFrontColor. As an example, I give it the color red. If all channels have 32 bits, that would be 0xFFFFFFFF'00000000'00000000'00000000, right?.
Next, Geometry shader is involved. I want my geometry shader to emit some additional vertices. At least one of them is at the very same position as the original vertex coming in from the Vertex shader. However, it is assigned another color, e.g. green. That would be 0x00000000'FFFFFFFF'00000000'00000000, right?
Sooner or later, after every vertex has been dealt, the rasterization takes place. As I understand, both vertices are rasterized and will therefore become the very same fragment. So, there we go. What color will that particular fragment get? Is there some kind of automatic blending and the fragment becomes yellow? Or is red or rather green?
This question might be silly. But I am simply not clear on that and would appreciate if somebody could clarify that for me.
If there is no blending (which I assume), how could I possibly create a blending effect?
Assuming you're rendering points (which seems to be what you're describing), the two vertices with the different colors will result in two fragments (one for each vertex) at the same location. What final color will be written to the output depends on the Z values for each, the blending function set and the order in which they are processed (which is effectively random -- you can't count on either order unless you do some extra sync stuff, so you need to set your blend func/Z-culling such that it doesn't matter).
I think they will be Z-Fighting, if they have the exact same values for x y and z.
About blending:
This is separate from the programmable pipeline, so you don't have to do most of the work in the shaders for it.
First enable blending with glEnable(GL_BLEND),
then specify your desired blending function with glBlendFunc, most commonly glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
Now the vertices only need an alpha value set at gl_FragColor.a and their color will blend.