Next Generation Emulation banner

1 - 20 of 50 Posts

·
Registered
Joined
·
423 Posts
Discussion Starter #1 (Edited)
Hi there, some of you have already seen that I'm working on an OpenGL implementation, as OpenGL is far better suited for push-buffer emulation than D3D.
This is mainly due to the fact that D3D needs Index & Vertex buffers for almost everything, while OpenGL can render directly from pointers (using glVertexAttribPointer, glDrawArrays and glDrawElements) and supports immediate mode rendering.​

Alas, I'm a complete newbie to OpenGL, so I could use some help. (StrikerX3 is already helping me out, testing a few things here and there. But like me, he's also new to OpenGL.)

So here a request : Does anyone here have experience with OpenGL and are you willing to help us out a little?

Right now the most important thing that I can't get going, is setting the correct viewport, and projection & model view matrices. (All this either with a simple shader or using the fixed-function pipeline.)

Please take a look at my current code, perhaps you spot a problem or an incorrect assumption - any help is appreciated!
 

·
Linux's worst nightmare..
Joined
·
1,510 Posts
I wish i knew enough opengl to help... sometime in the future i gotta try my hand at 3d programming
 

·
Registered
Joined
·
359 Posts
I just saw on your blog that you were also trying to convert your project (cxbx) to OpenGL, with plans to use CG instead of ARB fragment programs. Are any of the XDK samples displaying?
 

·
Shadow of nothing...
Joined
·
6,071 Posts
I'm testing it (the d3d8_xbox.dll) with the normal DirectX SDK first. So far, everything I added works just fine except lighting. There's no equivalent light parameter for "Range" in OpenGL, afaik.
 

·
Shadow of nothing...
Joined
·
6,071 Posts
We'll need a fixed pipeline implementation because what if the game is already using a shader?
 

·
Registered
Joined
·
423 Posts
Discussion Starter #8 (Edited)
Enlighten me please; What part of the fixed function pipeline is still active when there's also a shader active?

As a sidenote : It seems the NV2A shader pipe doesn't apply the world/view/projection matrix transform yet - as with my push-buffer emulation code I've seen that the Xbox1 D3D implementation still uses a shader program internally when the fixed-functinon shader code contains D3DFVF_XYZRHW (it doesn't seem to do that in the D3DFVF_XYZ and D3DFVF_XYZB* cases). This fixed-function shader only applies multi-sample scaling & offsets; Here the code I got using my not-yet commited vertex shader decoder (the hexadecimal codes are what's put in the push-buffer slots dedicated for vertex-shader programs) :

Code:
// 00000000, 0020001B, 0836106C, 2F100FF8:
mov r1, v0;
// 00000000, 0420061B, 083613FC, 5011F818:
mov oD0, v3; // Note: Somehow, oD1 is not assigned?!?
rcp r1.w, r1.w;
// 00000000, 002008FF, 0836106C, 2070F828:
mov oFog, v4.w;
// 00000000, 0240081B, 1436186C, 2F20F824:
mul r2, r1, c[0]; // c[-96] in D3D speak - applies SuperSampleScale
// 00000000, 0060201B, 2436106C, 3070F800:
add r12, r2, c[1]; // c[-95] in D3D speak - applies SuperSampleOffset
// 00000000, 00200200, 0836106C, 2070F830:
mov oPts, v1.x;
// 00000000, 00200E1B, 0836106C, 2070F838:
mov oB0, v7;
// 00000000, 0020101B, 0836106C, 2070F840:
mov oB1, v8;
// 00000000, 0020121B, 0836106C, 2070F848:
mov oT0, v9;
// 00000000, 0020141B, 0836106C, 2070F850:
mov oT1, v10;
// 00000000, 0020161B, 0836106C, 2070F858:
mov oT2, v11;
// 00000000, 0020181B, 0836106C, 2070F861:
mov oT3, v12;
mov oPos, r12; // Note: This is needed as oPos is read-only (we use R12 above)
END;
The XDK docs also mention a "#pragma screenspace" directive that indicates that screenspace scale & offset are already handled by the shader, otherwise the following opcodes are added automatically :
Code:
mul r12.xyz, r12, c58; // c[-38] in D3D speak - see EmuNV2A_ViewportScale,
rcp r1.x, r12.w; // Originally RCC, but that's not supported in ARBvp1.0
mad r12.xyz, r12, r1.x, c59; // c[-37] in D3D speak - see EmuNV2A_ViewportOffset

