
3D Woes.
Posted Wednesday, 22 June, 2011 - 22:20 by Dan inI am an entirely self-taught programmer.
Everything I've ever learned I have taught myself, and I don't really like asking for help at the best of times, because part of the appeal for me is figuring things out on my own.
In the past I have taught myself, VB6, VB.Net, ASP, Html, MySQL and have used, DirectX7, DirectX9, and now OpenTK.
I understand sockets, multi threading, encryption, and I can make 2D games using OpenTK or Dx9 without any problem at all.
I give that as an introduction so that you can understand a few things about me, firstly I am determined, secondly because I am self taught, I've missed out on much lingo that I would have otherwise learned.
When answering any of my questions, feel free to post any of the code in c# as while I cannot write it, I can read it and convert it with ease.
Now for my question.
As I said I've used Dx7 -> OpenTK in the last few years to create 2D games, but every time I attempt to do anything in 3D I get stuck, I've tried countless tutorials, and even tried copy/pasting examples, and I can never ever seem to get any to work for me, much to my frustration, as a result each time I sadly end up getting annoyed and resorting to making something in 2D, which is within my ability.
So now I'm going to post some code, any pointers are much appreciated.
Start.vb
Imports System.IO Public Class Start Shared Sub Main(ByVal args As String()) Dim Eng As New Engine 'Start up a new engine object Dim gThread As New System.Threading.Thread(AddressOf Eng.EngLoad) gThread.Start() Do Until Eng.Running = False System.Threading.Thread.Sleep(1) Application.DoEvents() Loop End Sub
Engine.vb
Imports OpenTK.Graphics.OpenGL Imports OpenTK Imports System.Drawing.Text Public Class Engine Private Context As New OpenTK.Audio.AudioContext 'This is required for any sound to work Public Running As Boolean = True Public ScrWidth As Integer = 800 Public ScrHeight As Integer = 600 Public Debug As Boolean = True Public Game As Frm Public Sub EngLoad() Game = New Frm 'create a new instance of the game form Game.ClientSize = New System.Drawing.Size(ScrWidth, ScrHeight) 'change the form resultion to match the game resolution Game.MaximizeBox = False 'don't want people resizing the game Game.MinimizeBox = False Game.Text = "Project Rebirth (Enigma)" 'set the game text Game.GlControl1.Left = 0 'Set the OpenGL control to be in the top left Game.GlControl1.Top = 0 Game.GlControl1.Size = New System.Drawing.Size(ScrWidth, ScrHeight) 'resize the openGL control to use all the avalible space. Game.Show() Do Until Game.Loaded = True System.Threading.Thread.Sleep(1) Application.DoEvents() Loop Call Game.SetupViewpoint() 'setup the viewpoint so OpenGL knows to use all of the space GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit) 'clear the backbuffer Game.GlControl1.SwapBuffers() GL.Enable(EnableCap.DepthTest) Call Me.Run() End Sub Private Sub Run() Do Until Game.Running = False Application.DoEvents() 'accept input from the ui System.Threading.Thread.Sleep(0) 'allow the cpu to be used by other processes. GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit) 'clear the backbuffer Try 'rendering happens here 'GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line) GL.Begin(BeginMode.Quads) GL.Color4(Color.LimeGreen) 'Front face? GL.Vertex3(100, 100, 0.5) GL.Vertex3(200, 100, 0.5) GL.Vertex3(200, 200, 0.5) GL.Vertex3(100, 200, 0.5) 'back face GL.Color4(Color.Red) GL.Vertex3(100, 100, -0.5) GL.Vertex3(100, 200, -0.5) GL.Vertex3(200, 200, -0.5) GL.Vertex3(200, 100, -0.5) 'right face? GL.Color4(Color.Blue) GL.Vertex3(200, 100, -0.5) GL.Vertex3(200, 200, -0.5) GL.Vertex3(200, 200, 0.5) GL.Vertex3(200, 100, 0.5) GL.End() Try Game.GlControl1.SwapBuffers() 'Flip the backbuffer to the screen Catch ex As Exception End Try Loop Me.Running = False End Sub End Class
Frm.vb
Imports OpenTK.Graphics.OpenGL Imports OpenTK Public Class Frm Public Loaded As Boolean = False Public Running As Boolean = False Public MouseX As Integer = 0 Public MouseY As Integer = 0 Public MouseUpdate As Boolean Public MouseButton(0 To 2) As String Public CollectKeys As Boolean = False Public KeyCollection As String Dim curs As Cursor Private Sub GlControl1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GlControl1.Load Loaded = True Running = True GL.ClearColor(Color.White) End Sub Public Sub SetupViewpoint() Dim w As Integer = GlControl1.Width Dim h As Integer = GlControl1.Height GL.MatrixMode(MatrixMode.Projection) GL.LoadIdentity() GL.Ortho(0, w, h, 0, -1, 1) 'bottom left has cordinate 0,0 GL.Viewport(0, 0, w, h) 'use all of the glcontrol paining area GL.MatrixMode(MatrixMode.Modelview) GL.LoadIdentity() End Sub Private Sub GlControl1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles GlControl1.MouseDown MouseUpdate = True Dim state As String state = Control.MouseButtons.ToString() If InStr(state, "Left") Then If MouseButton(0) <> "hold" Then MouseButton(0) = "true" End If Else MouseButton(0) = "false" End If If InStr(state, "Middle") Then If MouseButton(1) <> "hold" Then MouseButton(1) = "true" End If Else MouseButton(1) = "false" End If If InStr(state, "Right") Then If MouseButton(2) <> "hold" Then MouseButton(2) = "true" End If Else MouseButton(2) = "false" End If End Sub Private Sub GlControl1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles GlControl1.MouseMove MouseX = e.X MouseY = e.Y MouseUpdate = True End Sub Private Sub GlControl1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles GlControl1.MouseUp Call GlControl1_MouseDown(sender, e) End Sub Private Sub Frm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Running = False End Sub Private Sub Frm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load MouseButton(0) = "false" MouseButton(1) = "false" MouseButton(2) = "false" Dim path As String = System.IO.Path.GetTempPath & "Enigma\" Dim zp As New ArchiveAccesss zp.Extract(Application.StartupPath & "/Content/Console.dat", "trans.cur", path) curs = New Cursor(path & "trans.cur") System.Windows.Forms.Cursor.Current = curs GlControl1.Cursor = curs End Sub Private Sub GlControl1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles GlControl1.KeyPress If CollectKeys = True Then KeyCollection += e.KeyChar End If End Sub Private Sub GlControl1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles GlControl1.MouseEnter End Sub Private Sub GlControl1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles GlControl1.MouseLeave End Sub End Class
It doesn't seem to matter what value I put for the z axis, I never seem to be changing the "depth" of the square.
I have a 2D engine written in OpenTK, and DirectX, but I think there is something I'm just *not getting* when it comes to 3D..
any pointers are really appreciated at this point, because I am 100% frustrated.
What I really would like to be able to do is to get just a 3D cube that I can rotate with a button press so that I can see exactly what is going on at each step.


