MS3D Texture Array.
I recently took up the task of making my ms3d loader compatible with vertex arrays. Which has been successfuly so far. I made a parser application which modified the triangle structure so that all the vertex indices were right next to each other. i could then point to the first vertex indice specified in the mesh struct specify how many to draw from the meshs triangle count variable and draw the mesh. My draw loop merely jumps to the next mesh and then its around 10 lines of ASSEMBLY code to setup the draw, nice eh?
Kinda like this:
Indice1,Normal1,Tex1,Indice2,Normal2,Tex2 becomes -> Indice1 Indice2 Tex1 Tex2 Normal1 Normal2
Now onto my problem, When i come to the texture coordinates. The s and t coordinate are separated in m_s[3] and m_t[3] in the triangle structure. so i need to interleave them right? so what i need is this:
m_s[1],m_t[1],m_s[2],m_t[2],m_s[3],m_t[3]
and i did just that. But unfortunatly it doesnt work. When the textures display theyre all distorted and skewed. This tells me that they are wrong. But before i spend several hours trying to port my assembly code into C :D. Am i doing it right? am i meant to do m_s[1],m_t[1],m_s[2],m_t[2],m_s[3],m_t[3]?
In a bit of a rush atm, i can post some much more informative code later on.
Quote:Original post by whyisitalwaysme2Why in all the hells are you writing an OpenGL application in assembly? I could possibly understand it if you were coding one of those 4k demos, but in that case you wouldn't be using a format as inefficient as milkshape.
My draw loop merely jumps to the next mesh and then its around 10 lines of ASSEMBLY code to setup the draw, nice eh?
Quote:But before i spend several hours trying to port my assembly code into C :DAnd why you would then port that assembly code to C is an absolute mystery...
It's about speed/efficiency and control, if your doing something yourself as a hobby, you may as well do it properly. Assembly fair enough, can't actually be used for anything in the *real world* but once you start and see just how much lighter and less bloated it is, programming in c (low level by todays standards) irritates you :p.
As for milkshake, like i said, im building a parser which cuts out all useless information and then reorders it all for use with vertex arrays.etc And yes, its a crap file format. I was going to make an importer and exporter but its all written in c++ and i have to import lib files, so i figured it would be quicker just to parse an ms3d file.
And by porting to c i meant just the bits of code relevant to my problem, so that more people on here could actually make sense of it.
As for milkshake, like i said, im building a parser which cuts out all useless information and then reorders it all for use with vertex arrays.etc And yes, its a crap file format. I was going to make an importer and exporter but its all written in c++ and i have to import lib files, so i figured it would be quicker just to parse an ms3d file.
And by porting to c i meant just the bits of code relevant to my problem, so that more people on here could actually make sense of it.
I just tried something else. When i call glDrawElements, and it looks through the indices does it select texture coordinates out from the array like it does with the vertex coords? in other words do the the indices also index which texture coords to draw as well as which vertex coordinates?
Im really confused. My hex editor is showing a nice clean parse of the data being placed in the right places in my output file :/.
Heres my assembly code for parsing, havent ported it yet. its unoptimized since im constantly redoing it over and over in different ways. Assume Source points to the start of the original files triangle structures.
Im really confused. My hex editor is showing a nice clean parse of the data being placed in the right places in my output file :/.
Heres my assembly code for parsing, havent ported it yet. its unoptimized since im constantly redoing it over and over in different ways. Assume Source points to the start of the original files triangle structures.
mov dword[Counter],0 TransferTriangleTex: mov eax,dword[Counter] mov ecx,70 mul ecx add eax,44 mov ebx,eax add ebx,dword[SourceFilePointer] add ebx,dword[SourceFileBuffer] mov eax,dword[DestinationFileBuffer] add eax,dword[DestinationFilePointer] ;eax= dest, ebx= src mov ecx,dword[ebx] ;s mov dword[eax],ecx mov ecx,dword[ebx+12] mov dword[eax+4],ecx ;t mov ecx,dword[ebx+4] ;s mov dword[eax+8],ecx mov ecx,dword[ebx+16] ;t mov dword[eax+12],ecx mov ecx,dword[ebx+8] ;s mov dword[eax+16],ecx mov ecx,dword[ebx+20] ;t mov dword[eax+20],ecx add dword[DestinationFilePointer],24 inc dword[Counter] mov eax,dword[Count] cmp dword[Counter],eax jne TransferTriangleTex
Quote:Original post by whyisitalwaysme2That assumes that you have sufficient knowledge of instruction scheduling, caching, memory latencies, etc. to optimise better than the compiler. Your code is SIMD optimised, right?
It's about speed/efficiency and control, if your doing something yourself as a hobby, you may as well do it properly.
Quote:Assembly fair enough, can't actually be used for anything in the *real world* but once you start and see just how much lighter and less bloated it is, programming in c (low level by todays standards) irritates you :p.Methinks you missed the entire point of programming languages, if you regard C as bloated in this day and age...
Quote:As for milkshake, like i said, im building a parser which cuts out all useless information and then reorders it all for use with vertex arrays.etc And yes, its a crap file format. I was going to make an importer and exporter but its all written in c++ and i have to import lib files, so i figured it would be quicker just to parse an ms3d file.This is even less a job for assembly. Write a converter in a high-level language (such as python, or ruby), that outputs a slimmed-down binary format you can load with your assembly. Even if you insist on writing your application in assembly for (very dubious) performance reasons, simple tools don't need that level of performance, so you should be writing them in an easy language.
Quote:And by porting to c i meant just the bits of code relevant to my problem, so that more people on here could actually make sense of it.A fair number of us can read ASM - it is a requirement for most CS degrees, after all.
Quote:I just tried something else. When i call glDrawElements, and it looks through the indices does it select texture coordinates out from the array like it does with the vertex coords? in other words do the the indices also index which texture coords to draw as well as which vertex coordinates?All vertex elements use the very same index - i.e each value in the index array specifies the same offset into each of the vertex, normal and texture-coord arrays.
Okay thats ruled something out at least.
Although a lot of people can read asm its not exactly a mainstream language, im not trying to sound elitist or anything, its just i want this solved :/. I do try to follow basic optimization procedures such as caching and byte alignment for memory, i am aware of how complex and intelligent compilers are these days.
SIMD? not so much, Couple of areas where my code could benefit from some SSE/MMX with maybe parallel processing but not enough to make me actually stop and get the intel docs out and spend several hours on a small piece of code for 10-20 cycles. Obviously wherever theres code that does a repeated job on a large amount of data ill be more inclined to go for SIMD optimized first time :p. But this is things like a couple of trig operations for basic movement. This May contradict my previous statement of taking my time or even using assembly at all but i like to get a *section* of a program done before i go back and clean it up.
I could of definetly used python/ruby and hell, i should have. But i had actually written half the code in assembly before i even realised it. You see my code is derived from Nehe's lesson 31 where the guy does all the parsing at load time. I was porting this and realised i should probably run this process on the file at development time instead of runtime. So it was a bit of a copy and paste job but your right, assembly is stupid for this.
Although a lot of people can read asm its not exactly a mainstream language, im not trying to sound elitist or anything, its just i want this solved :/. I do try to follow basic optimization procedures such as caching and byte alignment for memory, i am aware of how complex and intelligent compilers are these days.
SIMD? not so much, Couple of areas where my code could benefit from some SSE/MMX with maybe parallel processing but not enough to make me actually stop and get the intel docs out and spend several hours on a small piece of code for 10-20 cycles. Obviously wherever theres code that does a repeated job on a large amount of data ill be more inclined to go for SIMD optimized first time :p. But this is things like a couple of trig operations for basic movement. This May contradict my previous statement of taking my time or even using assembly at all but i like to get a *section* of a program done before i go back and clean it up.
I could of definetly used python/ruby and hell, i should have. But i had actually written half the code in assembly before i even realised it. You see my code is derived from Nehe's lesson 31 where the guy does all the parsing at load time. I was porting this and realised i should probably run this process on the file at development time instead of runtime. So it was a bit of a copy and paste job but your right, assembly is stupid for this.
Okay in my draw loop i set my vertice pointer to the start of my vertices for all meshes, and since all my triangle structures have been altered to be in chunks. All my normals and texture pointers point to the start of a large array for all meshes.
Here i after i load the file i set the pointers
And Here is my parse loop which is unchanged from yesterday which converts the data file which the above code reads.
Ive kind of narrowed it down to 2 thing. Either theres a tiny barely noticeable mistake *somewhere* or im not actually interleaving the coordinates correctly.
Sorry for the crappy code :/.
Here i after i load the file i set the pointers
;Find Verticesmov eax,[ModelBuffer]movzx ecx,word[eax]mov [VerticeCount],ecxadd eax,2mov [VerticePointer],eax;Find Trianglesmov eax,13mul [VerticeCount]add eax,[VerticePointer]movzx ebx,word[eax]mov [TriangleCount],ebxadd eax,2mov [TrianglePointer],eax;Find Meshesmov eax,66mul [TriangleCount]add eax,[TrianglePointer]movzx ecx,word[eax]mov [MeshCount],ecxadd eax,2mov [MeshPointer],eax;Find Normalsmov eax,6mul [TriangleCount]add eax,[TrianglePointer]mov [NormalPointer],eax;find Texture Coordsmov eax,36mul [TriangleCount]add eax,[NormalPointer]mov [TexturePointer],eax
proc ModelRenderinvoke glVertexPointer,3,GL_FLOAT,0,[VerticePointer]invoke glNormalPointer,GL_FLOAT,0,[NormalPointer]invoke glTexCoordPointer,2,GL_FLOAT,0,[TexturePointer]mov eax,[MeshPointer]mov [CurrentMeshPointer],eaxmov [MeshCounter],0DrawMesh: cmp [MeshCounter],0 je SkipMeshJump mov eax,[MeshTriangleCount] mov ebx,2 mul ebx add eax,3 add [CurrentMeshPointer],eax SkipMeshJump: mov ebx,[CurrentMeshPointer] movzx eax,word[ebx+3] mov ecx,6 mul ecx mov ecx,eax add ecx,[TrianglePointer] movzx eax,word[ebx+1] mov [MeshTriangleCount],eax mov ebx,3 mul ebx invoke glDrawElements,GL_TRIANGLES,eax,GL_UNSIGNED_SHORT,ecxinc [MeshCounter]mov eax,[MeshCount]cmp [MeshCounter],eaxjne DrawMeshretendp
And Here is my parse loop which is unchanged from yesterday which converts the data file which the above code reads.
mov dword[Counter],0 TransferTriangleTex: mov eax,dword[Counter] mov ecx,70 mul ecx add eax,44 mov ebx,eax add ebx,dword[SourceFilePointer] add ebx,dword[SourceFileBuffer] mov eax,dword[DestinationFileBuffer] add eax,dword[DestinationFilePointer] ;eax= dest, ebx= src mov ecx,dword[ebx] ;s mov dword[eax],ecx mov ecx,dword[ebx+12] mov dword[eax+4],ecx ;t mov ecx,dword[ebx+4] ;s mov dword[eax+8],ecx mov ecx,dword[ebx+16] ;t mov dword[eax+12],ecx mov ecx,dword[ebx+8] ;s mov dword[eax+16],ecx mov ecx,dword[ebx+20] ;t mov dword[eax+20],ecx add dword[DestinationFilePointer],24 inc dword[Counter] mov eax,dword[Count] cmp dword[Counter],eax jne TransferTriangleTex
Ive kind of narrowed it down to 2 thing. Either theres a tiny barely noticeable mistake *somewhere* or im not actually interleaving the coordinates correctly.
Sorry for the crappy code :/.
Quote:Original post by whyisitalwaysme2My point is that modern compilers offer automatic SIMD optimisation, as well as all that pesky register allocation and cache optimisation...
SIMD? not so much, Couple of areas where my code could benefit from some SSE/MMX with maybe parallel processing but not enough to make me actually stop and get the intel docs out and spend several hours on a small piece of code for 10-20 cycles.
Quote:Ive kind of narrowed it down to 2 thing. Either theres a tiny barely noticeable mistake *somewhere* or im not actually interleaving the coordinates correctly.Despite my earlier statement, I am finding your assembly pretty hard to follow [smile]
However, it does appear that you are interleaving your texture coordinates correctly, so I would guess a bug somewhere.
Quote:
The t values are all set to 1.0-(original value). The reason for this is that OpenGL uses a lower-left coordinate system, whereas Milkshape uses an upper-left coordinate system for it's texture coordinates. This reverses the y coordinate.
Just went through the nehe tut and noticed that by sheer chance. God dammit. i HATE this file format XD.
okay i made a model with a single triangle. Here is the actual data stored from [TexturePointer] when its non interleaved (note i havent inverted the t coords yet):
What i have currently:
Uninterleaved
S = 3F 00 00 00/00 00 00 00/00 00 00 80
T = 3F 00 00 00/00 00 00 80/3F 00 00 80
Interleaved:
s1 t1 s2 t2 s3 t3
3F 00 00 00/3F 00 00 00/00 00 00 00/00 00 00 80/00 00 00 80/3F 00 00 80
Okay so what i need to know is, which is the negative flag? 80 or 3F?
Once i know this i can calculate the T coords values...make up a triangle in immediate mode with manually calculated coords and see exactly how to arrange them.
So close!
What i have currently:
Uninterleaved
S = 3F 00 00 00/00 00 00 00/00 00 00 80
T = 3F 00 00 00/00 00 00 80/3F 00 00 80
Interleaved:
s1 t1 s2 t2 s3 t3
3F 00 00 00/3F 00 00 00/00 00 00 00/00 00 00 80/00 00 00 80/3F 00 00 80
Okay so what i need to know is, which is the negative flag? 80 or 3F?
Once i know this i can calculate the T coords values...make up a triangle in immediate mode with manually calculated coords and see exactly how to arrange them.
So close!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement