In OpenGL, how to clear drawn primitives in a 3D region - opengl

Let us say, I draw 3 points with glVertex3f at (0,0,0), (9,0,0) and (10,0,0)
I would like to clear all Vertex3f points in the bounding box region (2,-1,-1) to (15, 1, 1) which should include the last two points.
How does one do this in OpenGL?

Manage your point drawing outside of OpenGL. IE Don't use OpenGL to accomplish this. OpenGL is used for drawing data, not keeping track of it. If you want to get rid of certain objects, don't tell OpenGL to draw them. There are various space-partitioning data structures at your disposal for efficiently finding intersections.
The naive way is to check to see that all the points in your scene are outside that region before you draw them.
A better way is to use a kd-tree or an octree to exponentially narrow down the number of comparisons you must do.

Related

Draw part of sphere limited by set of vertices

What's the best way to draw part of sphere in, for example, OpenGL, considering I have vertices of boundaries of region that should be rendered?
I'm drawing sphere using octahedron transformation (described here: https://stackoverflow.com/a/7687312/1840136) and I can draw arcs that represent boundaries in same way by creating intermediate vertices and then "normalizing" them.
To create triangles out of plane I can use something from this answer: https://math.stackexchange.com/a/1814637, but thing is it will be still flat something. To get part of sphere, I definitely need another bunch of intermediate vertices for additional triangles. What is the algorithms for such task? And, as I already may have triangles forming original sphere, can I use this data somehow?

OpenGL 3.2+ Drawing Cubes around existing vertices

So I have a cool program that renders a pretty cube in the centre of the screen.
I'm trying to now create a tiny cube on each corner of the existing cube (so 8 tiny cubes), centred on each of the existing cubes corners (or vertices).
I'm assuming an efficient way to implement this would be with a loop of some kind, to minimise the amount of code.
My query is, how does this affect the VAO/VBO's? Even in a loop, would each one need it's own buffer or could they all be sent at the same time...
Secondly, if it can be done, what would the structure of this loop be like, in terms of focusing on separate vertices given that each vertex has different coordinates...
As Vaughn Cato said, each object (using the same VBOs) can simply be drawn at different locations in world space, so you do not need to define separate VBO's for each object.
To complete this task, you simply need a loop to modify the given matrix before each one is rendered to the screen to change the origins of where each cube is drawn.

3d Occlusion Culling