Comments
Re: 3D Woes.
It doesn't seem to matter what value I put for the z axis, I never seem to be changing the "depth" of the square.
This is because you are using an orthographic projection matrix (GL.Ortho). If you wish to make objects appear smaller than they are, you need to use a perspective projection:
Re: 3D Woes.
It doesn't seem to matter what value I put for the z axis, I never seem to be changing the "depth" of the square.
This is because you are using an orthographic projection matrix (GL.Ortho). If you wish to make objects appear smaller than they are, you need to use a perspective projection:
I found out by playing with it that Matrix4.Create perspective doesn't work because the first value is invalid, quick google tells me it has to be > 0 and < then Pi, because it works in radians.
But trying various values for it results in me getting nothing at all now, instead of it just rendering 2D squares.
Is there anything anywhere I could read that would give me a better understanding of 3D and how OpenGL works?
I'm no stranger to reading entire books.
I'm honestly at a loss, everything I try and do involving 3D just seems to fail miserably.
Re: 3D Woes.
You are right, the first parameter must be in radians (try MathHelper.PiOverTwo or so).
If you see nothing on screen, chances are your camera is pointed the wrong way (the objects are rendered behind your viewpoint). Try running the OpenTK Example Browser and check the first few OpenGL examples. They are written in C#, but the OpenGL code is identical - these tutorials should provide a good starting point for 3d.
It might also be a good idea to read up on linear algebra (vector and matrix math). 3d is math-heavy and the more linear algebra you know, the simpler everything will appear.