mike029's picture

OpenGL Performance VBO

Hello,

im interessted in programming OGL for 2D and 3D, especially for CAD and GIS visualization.

A simple programm (below) should gave me a feeling of the performance thats aviable throug hardware acceleration,
but the Performace is very poor and i dont belive thats all.
Rendering 260.000 thousands triangles take 1 second, I think thats too long.
I have spend hours to find find the Problem, also tested native Code (c++ with glew and freeglut).

So please help me to find the bottleneck!?
Also some values about triangles per sec on other platforms would be great.

Ok think thats all, Thanks in advance for any answers!!

Hardware tested on:

Laptop:
Core i7-720QM
ATI HD5850 Mobility
64bit Windows 7 Ultimate
8GB RAM
Driver - Current stable

Results: 1,007 second for 260.000 trias

Workstation:
Core i7-970
NVidia Quadro 2000D
64bit Windows 7 Ultimate
16GB RAM
Driver - Current stable

Sample with latest OpenTK Toolkit (tested in Framework 3.5 SP1):

	Private m_VBOId As Integer
	Private m_IBOId As Integer
	Private Const PointCount As Integer = 3 * 260000
	Private Const SizeOf_Float As Byte = 4
	Private Const SizeOf_UInt As Byte = 4
	Public m_Vertices(PointCount * 3 - 1) As Single
	Private m_Indices(PointCount - 1) As UInteger
 
	Friend Sub CreateVertices(width As Integer, height As Integer)
		Dim x As New Random()
 
		For i As Integer = 0 To PointCount * 3 - 1 Step 3
			m_Vertices(i) = x.NextDouble() * width * 0.95
			m_Vertices(i + 1) = x.NextDouble() * height * 0.95
			m_Vertices(i + 2) = 0.1
		Next
 
		For i As Integer = 0 To m_Indices.Length - 1
			m_Indices(i) = i	' Mod 3
		Next
 
	End Sub
	Friend Sub DrawVBO()
 
		GL.PushAttrib(AttribMask.EnableBit)
		GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit)
 
		GL.EnableClientState(ArrayCap.VertexArray)
		GL.Enable(EnableCap.VertexArray)
 
 
		GL.BindBuffer(BufferTarget.ArrayBuffer, m_VBOId)
		GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_IBOId)
 
		'# VertexPointer setzen
		'# Size			Anzahl der Werte wie x,y,z - also für x,y,z = 3
		'# Type			In welchem Format liegen die Daten vor
		'# Stride		In welchem abstand zueinander liegen die Punktdaten
		'# Offset		Welchen Offset im Array
		GL.VertexPointer(3, VertexPointerType.Float, 3 * SizeOf_Float, 0)
 
		'# Mode 
		'# immer 0
		'# Anzahl der Vertices im Array
		GL.DrawArrays(BeginMode.Triangles, 0, PointCount)
 
 
 
		'GL.DrawElements(BeginMode.TriangleStrip, PointCount, DrawElementsType.UnsignedInt, 0)
 
 
		GL.PopAttrib()
		GL.PopClientAttrib()
	End Sub
	Friend Sub CreateVBO()
 
		GL.GenBuffers(1, m_VBOId)
		GL.BindBuffer(BufferTarget.ArrayBuffer, m_VBOId)
 
		'Daten in den Puffer schieben
		'BufferTarget		Was für ein Puffer - wir wollen den Vertexpuffer als ArrayBuffer
		'Size						Ist Size in Bytes - PointCount * SizeOfFloat * 3 = x,y,z
		'Data						Das Array mit den Werten
		'Usage					Gibt verschiedene mit Static oder Dynamic - da wir die Daten in dem Puffer nicht ändern Static
		GL.BufferData(BufferTarget.ArrayBuffer, SizeOf_Float * PointCount * 3, m_Vertices, BufferUsageHint.DynamicDraw)
 
 
		GL.GenBuffers(1, m_IBOId)
		GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_IBOId)
 
 
		GL.BufferData(BufferTarget.ElementArrayBuffer, SizeOf_UInt * m_Indices.Length, m_Indices, BufferUsageHint.StaticDraw)
 
	End Sub
 
	Friend Function Render(glControl As Object) As String
 
		Dim tWatch As New Stopwatch()
		tWatch.Start("Render")
 
		GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit Or ClearBufferMask.StencilBufferBit Or ClearBufferMask.AccumBufferBit)
		GL.ClearColor(Color.Black)
 
		DrawVBO()
		'DrawImmidiate()
 
		'# Wait for all done
		GL.Flush()
		GL.Finish()
 
		If TypeOf glControl Is OpenTK.GLControl Then
			CType(glControl, OpenTK.GLControl).SwapBuffers()
		Else
			CType(glControl, OpenTK.GameWindow).SwapBuffers()
		End If
 
 
		Return "DrawTime: " & Format(tWatch.Done(), "N5") & "   FPS: " & Format(1 / tWatch.Done(), "N1")
	End Function

Comments

Comment viewing options

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

Maybe you should divide your model to several pieces and then use frustum culling method on 3D or
just box culling on 2D before drawing (checking bbox or bounding sphere which I use when I rotate models).

ERP's picture

How big are the triangles on screen, they'll need to be close to 1 pixel in order to hit peak rates.
You'll also likely have to use triangle strips and a trivial vertex/pixel shader.
You'd also have to remove the Flush calls and average over more than one frame, although that won't show the impact your seeing.

If the tris are big enough to look like tris your just fill limited.

My usual test for triangle through put is to draw heavily tessellated spheres or planes, you get marginally better vertex distribution than in real models, but it's close enough.

In practice almost any piece of modern hardware (minus some of the embedded stuff) is more than fast enough unless you're requirements are extreme.