I'm writing a Minecraft like static 3d block world in C++ / openGL. I'm working at improving framerates, and so far I've implemented frustum culling using an octree. This helps, but I'm still seeing moderate to bad frame rates. The next step would be to cull cubes that are hidden from the viewpoint by closer cubes. However I haven't been able to find many resources on how to accomplish this.
Create a render target with a Z-buffer (or "depth buffer") enabled. Then make sure to sort all your opaque objects so they are rendered front to back, i.e. the ones closest to the camera first. Anything using alpha blending still needs to be rendered back to front, AFTER you rendered all your opaque objects.
Another technique is occlusion culling: You can cheaply "dry-render" your geometry and then find out how many pixels failed the depth test. There is occlusion query support in DirectX and OpenGL, although not every GPU can do it.
The downside is that you need a delay between the rendering and fetching the result - depending on the setup (like when using predicated tiling), it may be a full frame. That means that you need to be creative there, like rendering a bounding box that is bigger than the object itself, and dismissing the results after a camera cut.
And one more thing: A more traditional solution (that you can use concurrently with occlusion culling) is a room/portal system, where you define regions as "rooms", connected via "portals". If a portal is not visible from your current room, you can't see the room connected to it. And even it is, you can click your viewport to what's visible through the portal.
The approach I took in this minecraft level renderer is essentially a frustum-limited flood fill. The 16x16x128 chunks are split into 16x16x16 chunklets, each with a VBO with the relevant geometry. I start a floodfill in the chunklet grid at the player's location to find chunklets to render. The fill is limited by:
The view frustum
Solid chunklets - if the entire side of a chunklet is opaque blocks, then the floodfill will not enter the chunklet in that direction
Direction - the flood will not reverse direction, e.g.: if the current chunklet is to the north of the starting chunklet, do not flood into the chunklet to the south
It seems to work OK. I'm on android, so while a more complex analysis (antiportals as noted by Mike Daniels) would cull more geometry, I'm already CPU-limited so there's not much point.
I've just seen your answer to Alan: culling is not your problem - it's what and how you're sending to OpenGL that is slow.
What to draw: don't render a cube for each block, render the faces of transparent blocks that border an opaque block. Consider a 3x3x3 cube of, say, stone blocks: There is no point drawing the center block because there is no way that the player can see it. Likewise, the player will never see the faces between two adjacent stone blocks, so don't draw them.
How to draw: As noted by Alan, use VBOs to batch geometry. You will not believe how much faster they make things.
An easier approach, with minimal changes to your existing code, would be to use display lists. This is what minecraft uses.
How many blocks are you rendering and on what hardware? Modern hardware is very fast and is very difficult to overwhelm with geometry (unless we're talking about a handheld platform). On any moderately recent desktop hardware you should be able to render hundreds of thousands of cubes per frame at 60 frames per second without any fancy culling tricks.
If you're drawing each block with a separate draw call (glDrawElements/Arrays, glBegin/glEnd, etc) (bonus points: don't use glBegin/glEnd) then that will be your bottleneck. This is a common pitfall for beginners. If you're doing this, then you need to batch together all triangles that share texture and shading parameters into a single call for each setup. If the geometry is static and doesn't change frame to frame, you want to use one Vertex Buffer Object for each batch of triangles.
This can still be combined with frustum culling with an octree if you typically only have a small portion of your total game world in the view frustum at one time. The vertex buffers are still loaded statically and not changed. Frustum cull the octree to generate only the index buffers for the triangles in the frustum and upload those dynamically each frame.
If you have surfaces close to the camera, you can create a frustum which represents an area that is not visible, and cull objects that are entirely contained in that frustum. In the diagram below, C is the camera, | is a flat surface near the camera, and the frustum-shaped region composed of . represents the occluded area. The surface is called an antiportal.
.
..
...
....
|....
|....
|....
|....
C |....
|....
|....
|....
....
...
..
.
(You should of course also turn on depth testing and depth writing as mentioned in other answer and comments -- it's very simple to do in OpenGL.)
The use of a Z-Buffer ensures that polygons overlap correctly.
Enabling the depth test makes every drawing operation check the Z-buffer before placing pixels onto the screen.
If you have convex objects you must (for performance) enable backface culling!
Example code:
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
You can change the behaviour of glCullFace() passing GL_FRONT or GL_BACK...
glCullFace(...);
// Draw the "game world"...

Are there any easy ways to generate OpenGL code for drawing shapes from a GUI?

I have enjoyed learning to use OpenGL under the context of games programming, and I have experimented with creating small shapes. I'm wondering if there are any resources or apps that will generate code similar to the following with a simple paint-like interface.
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex2f(1, 0);
glVertex2f(2, 3);
glVertex2f(4, 5);
glEnd();
I'm having trouble thinking of the correct dimensions to generate shapes and coming up with the correct co-ordinates.
To clarify, I'm not looking for a program I can just freely draw stuff in and expect it to create good code to use. Just more of a visual way of representing and modifying the sets of coordinates that you need.
I solved this to a degree by drawing a shape in paint and measuring the distances between the pixels relative to a single point, but it's not that elegant.
It sounds like you are looking for a way to import 2d geometry into your application. The best approach in my opinion would be to develop a content pipeline. It goes something like this:
You would create your content in a 3d modeling program like Google's Sketchup. In your case you would draw 2d shapes using polygons.
You need a conversion tool to get the data out of the original format and into a format that your target application can understand. One way to get polygon and vertex data out of Sketchup is to export to Collada and have your tool read and process it. (The simplest format would be a list of triangles or lines.)
Write a geometry loader in your code that reads the data created by your conversion tool. You need to write opengl code that uses vertex arrays to display the geometry.
The coordinates you'll use just depend on how you define your viewport and the resolution you're operating in. In fact, you might think about collecting the coordinates of the mouse clicks in whatever arbitrary coordinate system you want and then mapping those coordinates to opengl coordinates.
What kind of library are you expecting?
something like
drawSquare(dx,dy);?
drawCircle(radius);?
drawPoly(x1,y1,x2,y2....);?
Isn't that exactly the same as glVertex but with a different name? Where is the abstraction?
I made one of these... it would take a bitmap image, and generate geometry from it. try looking up triangulation.
the first step is generating the edge of the shape, converting it from pixels to vertices and edges, find all the edge pixels and put a vertex at each one, then based on either the distance between vertices, or (better) the difference in gradient between edges to cull out vertices and reduce the poly count of the mesh.
if your shape drawing program works with 'vector graphics' rather than pixels, i.e. plotting points and having lines drawn between them, then you can skip that first step and you just need to do triangulation.
the second step, once you have your edges and vertices is triangulation, in order to generate triangles, ear clipping is a simple method for instance.
as for the coordinates to use? that’s entirely up to you as others have said, to keep it simple, Id just work in pixel coordinates.
you can then scale and translate as needed to transform the shape for use.

Drawing "point-like" shapes in OpenGL, indifferent to zoom

I'm working with Qt and QWt3D Plotting tools, and extending them to provide some 3-D and 2-D plotting functionality that I need, so I'm learning some OpenGL in the process.
I am currently able to plot points using OpenGL, but only as circles (or "squares" by turning anti-aliasing off). These points act the way I like - i.e. they don't change size as I zoom in, although their x/y/z locations move appropriately as I zoom, pan, etc.
What I'd like to be able to do is plot points using a myriad of shapes (^,<,>,*,., etc.). From what I understand of OpenGL (which isn't very much) this is not trivial to accomplish because OpenGL treats everything as a "real" 3-D object, so zooming in on any openGL shape but a "point" changes the object's projected size.
After doing some reading, I think there are (at least) 2 possible solutions to this problem:
Use OpenGL textures. This doesn't seem to difficult, but I believe that the texture images will get larger and smaller as I zoom in - is that correct?
Use OpenGL polygons, lines, etc. and draw *'s, triangles, or whatever. But here again I run into the same problem - how do I prevent OpenGL from re-sizing the "points" as I zoom?
Is the solution to simply bite the bullet and re-draw the whole data set each time the user zooms or pans to make sure that the points stay the same size? Is there some way to just tell openGL to not re-calculate an object's size?
Sorry if this is in the OpenGL doc somewhere - I could not find it.
What you want is called a "point sprite." OpenGL1.4 supports these through the ARB_point_sprite extension.
Try this tutorial
http://www.ploksoftware.org/ExNihilo/pages/Tutorialpointsprite.htm
and see if it's what you're looking for.
The scene is re-drawn every time the user zooms or pans, anyway, so you might as well re-calculate the size.
You suggested using a textured poly, or using polygons directly, which sound like good ideas to me. It sounds like you want the plot points to remain in the correct position in the graph as the camera moves, but you want to prevent them from changing size when the user zooms. To do this, just resize the plot point polygons so the ratio between the polygon's size and the distance to the camera remains constant. If you've got a lot of plot points, computing the distance to the camera might get expensive because of the square-root involved, but a lookup table would probably solve that.
In addition to resizing, you'll want to keep the plot points facing the camera, so billboarding is your solution, there.
An alternative is to project each of the 3D plot point locations to find out their 2D screen coordinates. Then simply render the polygons at those screen coordinates. No re-scaling necessary. However, gluProject is quite slow, so I'd be very surprised if this wasn't orders of magnitude slower than simply rescaling the plot point polygons like I first suggested.
Good luck!
There's no easy way to do what you want to do. You'll have to dynamically resize the primitives you're drawing depending on the camera's current zoom. You can use a technique known as billboarding to make sure that your objects always face the camera.