Omens Of War .TER File Format
I've started reverse-engineering the .TER file format that's used in OoW zones and what follows is my progress thus far.
The header is as follows: Code:
struct Header { Each element is a null-terminated name followed by a null-terminated value. If the name starts with 'e_' it is a property of the previous object named, otherwise it's naming a new object and its associated base texture. For example, the list for wall of slaughter is: colmap01 colmap01.dds e_TextureDiffuse0 palmap01a.bmp e_TexturePalette0 HW_rd01_c.dds e_TextureDetail0 e_fScale0 e_fGrassDensity0 FT_RD2_c.dds e_TextureDetail1 e_fScale1 e_fGrassDensity1 FT_path01.dds e_TextureDetail2 e_fScale2 e_fGrassDensity2 FT_plateau01.dds e_TextureDetail3 e_fScale3 e_fGrassDensity3 FT_grass01.dds e_TextureDetail4 e_fScale4 e_fGrassDensity4 FT_plateau02.dds e_TextureDetail5 e_fScale5 e_fGrassDensity5 None e_TextureDetail6 e_fScale6 e_fGrassDensity6 None e_TextureDetail7 e_fScale7 e_fGrassDensity7 None e_TextureDetail8 e_fScale8 e_fGrassDensity8 None e_TextureDetail9 e_fScale9 e_fGrassDensity9 Opaque_MaxC1DTP.fx colmap02 colmap02.dds e_TextureDiffuse0 palmap02a.bmp e_TexturePalette0 HW_rd01_c.dds e_TextureDetail0 e_fScale0 e_fGrassDensity0 FT_RD2_c.dds e_TextureDetail1 e_fScale1 e_fGrassDensity1 FT_path01.dds e_TextureDetail2 e_fScale2 e_fGrassDensity2 FT_plateau01.dds e_TextureDetail3 e_fScale3 e_fGrassDensity3 FT_grass01.dds e_TextureDetail4 e_fScale4 e_fGrassDensity4 FT_plateau02.dds e_TextureDetail5 e_fScale5 e_fGrassDensity5 None e_TextureDetail6 e_fScale6 e_fGrassDensity6 None e_TextureDetail7 e_fScale7 e_fGrassDensity7 None e_TextureDetail8 e_fScale8 e_fGrassDensity8 None e_TextureDetail9 e_fScale9 e_fGrassDensity9 Opaque_MaxC1DTP.fx colmap03 colmap03.dds e_TextureDiffuse0 palmap03a.bmp e_TexturePalette0 HW_rd01_c.dds e_TextureDetail0 e_fScale0 e_fGrassDensity0 FT_RD2_c.dds e_TextureDetail1 e_fScale1 e_fGrassDensity1 FT_path01.dds e_TextureDetail2 e_fScale2 e_fGrassDensity2 FT_plateau01.dds e_TextureDetail3 e_fScale3 e_fGrassDensity3 FT_DRD2_c.dds e_TextureDetail4 e_fScale4 e_fGrassDensity4 FT_plateau02.dds e_TextureDetail5 e_fScale5 e_fGrassDensity5 None e_TextureDetail6 e_fScale6 e_fGrassDensity6 None e_TextureDetail7 e_fScale7 e_fGrassDensity7 None e_TextureDetail8 e_fScale8 e_fGrassDensity8 None e_TextureDetail9 e_fScale9 e_fGrassDensity9 Opaque_MaxC1DTP.fx colmap04 colmap04.dds e_TextureDiffuse0 palmap04a.bmp e_TexturePalette0 HW_rd01_c.dds e_TextureDetail0 e_fScale0 e_fGrassDensity0 FT_RD2_c.dds e_TextureDetail1 e_fScale1 e_fGrassDensity1 FT_path01.dds e_TextureDetail2 e_fScale2 e_fGrassDensity2 FT_plateau01.dds e_TextureDetail3 e_fScale3 e_fGrassDensity3 FT_DRD2_c.dds e_TextureDetail4 e_fScale4 e_fGrassDensity4 FT_plateau02.dds e_TextureDetail5 e_fScale5 e_fGrassDensity5 None e_TextureDetail6 e_fScale6 e_fGrassDensity6 None e_TextureDetail7 e_fScale7 e_fGrassDensity7 None e_TextureDetail8 e_fScale8 e_fGrassDensity8 None e_TextureDetail9 e_fScale9 e_fGrassDensity9 Opaque_MaxC1DTP.fx tunn04 sp_tunn04.dds e_TextureDiffuse0 sp_tunn04_n.dds e_TextureNormal0 Opaque_MaxCB1.fx tunn05 sp_tunn05.dds e_TextureDiffuse0 sp_tunn05_n.dds e_TextureNormal0 Opaque_MaxCB1.fx tunn06 sp_tunn06.dds e_TextureDiffuse0 sp_tunn06_n.dds e_TextureNormal0 Opaque_MaxCB1.fx tunn07 tunn07.dds e_TextureDiffuse0 tunn07_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_wall_T01 sp_ft_wall_high.dds e_TextureDiffuse0 Di_ent_cinderblock01_mid_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_wall_M01 sp_ft_wall_mid.dds e_TextureDiffuse0 Di_ent_cinderblock01_mid_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_wall_B01 sp_ft_wall_low.dds e_TextureDiffuse0 Di_ent_cinderblock01_low_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_arch_T01 ab_arch_T01.dds e_TextureDiffuse0 Di_ent_metal02_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_arch_M01 ab_arch_M01.dds e_TextureDiffuse0 Di_ent_metal02_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_arch_B01 ab_arch_B01.dds e_TextureDiffuse0 Di_ent_metal02_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ab_floor_01 ab_floor_01.dds e_TextureDiffuse0 sp_ft_floor_n.dds e_TextureNormal0 Opaque_MaxCB1.fx rock18 av_rock18_c.dds e_TextureDiffuse0 av_rock18_n.dds e_TextureNormal0 Opaque_MaxCB1.fx rock10 av_rock10_c.dds e_TextureDiffuse0 av_rock10_n.dds e_TextureNormal0 Opaque_MaxCB1.fx rock16 av_rock16_c.dds e_TextureDiffuse0 Di_ent_wall_crumble01_n.dds e_TextureNormal0 Opaque_MaxCB1.fx maze01 av_rock12_c.dds e_TextureDiffuse0 av_rock12_n.dds e_TextureNormal0 Opaque_MaxCB1.fx maze02 Di_rune_plain_bkg_c.dds e_TextureDiffuse0 Di_rune_plain_bkg_n.dds e_TextureNormal0 Opaque_MaxCB1.fx maze03 ab_maze01_c.dds e_TextureDiffuse0 ab_maze01_n.dds e_TextureNormal0 Opaque_MaxCB1.fx maze04 Di_floor01_c.dds e_TextureDiffuse0 Di_floor01_n.dds e_TextureNormal0 Opaque_MaxCB1.fx maze05 Di_Maze01_Power_c.dds e_TextureDiffuse0 Di_Maze01_Main_n.dds e_TextureNormal0 Opaque_MaxCB1.fx ra_pris19 ra_prison19_c.dds e_TextureDiffuse0 ra_prison19_n.dds e_TextureNormal0 Opaque_MaxCB1.fx av_pris14high av_prison14_c.dds e_TextureDiffuse0 av_prison13a_n.dds e_TextureNormal0 Opaque_MaxCB1.fx av_pris22mid av_prison22_c.dds e_TextureDiffuse0 av_prison22_n.dds e_TextureNormal0 Opaque_MaxCB1.fx av_pris15low av_prison15_c.dds e_TextureDiffuse0 av_prison15_n.dds e_TextureNormal0 Opaque_MaxCB1.fx av_pris18flr av_prison18_c.dds e_TextureDiffuse0 av_prison18a_n.dds e_TextureNormal0 Opaque_MaxCB1.fx dn_path HW_rd01_c.dds e_TextureDiffuse0 HW_rd01_n.dds e_TextureNormal0 Opaque_MaxCB1.fx I'll post more as I figure it out. Happy Hacking, Lord Daeken M. BlackBlade (Cody Brocious) Edit #1: Added the object_count element to the struct. Edit #2: Replaced uint32 unk[2]; with the vertex_count and poly_count fields. Put the struct in code brackets. |
You can also get a proper view of it at http://home.archshadow.com/~daeken/t...tress_objs.txt
This is the debug output of my python script for decoding these files, so it's a bit messy still hehe. |
Ok... figured out more.
After the list comes the vertices. The struct for each vertex is as follows: Code:
struct Vertex { |
Well, I just got zone geometry rendering perfectly, albiet without textures (it's figured out, just not coded as of yet) :D
It was very, very simple. Code:
struct Header { Each element is a null-terminated name followed by a null-terminated value. If the name starts with 'e_' it is a property of the previous material named, otherwise it's naming a new material and its associated base texture. If the base texture named starts with e_, leave the base texture empty and treat this name as its own variable. In the case of having no base texture, simply use the first e_ entry value as the texture, but make sure you also set the e_ entry in your material data. Now comes the one portion of the file that I have yet to figure out. My theory is that it is a BSP or octree, but I have yet to test it. To skip it, seek to 3 + (vertex_count * 32) + (poly_count * 20) bytes before the end of the file. I'll work on figuring this out when I get a chance, but my knowledge of BSPs and octrees is so limited its not even funny. Next comes the vertices. You should decode these and store them in a zero-indexed array. Code:
struct Vertex { Code:
struct Triangle { Enjoy :D |
God anguish looks beautiful running in the python version of my ter decoder with full textures ;)
I got it working in about 10 minutes without having to change the file loader... everything was right on the first try :D I would take screenshots, but unfortunately GLUT doesn't want to let me go windowed... Whatever. I'll have the C version rendering .ter soon anyhow :D I will post screenshots ASAP. |
Anguish works great in my renderer but I can't display "riftseekers" at all. I have a problem loading the texture names from the strings at the start. The names seem to get out of step. Does it work for you?
And if so could you try to explain how to get the names decoded properly if you have the time :) Thanks |
I updated the guide (not the parent post, but one of the comments) to fix the material loading... basically, all you have to do is make sure that the base texture given isn't an e_ entry :)
|
Thanks - I'm still having trouble with this though. I think I'll do what you appeared to have done based on your post and write a decoder in python as it's so much easier to prototype stuff and then when it works recode it in c++.
|
I've had a closer look at the materials information and believe it should be formatted like this (just an extract from the riftseekers zone)
Code:
cieling The effects exist as files in the RenderEffects directory on disk. I would guess that they might be encoded directx effects files and the material information in the TER file describes the parameters to them. |
Quote:
Damn man... I can't believe I didn't see that before. Nice work :D |
Now I can get riftseekers to load properly.
Just using the diffuse textures it comes out all blue and orange. I wonder if it really looks like that. |
Dranik zone looks like this with my renderer
http://img57.exs.cx/img57/2686/render06.th.jpg Still some work to go on the textures I think. They almost look scaled wrong although it could just be that simply rendering the diffuse texture isn't enough to get a reasonable output. |
Looks like you may be using the wrong mipmapping level perhaps? I dunno... m'be the bump mapping is neccesary to make it look good...
|
Ah, good guess :)
Setting anisotropic mipmapping mode made it look far better :) |
All times are GMT -4. The time now is 12:13 PM. |
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.