In any case, as you can see there's no matrix multiplication (DP4) present in there, so that would mean the NV2A does matrix multiplication in a separate pass.
OpenGL however seems to expect me to do this matrix multiplication in my shader, which would mean every NV2A shader I convert will require an additional few opcodes for the a projection matrix multiplication.

Are my assumptions correct? I'm quite new to this all... TIA!
 

·
Registered
Joined
·
359 Posts
I was assuming that you would either have to do it multiple passes, or maybe prepend the fixed-function equivalent shaders before any shader included by the game. I'm not sure how multiple passes would work. I was trying to determine if the Transform Feedback extension (D3D10 Stream-Out) would help with this, but the sample tutorial I downloaded doesn't work on ATI cards as it uses the NV_transform_feedback extension, but ATI only supports EXT_transform_feedback.

EDIT: It seems one needs to add a vertex shader to the tutorial for it to make use of the EXT_transform_feedback extension. I've made this modification. However, as EXT_transform_feedback only works with GLSL (not ARB assembly shaders), the current method of utilizing Direct3D8 binary shaders would need to be drastically changed. Anyways, the current problem is getting OpenGL primitives on the screen, all else is secondary :).
 

·
Registered
Joined
·
359 Posts
That would be my assumption. I'm not the implementer, but given that the fixed function pipeline (FFP) can be emulated with shaders, why do you need it? In the scenario where the game uses both, render the vertices into a transform feedback buffer using a vertex shader that emulates the FFP, then render the transformed vertices using the game's vertex shader.
 

·
Shadow of nothing...
Joined
·
6,071 Posts
If there's no fixed pipeline, then that means that we won't have to worry about using OpenGL's fixed pipeline lighting functions! All of our lighting calculations can be done using the Xbox Direct3D's default shader programs if no custom vertex/fragment programs are being used.

EDIT: This is my 4034-th post, hopefully I can make good use out of my 4627-th post! :lol:

EDIT2: For !!ARBvp/fp1.0 programs, you MUST have instructions such as MOV, MUL, ADD, etc. in all caps. OpenGL will return an error if you dont! :) Btw, do you need help learning !!ARBvp/fp? I wrote some basic tutorials on both and they work rather well if you need them. Don't hesitate to ask!
 

·
Registered
Joined
·
137 Posts
Hi All I just wanted to ask you all when the dxbx emulator is in use for old and new computers will opengl effect those computers without directx? I believe that directx is better than opengl because I don't have opengl but directx instead and the graphics on direct is better than opengl well that is my opinion sorry about this discussion I had to put this in what do others in this forum think?

I know opengl has been around for a long time before even directx has but I believe that directx patrick would be better than opengl but if you think otherwise than I will try and agree with you and others in this forum!
 

·
Registered
Joined
·
423 Posts
Discussion Starter #14
I *think* I understand what's playing a part here : The D3DFVF_XYZRHW flag indicates already-transformed vertices are going to be rendered - hence the lack of a matrix rotation in the shader. And the use of a shader is most likely the preferred way to prevent the fixed-function pipeline to apply unwanted mvp transformations. (I'm just guessing here, but an alternative method could be to reset the mvp matrices to the identity matrix... that would be more costly in terms of state-changes).

Bottom line : There *is* a fixed-function pipeline in the NV2A, and we still have to figure out how to map it to OpenGL properly.
 

·
Registered
Joined
·
359 Posts
Bottom line : There *is* a fixed-function pipeline in the NV2A, and we still have to figure out how to map it to OpenGL properly.
From my research, there is no matching OpenGL equivalent to D3DLIGHT8/9 Range member, so it either has to be ignored or emulated. The idea of emulating the fixed-function pipeline with shaders is shown in Microsoft's Direct3D10 FixedFuncEmu Sample.
 

·
Registered
Joined
·
423 Posts
Discussion Starter #16
@blueshogun96 : I welcome all the help I can get - it's really frustrating working on this stuff and not understanding most of it :(

