Archive for category Programming
Getting started on adding a Gui.
Posted by admin in Programming on March 29th, 2009
I started working on a native gui for my opengl engine. I first thought about using windows gui, but because I have made a lot of custom gui’s before, and I didn’t feel like messing around with the windows system, I decided to just write my own. I am at a stage where I got the windows drawing, and have made a couple of gadget drawing methods. Next up is writing the control code to get things interactive.

OpenGL Gui
Multitexturing problem was solved.
Posted by admin in Programming on March 14th, 2009
I had a problem with multi texturing which ment that if one entity used multi texturing, then all other entities suddenly also used it. It had to do with not disabling muti textures the right way. This has now been fixed, and its one less problem to think about

cubes with multi texture
Mesh load/save methods.
Posted by admin in Programming on March 14th, 2009
This morning I added load/save methods to the mesh type. And the heightmap test went from taking about 1500 millisecs to calculate, to taking 23 millisecs to load and ready. I also did a test with coloring the terrain from a heightmap color gradient. And it seems to be working great.

terrain colored by a heightmap gradient
Heightmap from image.
Posted by admin in Programming on March 13th, 2009
I got the first version of a heightmap from image method done. It will load an image, extract the height coordinates from one of the color channels, then create a mesh and recalculate normals for it. The normal calculations takes a very long time if the heightmap is large, so I will soon have to write my own load/save format for objects, so that I can pre-calculate everything, save it to a binary format, then when loading everything is already calculated, so it will be much faster.
I did not have any colormaps for a heightmap, so I just used a grayscale image.

heightmap terrain
Planequads added.
Posted by admin in Programming on March 13th, 2009
I have just added planequads, which is basically just a quad where the texture repeat can be defined at creation. This is useful for things like floors & walls. Nothing major, but it was a quick add while I was going through the mesh code, so I figured I might as well add it.

