Archive for March, 2009
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 |
Distractions, they are everywhere.
Posted by admin in Uncategorized on March 9th, 2009
Today I got distracted with coding a simple gui that could be used to make a rogue like game. You know those old school ascii games. It could also be used for simple editor purposes I guess. I have actually been thinking about taking some time out to plan some kind of RPG game. I have always wanted to make one, and I used to be a GM way back when, so I did a lot of story telling and knows a fair bit about how RPG games are put together rules wise anyways.
So I might venture down that road someday soon, most likely sometime after I am done with my DDO Character planner, which is a tool I want to enable me to plan better characters for the MMO that I have been playing the last 3 years. There are a couple of tools out there, but none of them are to my liking, and I think that I could make a better one, or at least one suited better to my needs.
I will continue working on my 3D engine all along though, its not being dumped or anything, so no worries there. Its something that I will be working on along side any other projects. I like to have multiple projects going as I tend to tire a bit working only on one thing. Its nice to be able to jump back and forth a bit, even though I know it slows down progress on all of the projects, it keeps me busy and coding.