I hope you're tracking my push-buffer work; Last night I finally fixed the last few issues I was having with the push-buffer based vertex shader recompiler; All shaders I throw at it are now accepted by OpenGL, so at least there's some progress.

Alas, it doesn't really help getting anything drawn correctly. Here an example from the Vertices sample, which draws just 1 triangle like this :

Code:
struct CUSTOMVERTEX {
    FLOAT x, y, z, rhw;
    DWORD color; };

CUSTOMVERTEX g_Vertices[] = {
        { 320.0f, 150.0f, 0.5f, 1.0f, 0xffff0000, },
        { 420.0f, 330.0f, 0.5f, 1.0f, 0xff00ff00, },
        { 220.0f, 330.0f, 0.5f, 1.0f, 0xff00ffff, }};

SetStreamSource(0, g_pVB, sizeof(CUSTOMVERTEX));
SetVertexShader(D3DFVF_XYZRHW|D3DFVF_DIFFUSE);
DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
This sample doesn't even set any matrix, so when I look at the push-buffer commands I get this (just the interesting parts) :
Code:
  NV2A Get=$0B7403AC  1/ 2: Method=0394 Data=00000000 NV2A_DEPTH_RANGE_NEAR 
  NV2A > DepthRange({0, 16777215}) > GL_PROJECTION_MATRIX={1, 0, 0, 0}{0, 1, 0, 0}{0, 0, 1, 0}{0, 0, 0, 1}
  NV2A Get=$0B7408DC  3/ 3: Method=1D94 Data=000000F1 NV2A_CLEAR_BUFFERS 
  NV2A > ClearRect(0, 0, 639, 479) ClearColor={B:255, G:0, R:0, A:255} ClearZ=1.00 ClearStencil=0
  NV2A Get=$0B740954  1/ 8: Method=0B80 Data=3F800000 NV2A_VP_UPLOAD_CONST(0) 
  NV2A > SetVertexShaderConstant(0, {1, 1, 16777215, 1}{0.53125, 0.53125, 0, 0})
  NV2A Get=$0B740CD0  1/ 1: Method=17FC Data=00000005 NV2A_VERTEX_BEGIN_END 
  NV2A > DrawBegin(PrimitiveType=5{=D3DPT_TRIANGLELIST})
  NV2A: New vertex shader decoded:
!!ARBvp1.0
TEMP R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12;
ADDRESS A0;
ATTRIB v0 = vertex.attrib[0];
ATTRIB v1 = vertex.attrib[1];
ATTRIB v2 = vertex.attrib[2];
ATTRIB v3 = vertex.attrib[3];
ATTRIB v4 = vertex.attrib[4];
ATTRIB v5 = vertex.attrib[5];
ATTRIB v6 = vertex.attrib[6];
ATTRIB v7 = vertex.attrib[7];
ATTRIB v8 = vertex.attrib[8];
ATTRIB v9 = vertex.attrib[9];
ATTRIB v10 = vertex.attrib[10];
ATTRIB v11 = vertex.attrib[11];
ATTRIB v12 = vertex.attrib[12];
ATTRIB v13 = vertex.attrib[13];
ATTRIB v14 = vertex.attrib[14];
ATTRIB v15 = vertex.attrib[15];
OUTPUT oPos = result.position;
OUTPUT oD0 = result.color.front.primary;
OUTPUT oD1 = result.color.front.secondary;
OUTPUT oB0 = result.color.back.primary;
OUTPUT oB1 = result.color.back.secondary;
OUTPUT oPts = result.pointsize;
OUTPUT oFog = result.fogcoord;
OUTPUT oT0 = result.texcoord[0];
OUTPUT oT1 = result.texcoord[1];
OUTPUT oT2 = result.texcoord[2];
OUTPUT oT3 = result.texcoord[3];
PARAM c[] = { program.env[0..191] };
PARAM mvp[4] = { state.matrix.mvp };
MOV R1, v0;
MOV oD0, v3;
RCP R1.w, R1.w;
MOV oFog, v4.w;
MUL R2, R1, c[0];
MOV oD1, v4;
ADD R12, R2, c[1];
MOV oPts, v1.x;
MOV oB0, v7;
MOV oB1, v8;
MOV oT0, v9;
MOV oT1, v10;
MOV oT2, v11;
MOV oT3, v12;
MOV oPos, R12;
END
  NV2A > DrawEnd() DrawPrimitive(VertexIndex=0, VertexCount=3) Float:{320, 150, 0.5, 1}{420, 330, 0.5, 1}{220, 330, 0.5, 1} ColorByte:{B:0, G:0, R:255, A:255}{B:0, G:255, R:0, A:255}{B:255, G:255, R:0, A:255}
