private void Mod_LoadVisibility(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { int pos_visdata = 0; br.BaseStream.Seek(header.lumps[LUMP_VISIBILITY].fileofs, System.IO.SeekOrigin.Begin); if (header.lumps[LUMP_VISIBILITY].filelen == 0) { _SModel.vis.numclusters = 0; _SModel.vis.bitofs = null; _SModel.visdata = null; return; } _SModel.vis.numclusters = br.ReadInt32(); _SModel.vis.bitofs = new int[_SModel.vis.numclusters, 2]; for (int i = 0; i < _SModel.vis.numclusters; i++) { _SModel.vis.bitofs[i, DVIS_PVS] = br.ReadInt32(); _SModel.vis.bitofs[i, DVIS_PHS] = br.ReadInt32(); // decrement the offsets, because the data is stored in a seperate byte array _SModel.vis.bitofs[i, DVIS_PVS] -= 4 + ((4 * _SModel.vis.numclusters * 2)); _SModel.vis.bitofs[i, DVIS_PHS] -= 4 + ((4 * _SModel.vis.numclusters * 2)); } _SModel.visdata = new byte[(header.lumps[LUMP_VISIBILITY].fileofs + header.lumps[LUMP_VISIBILITY].filelen) - br.BaseStream.Position]; while (br.BaseStream.Position < (header.lumps[LUMP_VISIBILITY].fileofs + header.lumps[LUMP_VISIBILITY].filelen)) { _SModel.visdata[pos_visdata++] = br.ReadByte(); } }
/// <summary> /// CreateSurfaceLightmap /// --------------------- /// Creates a lightmap surface /// </summary> public void CreateSurfaceLightmap(CModel.SModel _SModel, ref CModel.SMSurface surf) { int smax; int tmax; int bytepos; if ( (surf.flags & CModel.EMSurface.SURF_DRAWSKY) == CModel.EMSurface.SURF_DRAWSKY | (surf.flags & CModel.EMSurface.SURF_DRAWTURB) == CModel.EMSurface.SURF_DRAWTURB ) { return; } smax = (surf.extents[0] >> 4) + 1; tmax = (surf.extents[1] >> 4) + 1; if (LM_AllocBlock(smax, tmax, ref surf.light_s, ref surf.light_t) == false) { LM_UploadBlock(false); LM_InitBlock(); if (LM_AllocBlock(smax, tmax, ref surf.light_s, ref surf.light_t) == false) { CMain.Error(CMain.EErrorParm.ERR_FATAL, "Consecutive calls to LM_AllocBlock(" + smax + "," + tmax + ") failed\n"); } } surf.lightmaptexturenum = CProgram.gQ2Game.gCMain.gCImage.current_lightmap_texture; bytepos = (surf.light_t * BLOCK_WIDTH + surf.light_s) * LIGHTMAP_BYTES; CProgram.gQ2Game.gCMain.gCLight.SetCacheState(ref surf); CProgram.gQ2Game.gCMain.gCLight.BuildLightMap(_SModel, ref surf, bytepos, ref lms.lightmap_buffer, BLOCK_WIDTH * LIGHTMAP_BYTES); }
private void Mod_LoadAreas(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <SDArea> DArea = new List <SDArea>(); List <CModel.SMArea> MArea = new List <CModel.SMArea>(); br.BaseStream.Seek(header.lumps[LUMP_AREAS].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_AREAS].fileofs + header.lumps[LUMP_AREAS].filelen)) { SDArea _DArea; _DArea.numareaportals = br.ReadInt32(); _DArea.firstareaportal = br.ReadInt32(); DArea.Add(_DArea); } for (int i = 0; i < DArea.Count; i++) { CModel.SMArea _MArea; _MArea.numareaportals = DArea[i].numareaportals; _MArea.firstareaportal = DArea[i].firstareaportal; _MArea.floodvalid = 0; _MArea.floodnum = 0; MArea.Add(_MArea); } _SModel.numareas = MArea.Count; _SModel.areas = MArea.ToArray(); }
private void Mod_LoadAreaPortals(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <SDAreaPortal> DAreaPortal = new List <SDAreaPortal>(); List <CModel.SMAreaPortal> MAreaPortal = new List <CModel.SMAreaPortal>(); br.BaseStream.Seek(header.lumps[LUMP_AREAPORTALS].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_AREAPORTALS].fileofs + header.lumps[LUMP_AREAPORTALS].filelen)) { SDAreaPortal _DAreaPortal; _DAreaPortal.portalnum = br.ReadInt32(); _DAreaPortal.otherarea = br.ReadInt32(); DAreaPortal.Add(_DAreaPortal); } for (int i = 0; i < DAreaPortal.Count; i++) { CModel.SMAreaPortal _MAreaPortal; _MAreaPortal.portalnum = DAreaPortal[i].portalnum; _MAreaPortal.otherarea = DAreaPortal[i].otherarea; MAreaPortal.Add(_MAreaPortal); } _SModel.numareaportals = MAreaPortal.Count; _SModel.areaportals = MAreaPortal.ToArray(); }
/// <summary> /// BeginBuildingLightmaps /// ---------------------- /// Initializes the lightmap building process /// </summary> public void BeginBuildingLightmaps(ref CModel.SModel _SModel) { CLocal.SLightStyle[] _LightStyle; // no dlightcache CMain.r_framecount = 1; // setup the base lightstyles so the lightmaps won't have to be regenerated // the first time they're seen _LightStyle = new CLocal.SLightStyle[CLocal.MAX_LIGHTSTYLES]; for (int i = 0; i < CLocal.MAX_LIGHTSTYLES; i++) { _LightStyle[i].rgb = new float[3]; _LightStyle[i].rgb[0] = 1.0f; _LightStyle[i].rgb[1] = 1.0f; _LightStyle[i].rgb[2] = 1.0f; _LightStyle[i].white = 3.0f; } CClient.cl.RefDef.lightstyles = _LightStyle; // jkrige ?? //if (!gl_state.lightmap_textures) //{ // gl_state.lightmap_textures = TEXNUM_LIGHTMAPS; //} // jkrige ?? CProgram.gQ2Game.gCMain.gCImage.StartLightmaps(ref _SModel); LM_InitBlock(); }
private void Mod_LoadLighting(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { if (header.lumps[LUMP_LIGHTING].filelen == 0) { _SModel.lightdata = null; return; } br.BaseStream.Seek(header.lumps[LUMP_LIGHTING].fileofs, System.IO.SeekOrigin.Begin); _SModel.lightdata = br.ReadBytes(header.lumps[LUMP_LIGHTING].filelen); }
private void Mod_SetParent(ref CModel.SModel _SModel, int idx_node, int idx_parent) { _SModel.nodes[idx_node].parent = idx_parent; if (_SModel.nodes[idx_node].contents != -1) { return; } Mod_SetParent(ref _SModel, _SModel.nodes[idx_node].children[0], idx_node); Mod_SetParent(ref _SModel, _SModel.nodes[idx_node].children[1], idx_node); }
private void Mod_LoadSurfedges(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <int> DSurfEdge = new List <int>(); br.BaseStream.Seek(header.lumps[LUMP_SURFEDGES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_SURFEDGES].fileofs + header.lumps[LUMP_SURFEDGES].filelen)) { DSurfEdge.Add(br.ReadInt32()); } _SModel.numsurfedges = DSurfEdge.Count; _SModel.surfedges = DSurfEdge.ToArray(); }
private void Mod_LoadPlanes(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { int bits; float[] normal = new float[3]; List <CShared.SCPlane> CPlane = new List <CShared.SCPlane>(); br.BaseStream.Seek(header.lumps[LUMP_PLANES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_PLANES].fileofs + header.lumps[LUMP_PLANES].filelen)) { CShared.SCPlane _CPlane; normal[0] = 0.0f; normal[1] = 0.0f; normal[2] = 0.0f; bits = 0; for (int j = 0; j < 3; j++) { normal[j] = br.ReadSingle(); if (normal[j] < 0) { bits |= 1 << j; } } _CPlane.normal.X = normal[0]; _CPlane.normal.Y = normal[1]; _CPlane.normal.Z = normal[2]; _CPlane.dist = br.ReadSingle(); _CPlane.type = (byte)br.ReadInt32(); _CPlane.signbits = (byte)bits; _CPlane.pad = new byte[2]; CPlane.Add(_CPlane); } _SModel.planes = CPlane.ToArray(); _SModel.numplanes = _SModel.planes.Length; }
public void FloodAreaConnections(ref CModel.SModel _SModel) { int floodnum; // all current floods are now invalid floodvalid++; floodnum = 0; // area 0 is not used for (int i = 1; i < _SModel.numareas; i++) { if (_SModel.areas[i].floodvalid == floodvalid) { continue; // already flooded into } floodnum++; FloodArea_r(_SModel, ref _SModel.areas[i], floodnum); } }
private void Mod_LoadVertexes(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <CModel.SMVertex> MVertex = new List <CModel.SMVertex>(); br.BaseStream.Seek(header.lumps[LUMP_VERTEXES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_VERTEXES].fileofs + header.lumps[LUMP_VERTEXES].filelen)) { CModel.SMVertex _MVertex; _MVertex.Position.X = br.ReadSingle(); _MVertex.Position.Y = br.ReadSingle(); _MVertex.Position.Z = br.ReadSingle(); MVertex.Add(_MVertex); } _SModel.numvertexes = MVertex.Count; _SModel.vertexes = MVertex.ToArray(); }
private void Mod_LoadEntityString(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { if (header.lumps[LUMP_ENTITIES].filelen > MAX_MAP_ENTSTRING) { // entity string exceeds maximum _SModel.map_entitystring = null; return; } br.BaseStream.Seek(header.lumps[LUMP_ENTITIES].fileofs, System.IO.SeekOrigin.Begin); if (br.BaseStream.Position < (header.lumps[LUMP_ENTITIES].fileofs + header.lumps[LUMP_ENTITIES].filelen)) { _SModel.map_entitystring = CShared.Com_ToString(br.ReadChars(header.lumps[LUMP_ENTITIES].filelen)); _SModel.map_entitystring = _SModel.map_entitystring.Replace("\r", "").Replace("\n", "\r\n"); } else { _SModel.map_entitystring = null; } }
private void Mod_LoadMarksurfaces(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <int> MarkSurface = new List <int>(); br.BaseStream.Seek(header.lumps[LUMP_LEAFFACES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_LEAFFACES].fileofs + header.lumps[LUMP_LEAFFACES].filelen)) { int msurf = br.ReadInt16(); if (msurf < 0 || msurf >= _SModel.numsurfaces) { CMain.Error(CMain.EErrorParm.ERR_FATAL, "Mod_ParseMarksurfaces: bad surface number"); } MarkSurface.Add(msurf); } _SModel.nummarksurfaces = MarkSurface.Count; _SModel.marksurfaces = MarkSurface.ToArray(); }
private void Mod_LoadEdges(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <CModel.SMEdge> MEdge = new List <CModel.SMEdge>(); br.BaseStream.Seek(header.lumps[LUMP_EDGES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_EDGES].fileofs + header.lumps[LUMP_EDGES].filelen)) { CModel.SMEdge _MEdge; _MEdge.v = new ushort[2]; _MEdge.v[0] = br.ReadUInt16(); _MEdge.v[1] = br.ReadUInt16(); _MEdge.cachededgeoffset = 0; MEdge.Add(_MEdge); } _SModel.numedges = MEdge.Count; _SModel.edges = MEdge.ToArray(); }
// ================================================================ // // AREAPORTALS // // ================================================================ public void FloodArea_r(CModel.SModel _SModel, ref CModel.SMArea area, int floodnum) { if (area.floodvalid == floodvalid) { if (area.floodnum == floodnum) { return; } System.Diagnostics.Debug.WriteLine("FloodArea_r: reflooded"); return; } area.floodnum = floodnum; area.floodvalid = floodvalid; for (int i = 0; i < area.numareaportals; i++) { if (portalopen[_SModel.areaportals[area.firstareaportal + i].portalnum] == true) { FloodArea_r(_SModel, ref _SModel.areas[_SModel.areaportals[area.firstareaportal + i].otherarea], floodnum); } } }
public void Mod_LoadBrushModel(ref CModel.SModel _SModel, MemoryStream ms) { SDHeader header; List <SLump> lumps; BinaryReader br; ms.Seek(0, System.IO.SeekOrigin.Begin); br = new BinaryReader(ms); if (worldMapLoaded == true) { CMain.Error(CMain.EErrorParm.ERR_FATAL, "ERROR: attempted to redundantly load world map"); return; } worldMapLoaded = true; _SModel.ModType = CModel.EModType.MOD_BRUSH; header.ident = br.ReadInt32(); if (header.ident != IDBSPHEADER) { CMain.Error(CMain.EErrorParm.ERR_WARNING, "RE_LoadWorldMap: " + _SModel.name + " has wrong identity."); return; } header.version = br.ReadInt32(); if (header.version != BSP_VERSION) { CMain.Error(CMain.EErrorParm.ERR_FATAL, "RE_LoadWorldMap: " + _SModel.name + " has wrong version number (" + header.version.ToString() + " should be " + BSP_VERSION.ToString() + ")"); return; } lumps = new List <SLump>(); for (int i = 0; i < HEADER_LUMPS; i++) { SLump _lump; _lump.fileofs = br.ReadInt32(); _lump.filelen = br.ReadInt32(); lumps.Add(_lump); } header.lumps = lumps.ToArray(); CProgram.gQ2Game.gCMain.gCImage.StartWAL(ref _SModel); // load into heap Mod_LoadVertexes(header, ref _SModel, ref br); Mod_LoadEdges(header, ref _SModel, ref br); Mod_LoadSurfedges(header, ref _SModel, ref br); Mod_LoadLighting(header, ref _SModel, ref br); Mod_LoadPlanes(header, ref _SModel, ref br); Mod_LoadTexinfo(header, ref _SModel, ref br); Mod_LoadFaces(header, ref _SModel, ref br); Mod_LoadMarksurfaces(header, ref _SModel, ref br); Mod_LoadVisibility(header, ref _SModel, ref br); Mod_LoadNodesAndLeafs(header, ref _SModel, ref br); Mod_LoadSubmodels(header, ref _SModel, ref br); Mod_LoadAreas(header, ref _SModel, ref br); Mod_LoadAreaPortals(header, ref _SModel, ref br); Mod_LoadEntityString(header, ref _SModel, ref br); _SModel.numframes = 2; // set up the submodels for (int i = 0; i < _SModel.numsubmodels; i++) { CModel.SMModel bm; CModel.SModel starmod; bm = _SModel.submodels[i]; starmod = CProgram.gQ2Game.gCMain.gCModel.mod_inline[i]; starmod.ModType = CModel.EModType.MOD_BRUSH; starmod.firstmodelsurface = bm.firstface; starmod.nummodelsurfaces = bm.numfaces; starmod.firstnode = bm.headnode; if (starmod.firstnode >= _SModel.numnodes) { System.Diagnostics.Debug.WriteLine("Inline model " + i.ToString() + " has bad firstnode"); } starmod.maxs = bm.bounds.Max; starmod.mins = bm.bounds.Min; starmod.radius = bm.radius; starmod.numleafs = bm.visleafs; CProgram.gQ2Game.gCMain.gCModel.mod_inline[i] = starmod; } CProgram.gQ2Game.gCMain.gCImage.FinalizeWAL(ref _SModel); portalopen = new bool[MAX_MAP_AREAPORTALS]; FloodAreaConnections(ref _SModel); }
/// <summary> /// EndBuildingLightmaps /// -------------------- /// Finalizes the processed lightmaps /// </summary> public void EndBuildingLightmaps(ref CModel.SModel _SModel) { LM_UploadBlock(false); CProgram.gQ2Game.gCMain.gCImage.FinalizeLightmaps(ref _SModel); }
private void Mod_LoadSubmodels(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <SDModel> DModel = new List <SDModel>(); List <CModel.SMModel> MModel = new List <CModel.SMModel>(); br.BaseStream.Seek(header.lumps[LUMP_MODELS].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_MODELS].fileofs + header.lumps[LUMP_MODELS].filelen)) { SDModel _DModel; _DModel.mins = new float[3]; _DModel.mins[0] = br.ReadSingle(); _DModel.mins[1] = br.ReadSingle(); _DModel.mins[2] = br.ReadSingle(); _DModel.maxs = new float[3]; _DModel.maxs[0] = br.ReadSingle(); _DModel.maxs[1] = br.ReadSingle(); _DModel.maxs[2] = br.ReadSingle(); _DModel.origin = new float[3]; _DModel.origin[0] = br.ReadSingle(); _DModel.origin[1] = br.ReadSingle(); _DModel.origin[2] = br.ReadSingle(); _DModel.headnode = br.ReadInt32(); _DModel.firstface = br.ReadInt32(); _DModel.numfaces = br.ReadInt32(); DModel.Add(_DModel); } for (int i = 0; i < DModel.Count; i++) { CModel.SMModel _MModel; _MModel.bounds.Min.X = DModel[i].mins[0] - 1; _MModel.bounds.Min.Y = DModel[i].mins[1] - 1; _MModel.bounds.Min.Z = DModel[i].mins[2] - 1; _MModel.bounds.Max.X = DModel[i].maxs[0] + 1; _MModel.bounds.Max.Y = DModel[i].maxs[1] + 1; _MModel.bounds.Max.Z = DModel[i].maxs[2] + 1; _MModel.origin.X = DModel[i].origin[0]; _MModel.origin.Y = DModel[i].origin[1]; _MModel.origin.Z = DModel[i].origin[2]; _MModel.radius = RadiusFromBounds(_MModel.bounds); _MModel.headnode = DModel[i].headnode; _MModel.firstface = DModel[i].firstface; _MModel.numfaces = DModel[i].numfaces; _MModel.visleafs = 0; MModel.Add(_MModel); } _SModel.numsubmodels = MModel.Count; _SModel.submodels = MModel.ToArray(); }
/// <summary> /// R_BuildLightMap /// --------------- /// Combine and scale multiple lightmaps into the floating format in blocklights /// </summary> public void BuildLightMap(CModel.SModel _SModel, ref CModel.SMSurface surf, int dest_pos, ref byte[] dest, int stride) { int smax, tmax; int r, g, b, a, max; int size; int lightmap; float[] scale; int nummaps; float[] bl; CLocal.SLightStyle style; int bl_pos; float modulate = 1.0f; if ( (_SModel.texinfo[surf.texinfo].flags & CQ2BSP.ESurface.SURF_SKY) == CQ2BSP.ESurface.SURF_SKY | (_SModel.texinfo[surf.texinfo].flags & CQ2BSP.ESurface.SURF_TRANS33) == CQ2BSP.ESurface.SURF_TRANS33 | (_SModel.texinfo[surf.texinfo].flags & CQ2BSP.ESurface.SURF_TRANS66) == CQ2BSP.ESurface.SURF_TRANS66 | (_SModel.texinfo[surf.texinfo].flags & CQ2BSP.ESurface.SURF_WARP) == CQ2BSP.ESurface.SURF_WARP ) { CMain.Error(CMain.EErrorParm.ERR_WARNING, "BuildLightMap called for non-lit surface"); } smax = (surf.extents[0] >> 4) + 1; tmax = (surf.extents[1] >> 4) + 1; size = smax * tmax; if (size > ((sizeof(float) * s_blocklights.Length) >> 4)) { CMain.Error(CMain.EErrorParm.ERR_WARNING, "Bad s_blocklights size"); } // set to full bright if no light data if (surf.samples == -1) { for (int i = 0; i < size * 3; i++) { s_blocklights[i] = 255; } for (int maps = 0; maps < CQ2BSP.MAXLIGHTMAPS && surf.styles[maps] != 255; maps++) { style = CClient.cl.RefDef.lightstyles[surf.styles[maps]]; } goto store; } // count the # of maps for (nummaps = 0; nummaps < CQ2BSP.MAXLIGHTMAPS && surf.styles[nummaps] != 255; nummaps++) { ; } lightmap = surf.samples; // add all the lightmaps if (nummaps == 1) { scale = new float[3]; for (int maps = 0; maps < CQ2BSP.MAXLIGHTMAPS && surf.styles[maps] != 255; maps++) { bl = s_blocklights; bl_pos = 0; for (int i = 0; i < 3; i++) { scale[i] = modulate * CClient.cl.RefDef.lightstyles[surf.styles[maps]].rgb[i]; } if (scale[0] == 1.0f && scale[1] == 1.0f && scale[2] == 1.0f) { for (int i = 0; i < size; i++, bl_pos += 3) { bl[bl_pos + 0] = _SModel.lightdata[lightmap + (i * 3) + 0]; bl[bl_pos + 1] = _SModel.lightdata[lightmap + (i * 3) + 1]; bl[bl_pos + 2] = _SModel.lightdata[lightmap + (i * 3) + 2]; } } else { for (int i = 0; i < size; i++, bl_pos += 3) { bl[bl_pos + 0] = _SModel.lightdata[lightmap + (i * 3) + 0] * scale[0]; bl[bl_pos + 1] = _SModel.lightdata[lightmap + (i * 3) + 1] * scale[1]; bl[bl_pos + 2] = _SModel.lightdata[lightmap + (i * 3) + 2] * scale[2]; } } // skip to next lightmap lightmap += size * 3; } } else { scale = new float[3]; for (int i = 0; i < (sizeof(float) * size * 3); i++) { s_blocklights[i] = 0; } for (int maps = 0; maps < CQ2BSP.MAXLIGHTMAPS && surf.styles[maps] != 255; maps++) { bl = s_blocklights; bl_pos = 0; for (int i = 0; i < 3; i++) { scale[i] = modulate * CClient.cl.RefDef.lightstyles[surf.styles[maps]].rgb[i]; } if (scale[0] == 1.0f && scale[1] == 1.0f && scale[2] == 1.0f) { for (int i = 0; i < size; i++, bl_pos += 3) { bl[bl_pos + 0] += _SModel.lightdata[lightmap + (i * 3) + 0]; bl[bl_pos + 1] += _SModel.lightdata[lightmap + (i * 3) + 1]; bl[bl_pos + 2] += _SModel.lightdata[lightmap + (i * 3) + 2]; } } else { for (int i = 0; i < size; i++, bl_pos += 3) { bl[bl_pos + 0] += _SModel.lightdata[lightmap + (i * 3) + 0] * scale[0]; bl[bl_pos + 1] += _SModel.lightdata[lightmap + (i * 3) + 1] * scale[1]; bl[bl_pos + 2] += _SModel.lightdata[lightmap + (i * 3) + 2] * scale[2]; } } // skip to next lightmap lightmap += size * 3; } } // add all the dynamic lights //if (surf.dlightframe == CMain.r_framecount) // R_AddDynamicLights(surf); // put into texture format store: stride -= (smax << 2); bl = s_blocklights; bl_pos = 0; for (int i = 0; i < tmax; i++, dest_pos += stride) { for (int j = 0; j < smax; j++) { r = Convert.ToInt32(bl[bl_pos + 0]); g = Convert.ToInt32(bl[bl_pos + 1]); b = Convert.ToInt32(bl[bl_pos + 2]); // catch negative lights if (r < 0) { r = 0; } if (g < 0) { g = 0; } if (b < 0) { b = 0; } // determine the brightest of the three color components if (r > g) { max = r; } else { max = g; } if (b > max) { max = b; } // alpha is ONLY used for the mono lightmap case. For this reason // we set it to the brightest of the color components so that // things don't get too dim. a = max; // rescale all the color components if the intensity of the greatest // channel exceeds 1.0 if (max > 255) { float t = 255.0f / max; r = (int)(r * t); g = (int)(g * t); b = (int)(b * t); a = (int)(a * t); } dest[dest_pos + 0] = (byte)r; dest[dest_pos + 1] = (byte)g; dest[dest_pos + 2] = (byte)b; dest[dest_pos + 3] = (byte)a; bl_pos += 3; dest_pos += 4; } } }
private void Mod_LoadTexinfo(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <CModel.SMTexInfo> MTexInfo = new List <CModel.SMTexInfo>(); br.BaseStream.Seek(header.lumps[LUMP_TEXINFO].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_TEXINFO].fileofs + header.lumps[LUMP_TEXINFO].filelen)) { CModel.SMTexInfo _MTexInfo; string texture; int next; _MTexInfo.vecs = new Microsoft.Xna.Framework.Vector4[2]; for (int i = 0; i < 2; i++) { _MTexInfo.vecs[i].X = br.ReadSingle(); _MTexInfo.vecs[i].Y = br.ReadSingle(); _MTexInfo.vecs[i].Z = br.ReadSingle(); _MTexInfo.vecs[i].W = br.ReadSingle(); } _MTexInfo.flags = (ESurface)br.ReadInt32(); br.ReadInt32(); // value texture = CShared.Com_ToString(br.ReadChars(32)); texture = "textures/" + texture; next = br.ReadInt32(); if (next > 0) { _MTexInfo.next = next; } else { _MTexInfo.next = 0; } _MTexInfo.image = CProgram.gQ2Game.gCMain.gCImage.FindImage(texture, out _MTexInfo.Width, out _MTexInfo.Height, CImage.EImageType.IT_WALL); // TODO //out->image = GL_FindImage (name, it_wall); //if (!out->image) //{ // ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name); // out->image = r_notexture; //} _MTexInfo.numframes = 0; MTexInfo.Add(_MTexInfo); } // count animation frames for (int i = 0; i < MTexInfo.Count; i++) { CModel.SMTexInfo _MTexInfo = MTexInfo[i]; _MTexInfo.numframes = 1; for (int step = _MTexInfo.next; step != 0 && step != i; step = MTexInfo[step].next) { _MTexInfo.numframes++; } MTexInfo[i] = _MTexInfo; } _SModel.numtexinfo = MTexInfo.Count; _SModel.texinfo = MTexInfo.ToArray(); }
private void Mod_LoadFaces(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <SDFace> DFace = new List <SDFace>(); List <CModel.SMSurface> MSurface = new List <CModel.SMSurface>(); br.BaseStream.Seek(header.lumps[LUMP_FACES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_FACES].fileofs + header.lumps[LUMP_FACES].filelen)) { SDFace _DFace; _DFace.planenum = br.ReadUInt16(); _DFace.side = br.ReadInt16(); _DFace.firstedge = br.ReadInt32(); _DFace.numedges = br.ReadInt16(); _DFace.texinfo = br.ReadInt16(); _DFace.styles = br.ReadBytes(MAXLIGHTMAPS); _DFace.lightofs = br.ReadInt32(); DFace.Add(_DFace); } CProgram.gQ2Game.gCMain.gCSurface.BeginBuildingLightmaps(ref _SModel); for (int i = 0; i < DFace.Count; i++) { CModel.SMSurface _MSurface; int side; short ti; _MSurface.firstedge = DFace[i].firstedge; _MSurface.numedges = DFace[i].numedges; _MSurface.flags = 0; _MSurface.polys = null; _MSurface.ibSurface = null; _MSurface.ibData = null; side = DFace[i].side; if (side != 0) { _MSurface.flags |= CModel.EMSurface.SURF_PLANEBACK; } _MSurface.plane = DFace[i].planenum; _MSurface.plane2 = new Microsoft.Xna.Framework.Plane(); ti = DFace[i].texinfo; if (ti < 0 || ti >= _SModel.numtexinfo) { CMain.Error(CMain.EErrorParm.ERR_WARNING, "MOD_LoadBmodel: bad texinfo number"); } _MSurface.texinfo = ti; _MSurface.bounds = CLocal.ClearBounds(); _MSurface.boundsMid.X = 0.0f; _MSurface.boundsMid.Y = 0.0f; _MSurface.boundsMid.Z = 0.0f; _MSurface.lightIndex = null; _MSurface.lightLength = null; _MSurface.texturechain = 0; _MSurface.visframe = 0; // lighting info _MSurface.dlightframe = 0; _MSurface.dlightbits = 0; _MSurface.lightmaptexturenum = 0; _MSurface.styles = new byte[MAXLIGHTMAPS]; for (int j = 0; j < MAXLIGHTMAPS; j++) { _MSurface.styles[j] = DFace[i].styles[j]; } _MSurface.cached_light = null; _MSurface.samples = DFace[i].lightofs; _MSurface.light_s = 0; _MSurface.light_t = 0; _MSurface.dlight_s = 0; _MSurface.dlight_t = 0; _MSurface.extents = null; _MSurface.texturemins = null; CModel.CalcSurfaceExtents(ref _SModel, ref _MSurface); // set the drawing flags if ((_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) == ESurface.SURF_WARP) { _MSurface.flags |= CModel.EMSurface.SURF_DRAWTURB; for (int j = 0; j < 2; j++) { _MSurface.extents[j] = 16384; _MSurface.texturemins[j] = -8192; } // TODO // cut up polygon for warps //SubdivideSurface(i, ref _WorldModel.mfaces[i]); //SubdivideSurface (out); } // create lightmaps and polygons if ( (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_SKY) != ESurface.SURF_SKY && (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_TRANS33) != ESurface.SURF_TRANS33 && (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_TRANS66) != ESurface.SURF_TRANS66 && (_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) != ESurface.SURF_WARP ) { CProgram.gQ2Game.gCMain.gCSurface.CreateSurfaceLightmap(_SModel, ref _MSurface); } if ((_SModel.texinfo[_MSurface.texinfo].flags & ESurface.SURF_WARP) == ESurface.SURF_WARP) { CProgram.gQ2Game.gCMain.gCSurface.BuildPolygonFromSurface(ref _MSurface); } MSurface.Add(_MSurface); } CProgram.gQ2Game.gCMain.gCSurface.EndBuildingLightmaps(ref _SModel); _SModel.numsurfaces = MSurface.Count; _SModel.surfaces = MSurface.ToArray(); }
public void Mod_LoadAliasModel(ref CModel.SModel _SModel, MemoryStream ms) { BinaryReader br; List <string> skinnames; List <CQ2MD2.SSTVert> st; List <CQ2MD2.SDTriangle> triangles; List <CQ2MD2.SAliasFrameDesc> aliasframes; // HACK - prevent model loading if in Heretic II mode if (CProgram.gQ2Game.gCMain.r_htic2 == true) { return; } ms.Seek(0, System.IO.SeekOrigin.Begin); br = new BinaryReader(ms); // identity (header) _SModel.ModelMD2.md2.identification = br.ReadBytes(4); if (_SModel.ModelMD2.md2.identification[0] != 'I' || _SModel.ModelMD2.md2.identification[1] != 'D' || _SModel.ModelMD2.md2.identification[2] != 'P' || _SModel.ModelMD2.md2.identification[3] != '2') { System.Diagnostics.Debug.WriteLine("MDL file " + _SModel.name + " doesn't have IDP2 id"); br.Close(); return; } // model version _SModel.ModelMD2.md2.version = br.ReadInt32(); if (_SModel.ModelMD2.md2.version != ALIAS_VERSION) { System.Diagnostics.Debug.WriteLine(_SModel.name + " has wrong version number (" + _SModel.ModelMD2.md2.version + " should be " + ALIAS_VERSION + ")"); br.Close(); return; } // skin size _SModel.ModelMD2.md2.skinwidth = br.ReadInt32(); _SModel.ModelMD2.md2.skinheight = br.ReadInt32(); if (_SModel.ModelMD2.md2.skinheight > CLocal.MAX_LBM_HEIGHT) { System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has a skin taller than " + CLocal.MAX_LBM_HEIGHT + "."); br.Close(); return; } // frame size _SModel.ModelMD2.md2.framesize = br.ReadInt32(); // number of skins _SModel.ModelMD2.md2.num_skins = br.ReadInt32(); // number of vertices _SModel.ModelMD2.md2.num_xyz = br.ReadInt32(); if (_SModel.ModelMD2.md2.num_xyz > MAX_VERTS) { System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has too many vertices"); br.Close(); return; } // number of st vertices _SModel.ModelMD2.md2.num_st = br.ReadInt32(); if (_SModel.ModelMD2.md2.num_st <= 0) { System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has no st vertices"); br.Close(); return; } // number of triangles _SModel.ModelMD2.md2.num_tris = br.ReadInt32(); if (_SModel.ModelMD2.md2.num_tris <= 0) { System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has no triangles"); br.Close(); return; } // number of gl commands _SModel.ModelMD2.md2.num_glcmds = br.ReadInt32(); // number of frames _SModel.ModelMD2.md2.num_frames = br.ReadInt32(); if (_SModel.ModelMD2.md2.num_frames <= 0) { System.Diagnostics.Debug.WriteLine("model " + _SModel.name + " has no frames"); br.Close(); return; } // load offsets _SModel.ModelMD2.md2.ofs_skins = br.ReadInt32(); // each skin is a MAX_SKINNAME string _SModel.ModelMD2.md2.ofs_st = br.ReadInt32(); // byte offset from start for stverts _SModel.ModelMD2.md2.ofs_tris = br.ReadInt32(); // offset for dtriangles _SModel.ModelMD2.md2.ofs_frames = br.ReadInt32(); // offset for first frame _SModel.ModelMD2.md2.ofs_glcmds = br.ReadInt32(); // offset for strip/fan command list _SModel.ModelMD2.md2.ofs_end = br.ReadInt32(); // end of file // // load the skin names // skinnames = new List <string>(); for (int i = 0; i < _SModel.ModelMD2.md2.num_skins; i++) { skinnames.Add(CShared.Com_ToString(br.ReadChars(MAX_SKINNAME))); } if (skinnames.Count != 0) { _SModel.ModelMD2.skinnames = skinnames.ToArray(); skinnames.Clear(); skinnames = null; } // // load base s and t vertices (not used in gl version) // st = new List <SSTVert>(); for (int i = 0; i < _SModel.ModelMD2.md2.num_st; i++) { SSTVert _SSTVert; _SSTVert.s = br.ReadInt16(); _SSTVert.t = br.ReadInt16(); st.Add(_SSTVert); } if (st.Count != 0) { _SModel.ModelMD2.st = st.ToArray(); st.Clear(); st = null; } // // load the triangles // triangles = new List <SDTriangle>(); for (int i = 0; i < _SModel.ModelMD2.md2.num_tris; i++) { SDTriangle _SDTriangle; _SDTriangle.index_xyz = new short[3]; _SDTriangle.index_xyz[0] = br.ReadInt16(); _SDTriangle.index_xyz[1] = br.ReadInt16(); _SDTriangle.index_xyz[2] = br.ReadInt16(); _SDTriangle.index_st = new short[3]; _SDTriangle.index_st[0] = br.ReadInt16(); _SDTriangle.index_st[1] = br.ReadInt16(); _SDTriangle.index_st[2] = br.ReadInt16(); triangles.Add(_SDTriangle); } if (triangles.Count != 0) { _SModel.ModelMD2.triangles = triangles.ToArray(); triangles.Clear(); triangles = null; } // // load the frames // aliasframes = new List <SAliasFrameDesc>(); for (int i = 0; i < _SModel.ModelMD2.md2.num_frames; i++) { SAliasFrameDesc _SAliasFrameDesc; _SAliasFrameDesc.scale = new float[3]; _SAliasFrameDesc.scale[0] = br.ReadSingle(); _SAliasFrameDesc.scale[1] = br.ReadSingle(); _SAliasFrameDesc.scale[2] = br.ReadSingle(); _SAliasFrameDesc.translate = new float[3]; _SAliasFrameDesc.translate[0] = br.ReadSingle(); _SAliasFrameDesc.translate[1] = br.ReadSingle(); _SAliasFrameDesc.translate[2] = br.ReadSingle(); _SAliasFrameDesc.name = br.ReadChars(16); _SAliasFrameDesc.verts = new STrivertx[_SModel.ModelMD2.md2.num_xyz]; for (int j = 0; j < _SModel.ModelMD2.md2.num_xyz; j++) { _SAliasFrameDesc.verts[j].v = new byte[3]; _SAliasFrameDesc.verts[j].v[0] = br.ReadByte(); _SAliasFrameDesc.verts[j].v[1] = br.ReadByte(); _SAliasFrameDesc.verts[j].v[2] = br.ReadByte(); _SAliasFrameDesc.verts[j].lightnormalindex = br.ReadByte(); } aliasframes.Add(_SAliasFrameDesc); } if (aliasframes.Count != 0) { _SModel.ModelMD2.aliasframes = aliasframes.ToArray(); aliasframes.Clear(); aliasframes = null; } // // load the gl commands // _SModel.ModelMD2.glcmds = br.ReadBytes(_SModel.ModelMD2.md2.num_glcmds * sizeof(int)); // set the model type _SModel.ModType = CModel.EModType.MOD_ALIAS; // register all skins _SModel.ModelMD2.skins = new Microsoft.Xna.Framework.Graphics.Texture2D[_SModel.ModelMD2.md2.num_skins]; for (int i = 0; i < _SModel.ModelMD2.md2.num_skins; i++) { _SModel.ModelMD2.skins[i] = CProgram.gQ2Game.gCMain.gCImage.LoadSkin(_SModel.ModelMD2.skinnames[i]); } // set default mins/maxs _SModel.mins.X = -32; _SModel.mins.Y = -32; _SModel.mins.Z = -32; _SModel.maxs.X = 32; _SModel.maxs.Y = 32; _SModel.maxs.Z = 32; // close the binary reader br.Close(); br = null; // close the memory stream ms.Close(); ms = null; BuildAliasModelBuffer(ref _SModel.ModelMD2); }
private void Mod_LoadNodesAndLeafs(SDHeader header, ref CModel.SModel _SModel, ref System.IO.BinaryReader br) { List <SDNode> DNode = new List <SDNode>(); List <SDLeaf> DLeaf = new List <SDLeaf>(); List <CModel.SMNode> MNode = new List <CModel.SMNode>(); // load nodes br.BaseStream.Seek(header.lumps[LUMP_NODES].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_NODES].fileofs + header.lumps[LUMP_NODES].filelen)) { SDNode _DNode; _DNode.planenum = br.ReadInt32(); _DNode.children = new int[2]; _DNode.children[0] = br.ReadInt32(); _DNode.children[1] = br.ReadInt32(); _DNode.mins = new short[3]; _DNode.mins[0] = br.ReadInt16(); _DNode.mins[1] = br.ReadInt16(); _DNode.mins[2] = br.ReadInt16(); _DNode.maxs = new short[3]; _DNode.maxs[0] = br.ReadInt16(); _DNode.maxs[1] = br.ReadInt16(); _DNode.maxs[2] = br.ReadInt16(); _DNode.firstface = br.ReadUInt16(); _DNode.numfaces = br.ReadUInt16(); DNode.Add(_DNode); } for (int i = 0; i < DNode.Count; i++) { CModel.SMNode _MNode; int p; _MNode.bounds.Min.X = DNode[i].mins[0]; _MNode.bounds.Min.Y = DNode[i].mins[1]; _MNode.bounds.Min.Z = DNode[i].mins[2]; _MNode.bounds.Max.X = DNode[i].maxs[0]; _MNode.bounds.Max.Y = DNode[i].maxs[1]; _MNode.bounds.Max.Z = DNode[i].maxs[2]; _MNode.plane = DNode[i].planenum; _MNode.firstsurface = DNode[i].firstface; _MNode.numsurfaces = DNode[i].numfaces; _MNode.contents = -1; // differentiate from leafs _MNode.children = new int[2]; for (int j = 0; j < 2; j++) { p = DNode[i].children[j]; if (p >= 0) { _MNode.children[j] = p; } else { _MNode.children[j] = DNode.Count + (-1 - p); } } _MNode.parent = 0; _MNode.visframe = 0; // leaf specific _MNode.cluster = 0; _MNode.area = 0; _MNode.firstmarksurface = 0; _MNode.nummarksurfaces = 0; MNode.Add(_MNode); } // load leafs br.BaseStream.Seek(header.lumps[LUMP_LEAFS].fileofs, System.IO.SeekOrigin.Begin); while (br.BaseStream.Position < (header.lumps[LUMP_LEAFS].fileofs + header.lumps[LUMP_LEAFS].filelen)) { SDLeaf _DLeaf; _DLeaf.contents = br.ReadInt32(); _DLeaf.cluster = br.ReadInt16(); _DLeaf.area = br.ReadInt16(); _DLeaf.mins = new short[3]; _DLeaf.mins[0] = br.ReadInt16(); _DLeaf.mins[1] = br.ReadInt16(); _DLeaf.mins[2] = br.ReadInt16(); _DLeaf.maxs = new short[3]; _DLeaf.maxs[0] = br.ReadInt16(); _DLeaf.maxs[1] = br.ReadInt16(); _DLeaf.maxs[2] = br.ReadInt16(); _DLeaf.firstleafface = br.ReadUInt16(); _DLeaf.numleaffaces = br.ReadUInt16(); _DLeaf.firstleafbrush = br.ReadUInt16(); _DLeaf.numleafbrushes = br.ReadUInt16(); DLeaf.Add(_DLeaf); } for (int i = 0; i < DLeaf.Count; i++) { CModel.SMNode _MNode; _MNode.bounds.Min.X = DLeaf[i].mins[0]; _MNode.bounds.Min.Y = DLeaf[i].mins[1]; _MNode.bounds.Min.Z = DLeaf[i].mins[2]; _MNode.bounds.Max.X = DLeaf[i].maxs[0]; _MNode.bounds.Max.Y = DLeaf[i].maxs[1]; _MNode.bounds.Max.Z = DLeaf[i].maxs[2]; _MNode.contents = DLeaf[i].contents; _MNode.cluster = DLeaf[i].cluster; _MNode.area = DLeaf[i].area; _MNode.firstmarksurface = DLeaf[i].firstleafface; _MNode.nummarksurfaces = DLeaf[i].numleaffaces; _MNode.parent = 0; _MNode.visframe = 0; // node specific _MNode.plane = 0; _MNode.firstsurface = 0; _MNode.numsurfaces = 0; _MNode.children = null; MNode.Add(_MNode); } _SModel.numnodes = DNode.Count + DLeaf.Count; _SModel.numDecisionNodes = DNode.Count; _SModel.numleafs = DLeaf.Count; _SModel.nodes = MNode.ToArray(); // chain decendants Mod_SetParent(ref _SModel, 0, -1); }