A plane made from a quad
Display Lists added
Posted by admin in Programming on March 12th, 2009
I had a little time, so I decided to add in display lists. After all its an easy addon, and it can speed up things in certain circumstances. I decided to add a static flag on the mesh type which will tell the engine if the mesh is dynamic or static, and if its static, that it should use a display list instead.
I made a method within the mesh type to produce a display list from its current arrays. This can also be used to convert loaded models since it does not care where the data came from.
I will tackle VBOs next, but not until after the code cleanup that I keep talking about, but haven’t gotten around to yet.
.3ds model loader
Posted by admin in Programming on March 12th, 2009
To complete the model loader functions, here is the .3ds one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | Function load3DSmodel:TMesh(file:String) Local tmp:TMesh = TMesh.init() Local stream:TStream, size:Int, id_node:String, size_node:Int, b:Byte, i:Int stream = ReadStream(file) If stream = Null Then Return tmp ' file could not be loaded, return false size = FileSize(file) DebugLog "Open "+file+" | Size:"+size While Not Eof(stream) id_node = Right(Upper(Hex(ReadShort(stream))),4) size_node = ReadInt(stream) DebugLog "Id="+id_node+" size="+size_node Select id_node Case "4D4D" 'Main node Case "3D3D" 'Config Case "4000" ' OBJECT BLOCK Repeat ' read the name of the object b = ReadByte(stream) If b = 0 Exit tmp.name :+ Chr(b) Until b = 0 DebugLog "Object name ="+tmp.name Case "4100" ' MESH BLOCK Case "4110" ' VERTICES LIST Local t:Int = ReadShort(stream) For i = 0 To t-1 tmp.addVertex(ReadFloat(stream),ReadFloat(stream),ReadFloat(stream)) ' default colors and tex uv for now Next DebugLog " Vertices: "+t Case "4120" ' FACE LIST Local t:Int = ReadShort(stream) For i = 0 To t-1 tmp.addFace(ReadShort(stream),ReadShort(stream),ReadShort(stream)) ReadShort(stream) Next DebugLog " Faces: "+t Case "4140" ' TEXTURE MAPPING COORDINATES LIST Local t:Int = ReadShort(stream) For i = 0 To t-1 tmp.addTexUV(ReadFloat(stream),ReadFloat(stream)) Next DebugLog " TexCoords: "+t Default ' no ID was found that we need, so fastforward past this chunk SeekStream(stream,StreamPos(stream)-6+size_node) End Select Wend CloseStream stream DebugLog "*** End of file ***" End Function |
.ase model loader
Posted by admin in Programming on March 12th, 2009
I have posted a couple of other model loader functions on the dbf forum, so I thought that I might as well post them here as well to complete the trio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | Function loadASEmodel:TMesh(loadfile:String) Local tmp:TMesh = TMesh.init() Local v1:String, v2:String, v3:String Local f1:Int, f2:Int, f3:Int, l:String Local a:Int, b:Int, i:Int, vertices:Int, faces:Int Local filein:TStream = ReadFile(loadfile) Repeat l = ReadLine(filein) Until Instr( l, "*MESH_NUMVERTEX" ) ' find the point where the vetrice And face number is l = Trim( l ) ' remove all unnecessary spaces l = Right( l, Len( l )-16 ) ' find the vertex number vertices = Int( l ) l = ReadLine(filein) ' read next line to get face number l = Trim( l ) ' remove all unnecessary spaces l = Right( l, Len( l )-15 ) ' find the face number faces = Int( l ) l = ReadLine(filein) ' skip one line For a = 1 To vertices l = ReadLine( filein ) l = Trim( l ) ' remove all unnecessary spaces l = Right( l, Len( l )-11 ) ' find the vertex data l = Replace( l, " ", "," ) v1 = NthField( l, Chr(9), 2 ) v2 = NthField( l, Chr(9), 3 ) v3 = NthField( l, Chr(9), 4 ) tmp.addVertex(Float(v1),Float(v2),Float(v3)) Next Repeat l = ReadLine(filein) Until Instr( l, "*MESH_FACE_LIST {" ) ' locate face list For a = 1 To faces l = ReadLine(filein) l = Trim( l ) ' remove all unnecessary spaces l = Right( l, Len( l ) - 10 ) l = Left(l, 61) f1 = Int(Mid(l, 13,5)) f2 = Int(Mid(l, 21,5)) f3 = Int(Mid(l, 29,5)) tmp.addFace(f1,f2,f3) Next Repeat l = ReadLine(filein) Until Instr( l, "*MESH_NORMALS {" ) ' find the point where the vetrice And face normals are For a = 1 To faces l = ReadLine(filein) l = Trim( l ) l = Right( l, Len( l )-19) If Left( l, 1 ) = Chr(9) Then l = Right( l, Len( l )-1 ) l = Replace( l, Chr(9), "," ) v1 = NthField( l, ",", 1 ) v2 = NthField( l, ",", 2 ) v3 = NthField( l, ",", 3 ) tmp.addFaceNormal(Float(v1),Float(v2),Float(v3)) For b = 1 To 3 l = ReadLine(filein) l = Trim( l ) l = Right( l, Len( l$ )-20) If Left( l, 1 ) = Chr(9) Then l = Right( l, Len( l )-1 ) l = Replace( l, Chr(9), "," ) v1 = NthField( l, ",", 1 ) v2 = NthField( l, ",", 2 ) v3 = NthField( l, ",", 3 ) tmp.addVertexNormal(Float(v1),Float(v2),Float(v3)) Next Next CloseFile(filein) Print "V:"+vertices Print "F:"+faces Return tmp End Function ' Given a String, a delimiter, And a n -- returns the nth Field Function NthField:String(s:String, delim:String, n:Int) Local o:Int = 1 For Local i:Int = 1 To n - 1 o = Instr(s, delim, o) If o = 0 Then Return "" End If o = o + 1 Next Local p:Int = Instr(s, delim, o) If p = 0 Then Return Mid(s, o) Else Return Mid(s, o, p - o) End If End Function |
.obj model loader code
Posted by admin in Programming on March 10th, 2009
I am fairly certain that my code for loading .obj model files is working as its intended now, so I thought that I would post the code as it might be of use for someone else as well. It is ofcause written in BlitzMax like everything else I code, but since BlitzMax is somewhat easy to read and understand, I think that it should be trivial to convert the code into other languages as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | Function loadOBJmodel:TMesh(loadfile:String) Local tmp:TMesh = TMesh.init() Local sline:String, ck:String Local v1:String, v2:String, v3:String Local f1:String, f2:String, f3:String Local vertices:Int, texUV:Int, vNormals:Int, faces:Int Local filein:TStream = ReadFile(loadfile) ' locate vertex data Repeat sline = ReadLine(filein) ck = Left( sline,2 ) Select ck Case "v " ' vertex v1 = NthField( sline," ",2 ) v2 = NthField( sline," ",3 ) v3 = NthField( sline," ",4 ) tmp.addVertex(Float(v1),Float(v2),Float(v3)) vertices:+ 1 Case "vt" ' vertex texture v1 = NthField( sline," ",2 ) v2 = NthField( sline," ",3 ) tmp.addTexUV(Float(v1),Float(v2)) Print v1+","+v2 texUV :+ 1 Case "vn" ' vertex normal v1 = NthField( sline," ",2 ) v2 = NthField( sline," ",3 ) v3 = NthField( sline," ",4 ) tmp.addVertexNormal(Float(v1),Float(v2),Float(v3)) vNormals :+ 1 Case "f " ' face sline = Right(sline,Len(sline)-2) ' trim start of string sline = Replace(sline," ","/") ' replace spaces ' vertex pointers f1 = NthField( sline,"/",1 ) f2 = NthField( sline,"/",4 ) f3 = NthField( sline,"/",7 ) tmp.addFVpointer(Int(f1)-1,Int(f2)-1,Int(f3)-1) ' texture pointers f1 = NthField( sline,"/",2 ) f2 = NthField( sline,"/",5 ) f3 = NthField( sline,"/",8 ) tmp.addFVTexUV(Int(f1)-1,Int(f2)-1,Int(f3)-1) ' normal pointers f1 = NthField( sline,"/",3 ) f2 = NthField( sline,"/",6 ) f3 = NthField( sline,"/",9 ) tmp.addFVnormal(Int(f1)-1,Int(f2)-1,Int(f3)-1) faces :+ 1 End Select Until Eof(filein) Return tmp End Function ' Given a String, a delimiter, And a n -- returns the nth Field Function NthField:String(s:String, delim:String, n:Int) Local o:Int = 1 For Local i:Int = 1 To n - 1 o = Instr(s, delim, o) If o = 0 Then Return "" End If o = o + 1 Next Local p:Int = Instr(s, delim, o) If p = 0 Then Return Mid(s, o) Else Return Mid(s, o, p - o) End If End Function |
The basic cube :)
Posted by admin in Programming on March 1st, 2009
My first project, now that I am programming again is a 3d opengl engine. So far I have gotten to the point where I can create objects and basic vertex lighting seems to be working. I don’t have a lot to show so far since most work at the moment has to do with getting the foundation of the code working, such as loading setting up the window, creation of meshes, entities, lights and so on. Once I am confident that the basic stuff works, then I will expand with more effecient ways of doing the objects, such as displaylists, or VBOs (vertex buffer objects).
So for now the only thing I have to show is the very basic, but almost mandatory cube, textured ofcause

some boxes