Adam, check my sig if you want quake on the web. strip out bits of the uri for more demonstrations, you should be able to work it out.
I don't expect MG will want to support full quake mods, only maps and maybe models.
mg, skip the mips. you only really care about the first image. your rendering api should provide a way to generate the entire mipchain automatically anyway, and there's a load of maps with dodgy mips anyway.
Announcement
Collapse
No announcement yet.
Real Flash Quake
Collapse
X
-
A browser version could easily be made.
I finished miptex parse entirely. It parses all of the miptexes and attempts to directly use the bytes wherever possible. It's very fast.
Images are nicer than copy/paste code boxes. Here is my method.
Leave a comment:
-
I was wondering if it will work with mods like, for example Hazard?
It would be great for me to be able to put a demo version on my itch.io page that could be played there & then in a browser.
Is that sort of thing possible with what you are proposing?
Leave a comment:
-
I wanted to test my idea of ignoring all structs and parsing the map out of the BSP using math directly on the bytes. In other words, no vars, references, nothing. I rewrote my miptex parser to try this.
I feel like my code is really clear except for 2 things:
_lumps is a Vector (compact array) of bytes with each index representing a lump. MIPTEX = 2, which is the index number for the bytes that correspond with the miptex lump. The rest is easy enough to figure out now that you know _lumps[MIPTEX] are all of the original bytes from the miptex lump in the BSP. I'm only getting offset1 right now. I'll get the other mips after I make sure that I like this way.
This method works. I have it set to cycle through mips displaying it's contents on every mouse click and the display is perfect. Not one fucked up texture.Code:public function get materials():Vector.<BitmapData> { if (!_mips.length) { _lumps[MIPTEX].position = 0; var _ofs:Vector.<int> = new Vector.<int>(); var i:int =_lumps[MIPTEX].readInt(); var n:int = 0; while(n < i) { _ofs[n] = _lumps[MIPTEX].readInt(); ++n; } n = 0; while (n < _ofs.length) { _lumps[MIPTEX].position = _ofs[n]; _mip_names[n] = readString(_lumps[MIPTEX], 16); _mips[n] = new BitmapData(_lumps[MIPTEX].readUnsignedInt(), _lumps[MIPTEX].readUnsignedInt(), true, 0xff000000); _lumps[MIPTEX].position = _lumps[MIPTEX].readUnsignedInt()+_ofs[n]; for (var y:int = 0; y < _mips[n].height; ++y) { for (var x:int = 0; x < _mips[n].width; ++x) { var pal:Array = QuakePalette.rgb[uint(_lumps[MIPTEX].readUnsignedByte())]; _mips[n].setPixel(x, y, uint(pal[0] << 16 | pal[1] << 8 | pal[2])); } } ++n; } } return _mips; }Last edited by MadGypsy; 02-11-2016, 10:41 PM.
Leave a comment:
-
Actually @spike, I just remembered a question I wanted to ask you.
When I get to the part of constructing the miptexes, I was considering creating a Worker so parsing the BSP can continue while the images are being made. My concern is mobile devices (my main focus) will just be trading the time to construct images with the overhead of a Worker and recieve no benefit.
What do you think about this?
Leave a comment:
-
65536 verts per buffer... just checked but, I found a stress test running 15,000,000 polys at 60fps. The buffer is small but apparently using multiple buffers can still create some amazing results.
Leave a comment:
-
considering how inefficient flash is, I'd suggest just throwing the entire map into a single trisoup buffer (or at least one buffer per texture) and just using that.
you might need to be prepared to split it more than that if your api is shitty and doesn't support more than 65k verts, depends on the map...
hurrah for modern gpus, throw everything at it and see what sticks!
Leave a comment:
-
I'm letting some thoughts stew so, I'm gonna ramble about what I am actually doing. First of all, this is not going to be a Quake engine. We have like 500 Quake engines, there is no point in me building another one. My engine may see a day where it is Quake capable though.
I came here like 5 years ago because google told me this is where to go if I want to learn how to build a 3D FPS. I know the quake 1 version of building a game pretty much inside and out. The one thing that has always been a mystery to me is the engine. Aside from user end controls and options, engines have always been a black box, to me. I still want to build a game. I still want to build the same damn game that I wanted to build 5 years ago. Before I build my game, I need to build my engine. I want direct and absolute control and knowledge of my entire "product"... not just the game.
I have brought that decision even down to NOT using 3rd party engine API's. I could walk these faces right now into subgeometry (incl textures and uvs), push them into geometry and dump that to a mesh that gets sent to the Away3D scene. I know I could do this, right now... with success. That defeats the purpose of knowing every iota of the code. I'm going to go all the way down to the GPU and build my way up.
One way my engine will differ from a quake engine is, I am not porting a damn thing. I understand the various problems I need to solve and I'm gonna write my own code to solve them. Even the BSP parser I just wrote will probably get rewritten in a far less verbose and far more direct way. Like, probably forget even assigning vars and do the math straight out of the BSP readInt()*readInt() so to speak. That's the great thing about BSP. All I need is a base number (ie the byte offset of a lump) and I can predict every spot the number I need will appear in. I have no idea if performing the math directly from bytes to bytes and only saving the results I need is smart or faster or better but, I'm probably going to find out. Flash expects vertexes in the order they need to be connected as Vector.<Number>[x,y,z,r,g,b,x,y,z,r,g,b,x,y,z,r,g,b,.......]. Maybe I could write a formula that spits the whole world out like that without allocating a bunch of memory on all these vars. You could say instead of parsing the BSP I would be attacking it for the bottom line.
IDK..it's all dynamic right now. I'm building an engine that supports things I understand which are supported by tools that I understand. I know how to map in radiant and compile with modern tools to BSP. My engine should support BSP.Last edited by MadGypsy; 02-11-2016, 12:29 AM.
Leave a comment:
-
Thinking out loud...
Storing this here so I can get to it easy from any device. Having a "struct reference" is helping me visualize how this all goes together.Code:n = 0; while(n < leaf.lface_num) { offset = lfaces[leaf.lface_id]; currFace = faces[model[0].face_id + offset]; //kinna dumb if face_id is always the same number & it's zero id = currFace.texinfo_id; j = 0; while (j < currFace.ledge_num) { e = ledges[currFace.ledge_id + j]; //surf->surfedge if (e > -1) { edge = edges[e]; //surfedge->edge vert = vertices[edge.vertex0]; //edge->vertices } else { edge = edges[-e]; vert = vertices[edge.vertex1]; //reverse if negative } s = dotproduct(vert, texinfo[id].vectorS) + texinfo[id].distS; t = dotproduct(vert, texinfo[id].vectorT) + texinfo[id].distT; ++j; } ++n; }
Code:BSP HEADER BSP version: 29 -DHeader_T { _entities->DEntry_T[0]: { position:4 offset:794724, length:26284, index:0 }, _planes->DEntry_T[1]: { position:12 offset:124, length:36200, index:1 }, _miptex->DEntry_T[2]: { position:20 offset:821008, length:544168, index:2 }, _vertices->DEntry_T[3]: { position:28 offset:79192, length:88296, index:3 } PLANES LUMP -PlaneLump_T:{count:1810} -Plane_T[0]: { position:124, normal->Vec3_T:{x:0, y:1, z:0}, dist:-64, type:1 } -Plane_T[1]: { position:144, normal->Vec3_T:{x:0, y:1, z:0}, dist:3064, type:1 } MIPS LUMP -MipLump_T:{count:81} offset[0]:328, offset[1]:1728, offset[2]:7208, offset[3]:7588, offset[4]:7968, offset[5]:13448, offset[6]:35248, offset[7]:38008, offset[8]:40768, offset[9]:46248, offset[10]:51728 SURFACE LUMP -SurfaceLump_T{count:489} -Surface_T[0]: { position:233488, vectorS->:Vec3_T:{x:0, y:0, z:-1}, vectorT->Vec3_T:{x:0, y:1, z:0}, distS:0, distT:0, texture_id:0, animated:0 } VERTEX LUMP -VertexLump_T:{count:7358} Vertex_T[0]: { position:79192, {x:408, y:-64, z:128} } Vertex_T[1]: { position:79204, {x:408, y:-64, z:192} } Vertex_T[2]: { position:79216, {x:384, y:-64, z:192} } FACES LUMP -FaceLump_T:{count:5516} -Face_T[0]: { position:253048, plane_id:0, side:0, ledge_id:0, ledge_num:6, texinfo_id:13, lightmap_styles:[0,255,255,255], lightmap_offset:152 } EDGES LUMP -EdgeLump_T:{count:13497} -Edge_T[0]: { position:527588, vertex0:0, vertex1:0 } -Edge_T[1]: { position:527592, vertex0:0, vertex1:1 } -Edge_T[2]: { position:527596, vertex0:1, vertex1:2 } VIS LUMP -VisLump_T:{count:40843} vislist[0]:13 vislist[1]:48 vislist[2]:32 vislist[3]:-20 vislist[4]:-10 vislist[5]:-29 vislist[6]:7 vislist[7]:-26 vislist[8]:-123 vislist[9]:0 vislist[10]:1 NODES LUMP -NodeLump_T:{count:2750} -Node_T[0]: { position:167488, plane_id:0, front:1, back:2301, box:BBoxShort_T:{ min:[-632,-456,-632], max:[1544,3096,312] }, face_id:0, face_num:6 } MODELS LUMP -ModelLump_T:{count:58} -Model_T[0]: { position:581576, bounds->:BoundBox_T:{ min->:Vec3_T:{x:-607, y:-431, z:-607}, max->:Vec3_T:{x:1519, y:3071, z:287} }, origin->:Vec3_T:{x:0, y:0, z:0}, node_id:[0, 0, 2970, 0], numleafs:1148, face_id:0, face_num:5059 } CLIPNODES LUMP -ClipNodesLump_T:{count:5408} -ClipNode_T[0]: { position:363368, planenum: 568, children:[1, 1606] } -ClipNode_T[1]: { position:363376, planenum: 204, children:[2, 615] } MARKSURFACE LUMP -MarkSurfaceLump_T:{count:14146} lface[0]:98 lface[1]:99 lface[2]:100 lface[3]:104 lface[4]:103 lface[5]:102 lface[6]:94 lface[7]:93 lface[8]:92 lface[9]:91 lface[10]:6 LEAFS LUMP -LeafLump_T:{count:1531} -Leaf_T[0]: { position:36324, type:-2, vislist:0, bound->:BBoxShort_T:{ min:[0,0,0], max:[0,0,0] }, lface_id:0, lface_num:0, ambient:[0, 0, 0, 0] } -Leaf_T[1]: { position:36352, type:-1, vislist:0, bound->:BBoxShort_T:{ min:[144,3024,-16], max:[176,3064,16] }, lface_id:0, lface_num:15, ambient:[4294967295, 4294967295, 0, 0] } ENTITIES LUMP -EntitiesLump_T:{count:26284} { "worldtype" "2" "sounds" "6" "classname" "worldspawn" "wad" "gfx/base.wad" "message" "the Slipgate Complex" } { "classname" "info_player_start" "origin" "480 -352 88" "angle" "90" } { "classname" "light" "origin" "480 96 168" "light" "250" } { "classname" "light" "origin" "480 288 168" "light" "250" } { "classname" "light" "origin" "272 96 80" } { "origin" "272 288 80" "classname" "light" } { "classname" "light" "origin" "272 192 80" } { "origin" "688 192 80" "classname" "light_fluorospark" "style" "10" } SURFEDGES LUMP -SurfEdgeLump_T:{count:26702} ledge[0]:1 ledge[1]:2 ledge[2]:3 ledge[3]:4 ledge[4]:5 ledge[5]:6 ledge[6]:7 ledge[7]:8 ledge[8]:-1 ledge[9]:9 ledge[10]:10 LIGHTMAPS LUMP -LightmapLump_T:{count:168590} light[0]:69 light[1]:79 light[2]:89 light[3]:77 light[4]:86 light[5]:95 light[6]:84 light[7]:91 light[8]:98 light[9]:0 light[10]:0Last edited by MadGypsy; 02-10-2016, 11:35 PM.
Leave a comment:
-
you should also have some faces[n].ledge_count variable too, which says how many surfedges there are for that surface, and thus how many verticies you should have.
otherwise yes, I think you're calculating the right vert[x,y,z], s, and t values for the first vertex of each surface.
Leave a comment:
-
I can't test my script til I come from the other end in my code and create a renderer to plug the BSP into. That being said I will just ask you if this looks like I understood what you said.
I realize the product of the loop is nothing (atm). My question is just whether my method describes what you said. I haven't touched the lightmap part yet.Code:while(n < faces.length) { e = ledges[faces[n].ledge_id]; //surf->surfedge if (e > -1) { edge = edges[e]; //surfedge->edge vert = vertices[edge.vertex0]; //edge->vertices } else { edge = edges[-e]; vert = vertices[edge.vertex1]; //reverse if negative } id = faces[n].texinfo_id; s = dotproduct(vert, texinfo[id].vectorS) + texinfo[id].distS; t = dotproduct(vert, texinfo[id].vectorT) + texinfo[id].distT; ++n; }Last edited by MadGypsy; 02-10-2016, 02:54 AM.
Leave a comment:
-
surf->surfedges->edges->vertex.
if the surfedge value is negative, then the edge is backwards and you should flip the two verts.
by just walking the edges of each face you can construct the polygon that way.
texture coords depend upon the texinfo. v.s = dotproduct(3dposition, texinfo->vecs[0])+texinfo->vecs[0][3]; v.t = dotproduct(3dposition, texinfo->vecs[1])+texinfo->vecs[1][3];
lightmap size is determined from the texture coords. divide by 16 to get the size, the lightmap data will be aligned with the smallest point. you'll need to atlas stuff yourself. beware precision.
Leave a comment:
-

The above shot is just to show I am serious. The main text on the page is a log dump of the models lump for e1m1 (I can do this to any/all lumps). The viewer is proving I can get the miptexs properly. The file list on the right is my complete rewrite of all the BSP structs (except the leaf lump which I am doing right this minute).
This was already a whole lot of work. I WILL get BSPs to render. Hopefully sooner than later.Last edited by MadGypsy; 02-09-2016, 02:01 PM.
Leave a comment:

Leave a comment: