I am currently studying computer graphics and OpenGL on my own. So far I know that the GPU knows the primitives point, line and triangle. I ask myself, when do I tell the GPU whether it should, for example, render a polygon with lines or triangles? A rectangle consists of four lines or two triangles. Is there a rule of thumb to help you decide when to render lines or triangles in such a case?
Related
I am starting openGL. Not able to understand why everything in graphics starts from triangles. Every article that I read says entire graphics rests on triangles.
What is the reason for choosing such a shape as a basic building block? I though square or circle would be much better and is logical because of the symmetry properties.
Great question. It's because triangles are the only polygons that can approximate other shapes while also being guaranteed to lie in a plane, which means they have well-defined and easy-to-compute surfaces.
I am trying to draw a curve in 3D in which the width may vary. I am doing something similar to what described in this tutorial.
Meaning, i create quads (and triangles) with the desired width instead of using OpenGL width. The problem is that the triangles are actually in 2D - they are drawn in a specific plane. The width will look different, of course, from different angles.
Am i tackling this problem in the correct way? Is there a good solution for my problem?
This is a tough question that i have recently come across while developing a game myself.
They way i handled it instead of drawing a line i would draw boxes as segments of the line. You could potential make cylinders but if your using lighting you could cheat boxes to look like cylinders.
You could also cross two quads to make an X of sorts along the length of the string.
I am trying to render rounded triangles to increase performance. To illustrate what I mean, see the picture below:
I tried in the CPU, now is there a way to move this algorithm somehow to the GPU? I can change the method's code that calls the fragment shader?
By the way if I can do it, then what programming language I need to re-make it to?
I am using an OpenGL 2.1 GPU with just 20GB-30GB memory bandwidth.
Read the paper Resolution Independent Curve Rendering using Programmable Graphics Hardware by Charles Loop and Jim Blinn.
Short version: assuming you have an efficient inside/outside test for your curve, render the enclosing hull shape as triangle(s), use a fragment shader to discard the pixels outside the curve.
Second the concern by Aeluned that transferring the algorithm to the GPU won't automatically make it faster.
I'm not sure exactly what you're up to, but it seems a bit dubious. You can actually end up hurting performance trying to do some of these custom calculations in a shader to render a circle or ellipse.
Modern GPU hardware can push billions of triangles a second. You're probably splitting hairs here.
In any case, if you want to 'fake' the geometry, this may be of interest to you: https://alfonse.bitbucket.io/oldtut/Illumination/Tutorial%2013.html
Well on OpenGL 2.1 you do not have geometry shaders (3.2+) so you can forget about GPU.
You can not improve rasterizing performance of convex shapes by your curved triangles
complexity of rasterization of any convex polygon is the same as any triangle of the same area
the difference is only in:
number of passing vertexes
memory transfer
with geometry shader this will be better with your triangles usage
number of boundary lines
boundary lines rasterization for filling
will be worse with your triangles usage
(need to join more triangles instead of single shape polygon)
So its not a good idea to implement this for better performance in your case.
The only thing i can think of to use this for is to ease up manual generation of shapes.
In that case just write a function glRoundedTriangle(....)
which generate the correct vertexes,colors,normals,texture coordinates from given input parameters.
how it would looked like is unknown because you did not specify the rounded triangle geometry/shape and/or input parameters (for example 3 points + 3 signed curve radiuses ?)
To improve performance in OpenGL use VBO/VAO
I've been using OpenGL since some time now for making 3D applications, but I never really understood the use of the GL_POINT and GL_LINES primitive drawing types for 3D games in the production phase.
(Where) are point and line primitives in OpenGL still used in modern games?
You know, OpenGL is not just for games and there are other kind of programs than just games. Think CAD programs, or map editors, where wireframes are still very usefull.
GL_POINTS are used in games for point sprites (either via the pointsprite functionality or by generating a quad from a point in the geometry shader) both for "sparkle" effects and volumetric clouds.
They are also used in some special algorithms just when, well... when points are needed. Such as in building histograms in the geometry shader as by the chapter in one of the later GPU Gems books. Or, for GPU instance culling via transform feedback.
GL_LINES have little use in games (mostly useful for CAD or modelling apps). Besides not being needed often, if they are needed, you will normally want lines with a thickness greater than 1, which is not well supported (read as: fast) on all implementations.
In such a case, one usually draws thick lines with triangle strips.
Who ever said those primitives were used in modern games?
GL_LINES is critical for wireframe views in 3D modeling tools.
(Where) are point and line primitives in OpenGL still used in modern games?
Where do you want them to be used?
Under standard methods, points can be used to build point sprites, which are 2D flatcards that always face the camera and are of a particular size. They are always square in window-space. Sadly, the OpenGL specification makes using them somewhat dubious, as point sprites are clipped based on the center of the point, not the size of the two triangles that are used to render it.
Lines are perfectly reasonable for line drawing. Once upon a time, lines weren't available in consumer hardware, but they have been around for many years now. Of course, antialiased line rendering (GL_LINE_SMOOTH) is another matter.
More importantly is the interaction of these things with geometry shaders. You can convert points into a quad. Or a triangle. Or whatever you want, really. Each "point" is just an execution of the geometry shader. You can have points which contain the position and radius of a sphere, and the geometry shader can output a window-aligned quad that is the appropriate size for the fragment shader to do some raytracing logic on it.
GL_POINTS just means "one vertex per geometry shader". GL_LINES means "two vertices per geometry shader." How you use it is up to you.
I'd say for debugging purposes, but that is just from my own perspective.
Some primitives can be used in areas where you don't think they can be applied, such as a particle system.
I agree with Pompe de velo about lines being useful for debugging. They can be useful when debugging AI and collision detection algorithms so that you can visualize the data that is being used by the AI or collision detection. Some example uses for AI, the lines can be used to show AI paths or path meshes. Lines can be used to show steering data that the AI is using. Lines can be used to show what an AI is aiming at. The data that is shown can be displayed in text form but sometimes it is easier to see it in visual form.
In most cases particles are based on GL_POINT, considering that there can be a huge number of particles on the screen it would be very expensive to use 4 vertices per particle, so GL_POINT solves this problem
GL_LINES good for debugging purposes, wireframe mode can be used in various cases. As mentioned above - in CAD apps, but if you're interesed in gamedev use - it's good for a scene editor.
In terms of collision detection, they come in handy when you want to visualize bounding volumes(boxes,spheres,k-dops) and contact manifolds in wireframe mode. Setting the colour of these primitives based on the status of collisions as well is incredibly useful.
Circles are one of the basics geometric entities. Yet there is no primitives defined in OpenGL for this, like lines or polygons. Why so? It's a little annoying to include custom headers for this all the time!
Any specific reason to omit it?
While circles may be basic shapes they aren't as basic as points, lines or triangles when it comes to rasterisation. The first graphic cards with 3D acceleration were designed to do one thing very well, rasterise triangles (and lines and points because they were trivial to add). Adding any more complex shapes would have made the card a lot more expensive while adding only little functionality.
But there's another reason for not including circles/ellipses. They don't connect. You can't build a 3D model out of them and you can't connect triangles to them without adding gaps or overlapping parts. So for circles to be useful you also need other shapes like curves and other more advanced surfaces (e.g. NURBS). Circles alone are only useful as "big points" which can also be done with a quad and a circle shaped texture, or triangles.
If you are using "custom headers" for circles you should be aware that those probably create a triangle model that form your "circles".
Because historically, video cards have rendered points, lines, and triangles.
You calculate curves using short enough lines so the video card doesn't have to.
Because graphic cards operate on 3-dimensional points, lines and triangles. A circle requires curves or splines. It cannot be perfectly represented by a "normal" 3D primitive, only approximated as an N-gon (so it will look like a circle at a certain distance). If you want a circle, write the routine yourself (it isn't hard to do). Either draw it as an N-gon, or make a square (2 triangles) and cut a circle out of it it using fragment shader (you can get a perfect circle this way).
You could always use gluSphere (if a three-dimensional shape is what you're looking for).
If you want to draw a two-dimensional circle you're stuck with custom methods. I'd go with a triangle fan.
The primitives are called primitives for a reason :)