Soundbomber's picture

Simple Objects

As an aside to my post on Cut Outs, as an alternative to using C.S.G to model my holes/cut-outs, I could also model the geometry using a model editor, thus hard coding the cut-outs into the model. My problem is this, so far to successfully model a 3d object, i have had to create individual vertices for EVERY triangle that makes up that model, so for example a cube-instead of only requiring 8 vertices, would require 6 faces*2 triangles*3 vertices=36 vertices. When I use the minimum of 8 vertices I only see certain facets of the cube shape.
Any ideas as where I am going wrong?

Inline Images

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
objarni's picture

What model editor are you using? Look for "convex subpolygons" or something like that, to break down your concave and multi-contour filled polygon. It's a whole plethora of algorithms to do this "tesselation".

Also, you should be able to use VBOs (Vertex Buffer Objects, look for them on opentk.com) to "share" vertices between different primitives (triangles or polygons). It's called "indexed mode" or similar.

Soundbomber's picture

The image above is just a simple cube created using DeleD 3D editor. I am already using VBOs.
Here is a sphere using the same program.

AttachmentSize
sphere.JPG67.07 KB
the Fiddler's picture

From the looks, this seems like an error in the element buffer. Do you calculate that manually, or is it created by the editor? Also, make sure the editor is exporting triangles not quads (I've been burnt by that before).

Soundbomber's picture

I calculate the buffers myself and the editor is exporting triangles not quads.

the Fiddler's picture

The vertices look correct (you can verify with DrawArrays and BeginMode.Points), which leaves the elememt buffer as the most probable source for the error. In fact, the second image looks exactly like what I got when I miscalculated the element buffer for a skydome, recently.

It's difficult to tell what the exact problem is without code, but this is the most likely explanation. Even an off-by-1 error will result in a rendering like this.

Soundbomber's picture

Here is my render code. I would be grateful if someone would care to check it out for integrity.

    Private Sub zDrawObject(ByVal oObject As ModelObject)
 
        oGL.EnableClientState(EnableCap.VertexArray)
        oGL.EnableClientState(EnableCap.TextureCoordArray)
        oGL.EnableClientState(EnableCap.NormalArray)
        oGL.EnableClientState(EnableCap.ColorArray)
 
        ' Solid
        ' Prepare buffers
        oGL.GenBuffers(2, Me.oBuffers)
        oGL.BindBuffer(BufferTarget.ArrayBuffer, Me.oBuffers(0))
        oGL.BufferData(BufferTarget.ArrayBuffer, oObject.oSolidVertices.Length * 12 * _
            Marshal.SizeOf(GetType(Single)), oObject.oSolidVertices, BufferUsageHint.StaticDraw)
        oGL.BindBuffer(BufferTarget.ElementArrayBuffer, Me.oBuffers(1))
        oGL.BufferData(BufferTarget.ElementArrayBuffer, oObject.oSolidIndices.Length * _
            Marshal.SizeOf(GetType(UShort)), oObject.oSolidIndices, BufferUsageHint.StaticDraw)
 
        ' Set as interleaved and draw object
        oGL.InterleavedArrays(InterleavedArrayFormat.T2fC4fN3fV3f, 0, Nothing)
        oGL.DrawArrays(BeginMode.Triangles, 0, oObject.oSolidVertices.Length)
 
        oGL.DisableClientState(EnableCap.VertexArray)
        oGL.DisableClientState(EnableCap.TextureCoordArray)
        oGL.DisableClientState(EnableCap.NormalArray)
        oGL.DisableClientState(EnableCap.ColorArray)
 
        oGL.BindBuffer(BufferTarget.ArrayBuffer, 0)
        oGL.BindBuffer(BufferTarget.ElementArrayBuffer, 0)
Inertia's picture

Since you have an index buffer, use GL.DrawElements instead of GL.DrawArrays.

the Fiddler's picture

Moreover, you want to call BufferData once only, at the point where you load the model. To draw the models, you need to:

  1. enable VBOs (check)
  2. set up the data format (you do that with InterleavedArrays, check)
  3. issue the draw command: DrawArrays if you don't have an element buffer, DrawElements if you have one.

As Inertia pointed out, the last point is throwing your rendering off.

Note that if you do not want to use an element buffer, you'll have to issue every vertex multiple times (which carries a speed penalty).

Soundbomber's picture

Ok, tried the following without success:

        oGL.DrawElements(BeginMode.Triangles, oObject.oSolidIndices.Length, DrawElementsType.UnsignedShort, _
            oObject.oSolidIndices)

nothing appears to get rendered.

Celeron's picture

I felt in the same error just few days ago. Since I'm very newbie in OpenGL programming, I think you have to specify just a InetPtr.Zero instead of the entire indices array, because you've already loaded indices in your VBO.
Can read more here: http://www.opentk.com/node/732

Fiddler and/or Inertia will tell more about it, I think ;-)