Archive for the ‘ 3D ’ Category

Lines

Just playing around with GL_LINES and shaders.  On a previous post, I got acquainted with glDrawArraysInstanced() but this time, I built a more solid environment around it, with colour, rotation and scaling options for each object.  So far, its actually pretty good for prototyping with primitives.  Now, I just need a better editor than just write code directly into the source. 🙂lines-thumb

 

Engine start-up (aka “Behold: the octree”)

I decided to start working on things other than OpenGL and focus on a few building features just for fun.  Voxel-based games are popular these days, thanks to Minecraft, Ace of Spades and upcoming Vox and Stonehearth, so I decided to look around that for info.  The creator of Vox made this web site on the intricacies of voxel engine building. But I decided to poke around, mixing and matching various approaches just to see if something interesting would come out.

First, it was necessary to see if my standard OpenGL commands that I wrapped around useful classes would hold.  I built a class that would solely focus on chunk rendering with an automated routine that chipped away a block at every pass, like a voxelized Swiss cheese. It was a naive first step but I was happy with the results.

cube00-thumbcube01-thumbcube02-thumb

As you can see in the images below, even with a little more than 300 cubes, the number of vertices is abnormally high, even if I’m careful at removing those that are common to adjacent cubes.  If I used a bigger chunk, OpenGL would choke.  Now, part of chunk management is to keep your chunks at a reasonable size, but that’s more for the rebuilding phase.  A single chunk that brings your video card to its knees is not a good sign.  Even with smaller chunks, you still need a lot of them and they generate a lot of vertices.  A lot!

cube03-thumb cube04-thumb

Of course, in a normal voxel-based game, cubes don’t tend to be cut away in such fashion.  In this demo, more vertices appear because the number of solitary cubes goes up, thus rendering the full 36 vertices that make a complete cube.

But the problem with this approach is that I still send information about those vertices that face away from the camera, the ones that are behind the three sides shown for each cube.  Culling is usually the answer to this: it is the process of not drawing a polygon if it faces away from the camera and OpenGL can do this on demand.  But that doesn’t stop me from over-flowing the vertices pipeline.  So why send so much information when half of it won’t be rendered anyway?

So I then rolled out my own culling process to prevent sending unwanted vertices, but it wasn’t a rousing success.  I tried some simple way to prevent rendering vertices if the chunk would be wholly on one side or the other of an axis. Things got ugly when a chunk shared both sides of the axis or if it was rotated … I ended up with additional or missing vertices.  A real mess.

I was looking for a way to subdivide the chunk and orient the culling on its individual sections when I ended up reading about octrees.  And then my brain started to expand.

An octree is a way to understand the context of a single point in space by sub-dividing the “world” into 8 blocks.  If a point is within one of these blocks, we subdivide that block again into 8 blocks, then again, and again, until the relevant information is matched (or not); e.g.: if you want to evaluate the possibilities of collision between a bullet and potential target, just subdivide your space toward the bullet and see if the target shares its space.

Below, you have a cubic “bullet” zooming into a fictitious – yet dangerous – world.  See how wireframed cubes are forming around it, defining a context in which other elements in the game may be analyzed.

octree00-thumb   octree01-thumb

By this “divide and conquer” approach, you can get information very quickly on very large surfaces.  In this frame below, if our bullet would be a meter long and wide (more like a giant cannonball that a tiny bullet), then the entire “world” this larger cube represents would be half a kilometre – 512 meters to be exact.  And yet it took little more then 9 sets of guesses (because 512 is 29) to zoom in on the bullet.

octree02-thumb

All in all, an octree is a perfect tool for a voxel-based engine: cube positioning and orientation, occlusion culling, targeting … I’ll have to review my first attempt and see how octrees can be an integral part of the engine now.

Fiat lux

Unlike God in Genesis, I had to sort out my own chaos before summoning light.

Tutorials are not meant to do 100% of the job for you. But there are some aspects of OpenGL that remain puzzling even when they are are presented to you for the umpteenth time. In this tutorial, the “answer code” is filled with buffer creations and variables assignments that either

  • mimic more or less the flow of the tutorial.
  • are simply patched on the legacy code of previous tutorials.
  • have their own little section (in some sort of library) away for the main flow .

While the work is cut out for me in order to understand the math of lighting, it’s another business to actually create something that will be re-usable and useful in other circonstances without someone taking you by the hand every time. As I said before, since I’m not using most authors’ windowing system, I had built my own patched up version of their tutorials that fit my own window creation with mouse and keyboard control.  As I was failing this tutorial (and others for reason I’ll have to investigate)  I spent a couple of days just sorting out things in proper places for understanding how OpenGL ticks. And that bring me more satisfaction that an individual rendering (well, the rendering part is nice, too. 🙂 )

The code now looks more like the narratives I like to put in code when I create some class for future reading for myself or others.

  1. Generate all the necessary buffers for a given program.
  2. Set all needed Uniforms for this program.
  3. Collect data, bind it.
  4. Set the program as current and render.

The fact of creating buffer and setting all uniforms so early at this stage helps me understand the purpose of this program: what I need as resources, what to set, what to calculate and abstract that knowledge in a general point of view.

(FYI: programs, in OpenGL, are not individual binaries – like a program that you run on your computer – but a set of pipeline rules that objects – i.e. their vertices, normals and uv texturing coordinates  – go through before showing the final results on the screen.)

Enjoy the results featuring Suzanne, the famous Blender monkey.

no_lighting_thumb

no_lighting_wf_thumb

with_lighting_thumb

with_lighting_wf_thumb

return top