So far everything looks good, it's just that I see only the blue (cleared) background, but no triangle... No matter how I initialize GL_MODELVIEW and GL_PROJECTION, the screen stays blank.
 

·
Registered
Joined
·
358 Posts
Hi All I just wanted to ask you all when the dxbx emulator is in use for old and new computers will opengl effect those computers without directx? I believe that directx is better than opengl because I don't have opengl but directx instead and the graphics on direct is better than opengl well that is my opinion sorry about this discussion I had to put this in what do others in this forum think?

I know opengl has been around for a long time before even directx has but I believe that directx patrick would be better than opengl but if you think otherwise than I will try and agree with you and others in this forum!
1) OpenGL is better than DX
2) All GPUs still support OpenGL and it is currently at 4.1
3) OpenGL is cross-platform meaning easy porting to other platforms
4) All functions in DX10/11 were in OpenGL for a long time
That is all.
 

·
Registered
Joined
·
359 Posts
So far everything looks good, it's just that I see only the blue (cleared) background, but no triangle... No matter how I initialize GL_MODELVIEW and GL_PROJECTION, the screen stays blank.
It wouldn't matter what you do with the matrices, since neither are used in the vertex program (you simply assign it to mvp). I'll look into that code later and see what changes need to be made for it to work.
 

·
Registered
Joined
·
359 Posts
This vertex program should work with vertices specified in screen space (i.e. D3DFVF_XYZRHW). I simply converted Microsoft's FixedFuncEmu shader to GLSL, then use NVIDIA's CG compiler to convert it to ARB assembly. It would need small modifications to work with DXBX, but should get your triangle appearing on the screen :D. Without modification, the below code should produce an uncolored triangle, since it isn't getting color information from the same vertex attribute as dxbx.
Code:
PARAM c[2] = { { 0.5, 1 },#since PARAM c is also used in dxbx, name change required
                program.local[1] }; 
MOV R0.xy, c[1]; #set R0.x = 640, R0.y = 480
MUL R0.y, R0, c[0].x;
MUL R0.z, R0.x, c[0].x;
RCP R0.x, R0.y;
RCP R0.y, R0.z;
MOV result.color, vertex.attrib[1]; #because I'm sending color information through vertex.attrib[1] (instead of vertex.attrib[3], like GL's immediate mode and dxbx)
MAD result.position.y, -vertex.attrib[0], R0.x, c[0];
MAD result.position.x, vertex.attrib[0], R0.y, -c[0].y;
MOV result.position.z, -vertex.attrib[0];
MOV result.position.w, c[0].y;
END
c[1] holds the value of the viewport, and is set with the following call
Code:
glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB,1,640,480,0,1);
where it is assumed that the viewport size of 640x480. The GLSL equivalent for this shader is:
Code:
#version 330 compatibility
uniform vec4 viewport;
layout (location = 0) in vec4 Position; //glVertexAttribPointer(0, ...);glEnableVertexAttribArray(0);
layout (location = 1) in vec4 Color; //glVertexAttribPointer(1, ...); glEnableVertexAttribArray(1);
void main()
{
	//The below code transforms screen coordinates into clip space
        vec4 pos;
	pos.x = (Position.x / (viewport.x/2.0)) -1;
        pos.y = -(Position.y / (viewport.y/2.0)) +1; 
        pos.w = 1;
	pos.z = -Position.z;
	gl_Position = pos;
	gl_FrontColor = Color;
}
and the value of viewport was set using:
Code:
int viewport = glGetUniformLocation(pg,"viewport");//assume pg is a valid program object
glProgramUniform4f(pg,viewport,640,480,0,1);//requires EXT_direct_state_access, else use glUniform4f
 
1 - 20 of 50 Posts
Top