Hi,
I've had a frustrating night. I'm writing a dual-api render engine and am trying to settle on a matrix handling implementation.
What I have has started to get a bit hairy, so I've decided to down tools for the night and start afresh tomorrow with a clean slate.
Two things:
As DirectX stores matrices in row-major format and OpenGL in column-major, I can keep my intermediate storage in just one of these formats, do my operations and then transpose it at the last minute before it is applied, correct?
Second, at more importantly, when multiple matrices are stacked together, do both APIs expect the matrices to be multiplied in opposite orders to get the same end result?
Simple Example:
DirectX: World Transform x Object Rotate x Object Translate
OpenGL : ObjectTranslate x Object Rotate x World Transform
Tbh I'm having difficulty getting opengl to render at all, and am testing in wireframe mode at the moment.
Thanks
Matrices (DirectX and OpenGL)
OpenGL and Direct3D use different view volumes. (For OpenGL see the chapter "Primitive Clipping" in the specification)
In OpenGL the view volume is given by
-w <= x <= w
-w <= y <= w
-w <= z <= w
but Direct3D uses
-w < x <= w
-w < y <= w
0 < z <= w
you have to take this into account.
In OpenGL the view volume is given by
-w <= x <= w
-w <= y <= w
-w <= z <= w
but Direct3D uses
-w < x <= w
-w < y <= w
0 < z <= w
you have to take this into account.
Both DirectX and OpenGL have exact same memory layout for a matrix. IIRC, the difference comes in the order you preform multiplications.
In GLSL you'd end up with the equivelent of (maybe you pre-multiply some of these before sending them to the shader):
outVetex = perspective * camera * model * inVertex;
But I can't be positive about the directX side as I haven't used it.
In GLSL you'd end up with the equivelent of (maybe you pre-multiply some of these before sending them to the shader):
outVetex = perspective * camera * model * inVertex;
But I can't be positive about the directX side as I haven't used it.
Quote:Original post by KulSeran
Both DirectX and OpenGL have exact same memory layout for a matrix. IIRC, the difference comes in the order you preform multiplications.
In GLSL you'd end up with the equivelent of (maybe you pre-multiply some of these before sending them to the shader):
outVetex = perspective * camera * model * inVertex;
But I can't be positive about the directX side as I haven't used it.
HLSL doesn't care which multiplication method you use the intrinsic functions support both as long as you are consistant.
You have to pass your projection, view and world(GL combines the last two into the modelview matrix) as uniforms they are not built in like in GLSL.
As long as you do your operations before you transpose you can keep the order the same for both OGL and D3D, be carefull with any operations on transposed matrices though as it is easy to forget if they are or not.
So, if I'm using glLoadMatrix* to copy my matrix into memory, does that mean I *don't* need to transpose it before doing so?
Quote:Original post by steviediscoIf you're using glLoad/MultMatrix*(), then the only requirement is that data be arranged in memory as OpenGL expects it, which is as 16 consecutive floats/doubles/etc., with basis vector elements arranged contiguously in memory.
So, if I'm using glLoadMatrix* to copy my matrix into memory, does that mean I *don't* need to transpose it before doing so?
In practical terms, this means you can use row-basis matrices with row-major storage, or column-basis matrices with column-major storage (whichever you prefer).
the other thing to consider, with dx effects
is that matrices will be passed to effects with column_major packing
because this allows the compiler to convert:
mul(row, matrix)
into 4 dot products
but the HLSL *syntax* for matrix declaration and component access is unaffected by this and will always be in row_major packing
so if you mix and match row_major and column_major packing in HLSL
there are no syntax changes required - but the asm output will be different
this lets you tweak the packing to match your syntax and find the best performance
(afaik)
this helps me understand it:
[Edited by - skytiger on November 12, 2010 6:29:33 AM]
is that matrices will be passed to effects with column_major packing
because this allows the compiler to convert:
mul(row, matrix)
into 4 dot products
but the HLSL *syntax* for matrix declaration and component access is unaffected by this and will always be in row_major packing
so if you mix and match row_major and column_major packing in HLSL
there are no syntax changes required - but the asm output will be different
this lets you tweak the packing to match your syntax and find the best performance
(afaik)
this helps me understand it:
LOGICAL PHYSICAL ROW MAJOR11 12 13 14 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 4421 22 23 2431 32 33 34 PHYSICAL COLUMN MAJOR41 42 43 44 11 21 31 41 12 22 32 42 13 23 33 43 14 24 34 44MATRIX CONVENTIONROW * MATRIX (DIRECTX)X Y Z 0 TRANSLATION IS STORED IN LOGICAL 41 42 43X Y Z 0X Y Z 0TX TY TZ 1MATRIX * COL (OPENGL)X X X TX TRANSLATION IS STORED IN LOGICAL 14 24 34Y Y Y TYZ Z Z TZ0 0 0 1DIRECTX (ROW * MATRIX) PHYSICAL ROW_MAJOR11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44 TX TY TZOPENGL (MATRIX * COL) PHYSICAL COLUMN_MAJOR11 21 31 41 12 22 32 42 13 23 33 43 14 24 34 44 TX TY TZHLSL FLOAT4X4 IS STORED IN COLUMN_MAJORTHIS MEANS THAT MUL(ROW, MATRIX) CAN BE COMPILED AS 4 DOT PRODUCTS
[Edited by - skytiger on November 12, 2010 6:29:33 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement