As I said before, except I had broken warcraft so had to delete a few
lines from my patch! Note this also accounts for one of the graphical
glitches I was noticing.
All looks good so here goes...
-------------------------
This is a really unreal patch... It makes the intro to Unreal2 look
fantastic, and the weapons in Unreal Tournament actually look correct.
There's a few glitches still after this, but things look a lot better so
its worth getting this in and patching things afterwards
2 comments:
1. I have split drawprimitive into smaller functions in its own module
now as it was both very ugly, and very large and needed large rewrites
for this patch anyway
2. I include in the patch the diagnostics which identified this problem
and make diagnostics a lot easier. I noted it was one of the patches
Alexander didnt apply before, but I would really appreciate them being
in (and they need turning on before compile to impact runtime as well).
I like this patch (and no new GL extensions used so hopefully no compile
issues either) :-)
Jason
-------------------------
Index: dlls/d3d8/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/Makefile.in,v
retrieving revision 1.8
diff -u -r1.8 Makefile.in
--- dlls/d3d8/Makefile.in 4 Jun 2003 21:55:29 -0000 1.8
+++ dlls/d3d8/Makefile.in 7 Jun 2003 23:27:21 -0000
@@ -16,6 +16,7 @@
d3d8_main.c \
device.c \
directx.c \
+ drawprim.c \
indexbuffer.c \
resource.c \
shader.c \
Index: dlls/d3d8/d3d8_private.h
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/d3d8_private.h,v
retrieving revision 1.35
diff -u -r1.35 d3d8_private.h
--- dlls/d3d8/d3d8_private.h 6 Jun 2003 18:12:59 -0000 1.35
+++ dlls/d3d8/d3d8_private.h 7 Jun 2003 23:27:21 -0000
@@ -67,6 +67,15 @@
#define HIGHEST_TRANSFORMSTATE 512
#define D3DSBT_RECORDED 0xfffffffe
+/* CreateVertexShader can return > 0xFFFF */
+#define VS_HIGHESTFIXEDFXF 0xF0000000
+#define VERTEX_SHADER(Handle) \
+ ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
+#define VERTEX_SHADER_DECL(Handle) \
+ ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaderDeclarations) / sizeof(IDirect3DVertexShaderDeclarationImpl*)) ? NULL : VertexShaderDeclarations[Handle]) : VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF])
+#define PIXEL_SHADER(Handle) \
+ ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
+
/* Direct3D8 Interfaces: */
typedef struct IDirect3DBaseTexture8Impl IDirect3DBaseTexture8Impl;
typedef struct IDirect3DVolumeTexture8Impl IDirect3DVolumeTexture8Impl;
@@ -112,14 +121,14 @@
/** temporary here waiting for buffer code */
typedef struct VSHADERINPUTDATA8 {
- D3DSHADERVECTOR V[16];
+ D3DSHADERVECTOR V[17];
} VSHADERINPUTDATA8;
/** temporary here waiting for buffer code */
typedef struct VSHADEROUTPUTDATA8 {
D3DSHADERVECTOR oPos;
D3DSHADERVECTOR oD[2];
- D3DSHADERVECTOR oT[4];
+ D3DSHADERVECTOR oT[8];
D3DSHADERVECTOR oFog;
D3DSHADERVECTOR oPts;
} VSHADEROUTPUTDATA8;
@@ -1064,7 +1073,8 @@
/* Stream Source */
UINT stream_stride[MAX_STREAMS];
IDirect3DVertexBuffer8 *stream_source[MAX_STREAMS];
-
+ BOOL streamIsUP;
+
/* Indices */
IDirect3DIndexBuffer8* pIndexData;
UINT baseVertexIndex;
@@ -1141,7 +1151,9 @@
IDirect3DDevice8Impl* device;
/** precomputed fvf if simple declaration */
- DWORD fvf;
+ DWORD fvf[MAX_STREAMS];
+ DWORD allFVF;
+
/** dx8 compatible Declaration fields */
DWORD* pDeclaration8;
DWORD declaration8Length;
@@ -1197,7 +1209,7 @@
extern HRESULT WINAPI IDirect3DVertexShaderImpl_ExecuteSW(IDirect3DVertexShaderImpl* This, VSHADERINPUTDATA8* input, VSHADEROUTPUTDATA8* output);
/* temporary internal Interfaces */
extern HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, DWORD Usage, IDirect3DVertexShaderImpl** ppVertexShader);
-extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, const void* vertexFirstStream, DWORD StartVertexIndex, DWORD idxDecal);
+extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides);
/* ------------------------ */
/* IDirect3DPixelShaderImpl */
@@ -1271,5 +1283,38 @@
const char* debug_d3dressourcetype(D3DRESOURCETYPE res);
const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType);
const char* debug_d3dpool(D3DPOOL Pool);
+
+/* Some #defines for additional diagnostics */
+#if 0 /* NOTE: Must be 0 in cvs */
+ /* To avoid having to get gigabytes of trace, the following can be compiled in, and at the start
+ of each frame, a check is made for the existance of C:\D3DTRACE, and if if exists d3d trace
+ is enabled, and if it doesnt exists it is disabled. */
+# define FRAME_DEBUGGING
+ /* Adding in the SINGLE_FRAME_DEBUGGING gives a trace of just what makes up a single frame, before
+ the file is deleted */
+# if 1
+# define SINGLE_FRAME_DEBUGGING
+# endif
+ /* The following, when enabled, lets you see the makeup of the frame, by drawprimitive calls.
+ A check is made for the existence of C:\D3DSHOWFRAME, and if it exists will write the
+ contents of the back buffer into /tmp/backbuffer_* after each primitive array is drawn
+ for a single frame. At the end of the frame, the file is deleted. */
+# if 1
+# define SHOW_FRAME_MAKEUP 1
+# endif
+extern BOOL isOn;
+extern BOOL isDumpingFrames;
+extern LONG primCounter;
+#endif
+
+/* Per-vertex trace: */
+#if 0 /* NOTE: Must be 0 in cvs */
+# define VTRACE(A) TRACE A
+#else
+# define VTRACE(A)
+#endif
+
+#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
+#define TRACE_STRIDED(sd,name) TRACE( #name "=(data:%p, stride:%ld, type:%ld)\n", sd->u.s.name.lpData, sd->u.s.name.dwStride, sd->u.s.name.dwType);
#endif /* __WINE_D3DX8_PRIVATE_H */
Index: dlls/d3d8/d3dcore_gl.h
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/d3dcore_gl.h,v
retrieving revision 1.2
diff -u -r1.2 d3dcore_gl.h
--- dlls/d3d8/d3dcore_gl.h 6 Jun 2003 18:12:59 -0000 1.2
+++ dlls/d3d8/d3dcore_gl.h 7 Jun 2003 23:27:21 -0000
@@ -268,4 +268,44 @@
#define WINAPI __stdcall
#define APIENTRY WINAPI
+/* Routine common to the draw primitive and draw indexed primitive routines */
+void drawPrimitive(LPDIRECT3DDEVICE8 iface,
+ int PrimitiveType,
+ long NumPrimitives,
+
+ /* for Indexed: */
+ long StartVertexIndex,
+ long StartIdx,
+ short idxBytes,
+ const void *idxData,
+ int minIndex);
+
+/* Structures required to draw primitives */
+
+
+
+
+
+typedef struct Direct3DStridedData {
+ BYTE *lpData; /* Pointer to start of data */
+ DWORD dwStride; /* Stride between occurances of this data */
+ DWORD dwType; /* Type (as in D3DVSDT_TYPE) */
+} Direct3DStridedData;
+
+typedef struct Direct3DVertexStridedData {
+ union {
+ struct {
+ Direct3DStridedData position;
+ Direct3DStridedData blendWeights;
+ Direct3DStridedData blendMatrixIndices;
+ Direct3DStridedData normal;
+ Direct3DStridedData pSize;
+ Direct3DStridedData diffuse;
+ Direct3DStridedData specular;
+ Direct3DStridedData texCoords[8];
+ } DUMMYSTRUCTNAME;
+ Direct3DStridedData input[16]; /* Indexed by constants in D3DVSDE_REGISTER */
+ } DUMMYUNIONNAME;
+} Direct3DVertexStridedData;
+
#endif /* __WINE_D3DCORE_GL_H */
Index: dlls/d3d8/device.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/device.c,v
retrieving revision 1.70
diff -u -r1.70 device.c
--- dlls/d3d8/device.c 6 Jun 2003 18:12:59 -0000 1.70
+++ dlls/d3d8/device.c 7 Jun 2003 23:27:22 -0000
@@ -41,23 +41,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
-/* Some #defines for additional diagnostics */
-
-/* Per-vertex trace: */
-#if 0
-# define VTRACE(A) TRACE A
-#else
-# define VTRACE(A)
+IDirect3DVertexShaderImpl* VertexShaders[64];
+IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
+IDirect3DPixelShaderImpl* PixelShaders[64];
+
+#ifdef FRAME_DEBUGGING
+BOOL isOn = FALSE;
+BOOL isDumpingFrames = FALSE;
+LONG primCounter = 0;
#endif
-
-static IDirect3DVertexShaderImpl* VertexShaders[64];
-static IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
-static IDirect3DPixelShaderImpl* PixelShaders[64];
-
-/* CreateVertexShader can return > 0xFFFF */
-#define VS_HIGHESTFIXEDFXF 0xF0000000
-
/*
* Utility functions or macros
*/
@@ -70,911 +63,6 @@
memcpy(gl_mat, (mat), 16 * sizeof(float)); \
} while (0)
-#define VERTEX_SHADER(Handle) \
- ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
-#define VERTEX_SHADER_DECL(Handle) \
- ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaderDeclarations) / sizeof(IDirect3DVertexShaderDeclarationImpl*)) ? NULL : VertexShaderDeclarations[Handle]) : VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF])
-#define PIXEL_SHADER(Handle) \
- ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
-
-#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
-
-/* Routine common to the draw primitive and draw indexed primitive routines */
-void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
- int PrimitiveType,
- long NumPrimitives,
- BOOL isIndexed,
-
- /* For Both:*/
- D3DFORMAT fvf,
- const void *vertexBufData,
-
- /* for Indexed: */
- long StartVertexIndex,
- long StartIdx,
- short idxBytes,
- const void *idxData,
- int minIndex) {
-
- int NumVertexes = NumPrimitives;
- IDirect3DVertexShaderImpl* vertex_shader = NULL;
- BOOL useVertexShaderFunction = FALSE;
-
- ICOM_THIS(IDirect3DDevice8Impl,iface);
-
- /* Dont understand how to handle multiple streams, but if a fixed
- FVF is passed in rather than a handle, it must use stream 0 */
-
- if (This->UpdateStateBlock->VertexShader > VS_HIGHESTFIXEDFXF) {
- vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader);
- if (NULL == vertex_shader) {
- ERR_(d3d_shader)("trying to use unitialised vertex shader: %lu\n", This->UpdateStateBlock->VertexShader);
- return ;
- }
- if (NULL == vertex_shader->function) {
- TRACE_(d3d_shader)("vertex shader declared without program, using FVF pure mode\n");
- } else {
- useVertexShaderFunction = TRUE;
- }
- fvf = (D3DFORMAT) This->UpdateStateBlock->vertexShaderDecl->fvf;
- TRACE_(d3d_shader)("vertex shader declared FVF: %08lx\n", This->UpdateStateBlock->vertexShaderDecl->fvf);
- memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8));
-
- /** init Constants */
- if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) {
- TRACE_(d3d_shader)("vertex shader init Constant\n");
- IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96);
- }
-
- }
-
- {
- int skip = This->StateBlock->stream_stride[0];
- GLenum primType = GL_POINTS;
- BOOL normal;
- BOOL isRHW;
- BOOL isPtSize;
- BOOL isDiffuse;
- BOOL isSpecular;
- int numBlends;
- BOOL isLastUByte4;
- int numTextures;
- int textureNo;
- const char *curVtx = NULL;
- const short *pIdxBufS = NULL;
- const long *pIdxBufL = NULL;
- const char *curPos;
- BOOL isLightingOn = FALSE;
- int vx_index;
- int coordIdxInfo = 0x00; /* Information on number of coords supplied */
- float s[8], t[8], r[8], q[8]; /* Holding place for tex coords */
- const char *coordPtr[8]; /* Holding place for the ptr to tex coords */
- int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */
-
-
- float x = 0.0f,
- y = 0.0f,
- z = 0.0f; /* x,y,z coordinates */
- float nx = 0.0f,
- ny =0.0,
- nz = 0.0f; /* normal x,y,z coordinates */
- float rhw = 0.0f; /* rhw */
- float ptSize = 0.0f; /* Point size */
- DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
- DWORD specularColor = 0; /* Specular Color */
-
- ENTER_GL();
-
- if (isIndexed) {
- if (idxBytes == 2) pIdxBufS = (short *) idxData;
- else pIdxBufL = (long *) idxData;
- }
-
- /* Check vertex formats expected ? */
- /**
- * FVF parser as seen it
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/Reference/CPP/D3D/FlexibleVertexFormatFlags.asp
- */
- normal = fvf & D3DFVF_NORMAL;
- isRHW = fvf & D3DFVF_XYZRHW;
- isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
- numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2 + ((FALSE == isLastUByte4) ? 0 : -1); /* WARNING can be < 0 because -2 */
- isPtSize = fvf & D3DFVF_PSIZE;
- isDiffuse = fvf & D3DFVF_DIFFUSE;
- isSpecular = fvf & D3DFVF_SPECULAR;
- numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
- coordIdxInfo = (fvf & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */
-
- TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d, coordIdxInfo=%x)\n",
- fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends, coordIdxInfo);
-
- /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
- set by the appropriate render state */
- if (!normal) {
- isLightingOn = glIsEnabled(GL_LIGHTING);
- glDisable(GL_LIGHTING);
- TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
- }
-
- if (isRHW) {
- double X, Y, height, width, minZ, maxZ;
- /*
- * Already transformed vertex do not need transform
- * matrices. Reset all matrices to identity.
- * Leave the default matrix in world mode.
- */
- glMatrixMode(GL_MODELVIEW);
- checkGLcall("glMatrixMode");
- glLoadIdentity();
- checkGLcall("glLoadIdentity");
- /**
- * As seen in d3d7 code:
- * See the OpenGL Red Book for an explanation of the following translation (in the OpenGL
- * Correctness Tips section).
- */
- glTranslatef(0.375f, 0.375f, 0.0f);
- /**
- *
- */
- glMatrixMode(GL_PROJECTION);
- checkGLcall("glMatrixMode");
- glLoadIdentity();
- checkGLcall("glLoadIdentity");
- X = This->StateBlock->viewport.X;
- Y = This->StateBlock->viewport.Y;
- height = This->StateBlock->viewport.Height;
- width = This->StateBlock->viewport.Width;
- minZ = This->StateBlock->viewport.MinZ;
- maxZ = This->StateBlock->viewport.MaxZ;
- TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
- /*glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);*/
- glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
- checkGLcall("glOrtho");
- } else {
- double X, Y, height, width;
- X = This->StateBlock->viewport.X;
- Y = This->StateBlock->viewport.Y;
- height = This->StateBlock->viewport.Height;
- width = This->StateBlock->viewport.Width;
-
- glMatrixMode(GL_MODELVIEW);
- checkGLcall("glMatrixMode");
- glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
- checkGLcall("glMultMatrixf");
-
-#if 0
- /**
- * OpenGL seems to map font between pixels
- * well with this it seems better but not perfect
- * anyone have a better idea ?
- */
- glTranslatef(0.8f / width, -0.8f / height, 0.0f);
- /**
- *
- */
-#endif
-
- glMatrixMode(GL_PROJECTION);
- checkGLcall("glMatrixMode");
- glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- }
-
- /* Set OpenGL to the appropriate Primitive Type */
- switch (PrimitiveType) {
- case D3DPT_POINTLIST:
- TRACE("POINTS\n");
- primType = GL_POINTS;
- NumVertexes = NumPrimitives;
- break;
-
- case D3DPT_LINELIST:
- TRACE("LINES\n");
- primType = GL_LINES;
- NumVertexes = NumPrimitives * 2;
- break;
-
- case D3DPT_LINESTRIP:
- TRACE("LINE_STRIP\n");
- primType = GL_LINE_STRIP;
- NumVertexes = NumPrimitives + 1;
- break;
-
- case D3DPT_TRIANGLELIST:
- TRACE("TRIANGLES\n");
- primType = GL_TRIANGLES;
- NumVertexes = NumPrimitives * 3;
- break;
-
- case D3DPT_TRIANGLESTRIP:
- TRACE("TRIANGLE_STRIP\n");
- primType = GL_TRIANGLE_STRIP;
- NumVertexes = NumPrimitives + 2;
- break;
-
- case D3DPT_TRIANGLEFAN:
- TRACE("TRIANGLE_FAN\n");
- primType = GL_TRIANGLE_FAN;
- NumVertexes = NumPrimitives + 2;
- break;
-
- default:
- FIXME("Unhandled primitive\n");
- break;
- }
-
- /* Fixme, Ideally, only use this per-vertex code for software HAL
- but until opengl supports all the functions returned to setup
- vertex arrays, we need to drop down to the slow mechanism for
- certain functions */
-
- if (isPtSize || isDiffuse || useVertexShaderFunction == TRUE || (numBlends > 0)) {
- TRACE("Using slow per-vertex code\n");
-
- /* Enable this one to be able to debug what is going on, but it is slower
- than the pointer/array version */
- VTRACE(("glBegin(%x)\n", primType));
- glBegin(primType);
-
- /* Draw the primitives */
- curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
-
- for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
-
- if (!isIndexed) {
- curPos = curVtx;
- } else {
- if (idxBytes == 2) {
- VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
- curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
- } else {
- VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
- curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
- }
- }
-
- /* Work through the vertex buffer */
- x = *(float *)curPos;
- curPos = curPos + sizeof(float);
- y = *(float *)curPos;
- curPos = curPos + sizeof(float);
- z = *(float *)curPos;
- curPos = curPos + sizeof(float);
- VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
-
- /* RHW follows, only if transformed */
- if (isRHW) {
- rhw = *(float *)curPos;
- curPos = curPos + sizeof(float);
- VTRACE(("rhw=%f\n", rhw));
- }
-
- /* Blending data */
- if (numBlends > 0) {
- UINT i;
- D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
- DWORD skippedBlendLastUByte4 = 0;
-
- for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
- ((float*)&skippedBlend)[i] = *(float *)curPos;
- curPos = curPos + sizeof(float);
- }
-
- if (isLastUByte4) {
- skippedBlendLastUByte4 = *(DWORD*)curPos;
- curPos = curPos + sizeof(DWORD);
- }
- }
-
- /* Vertex Normal Data (untransformed only) */
- if (normal) {
- nx = *(float *)curPos;
- curPos = curPos + sizeof(float);
- ny = *(float *)curPos;
- curPos = curPos + sizeof(float);
- nz = *(float *)curPos;
- curPos = curPos + sizeof(float);
- VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
- }
-
- if (isPtSize) {
- ptSize = *(float *)curPos;
- VTRACE(("ptSize=%f\n", ptSize));
- curPos = curPos + sizeof(float);
- }
-
- if (isDiffuse) {
- diffuseColor = *(DWORD *)curPos;
- VTRACE(("diffuseColor=%lx\n", diffuseColor));
- curPos = curPos + sizeof(DWORD);
- }
-
- if (isSpecular) {
- specularColor = *(DWORD *)curPos;
- VTRACE(("specularColor=%lx\n", specularColor));
- curPos = curPos + sizeof(DWORD);
- }
-
- /* Texture coords */
- /* numTextures indicates the number of texture coordinates supplied */
- /* However, the first set may not be for stage 0 texture - it all */
- /* depends on D3DTSS_TEXCOORDINDEX. */
- /* The number of bytes for each coordinate set is based off */
- /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
-
- /* Initialize unused coords to unsupplied so we can check later */
- for (textureNo = numTextures; textureNo < 7; textureNo++) numCoords[textureNo] = -1;
-
- /* So, for each supplied texture extract the coords */
- for (textureNo = 0; textureNo < numTextures; ++textureNo) {
-
- numCoords[textureNo] = coordIdxInfo & 0x03;
-
- /* Always one set */
- s[textureNo] = *(float *)curPos;
- curPos = curPos + sizeof(float);
- if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
- t[textureNo] = *(float *)curPos;
- curPos = curPos + sizeof(float);
- if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
- r[textureNo] = *(float *)curPos;
- curPos = curPos + sizeof(float);
- if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
- q[textureNo] = *(float *)curPos;
- curPos = curPos + sizeof(float);
- }
- }
- }
-
- coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
- }
-
- /* Now use the appropriate set of texture indexes */
- for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
-
- if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
- FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
- continue ;
- }
-
- /* Query tex coords */
- if ((This->StateBlock->textures[textureNo] != NULL) &&
- (useVertexShaderFunction == FALSE)) {
-
- int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
-
- if (coordIdx > 7) {
- VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
- } else if (coordIdx >= numTextures) {
- VTRACE(("tex: %d - Skip tex coords, as requested higher than supplied\n", textureNo));
- } else {
-
- int coordsToUse = numCoords[coordIdx];
-
- /* If texture transform flags in effect, values passed through to vertex
- depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
- if (coordsToUse > 0 &&
- This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)
- {
- /* This indicates how many coords to use regardless of the
- texture type. However, d3d/opengl fill in the rest appropriately */
- coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
-
- /* BUT - Projected is more 'fun' - Move the last coord to the 'q'
- parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */
- if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
- switch (coordsToUse) {
- case 0: /* Drop Through */
- case 1:
- FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n");
- break;
- case 2:
- q[textureNo] = t[textureNo];
- t[textureNo] = 0.0;
- coordsToUse = 4;
- break;
- case 3:
- q[textureNo] = r[textureNo];
- r[textureNo] = 0.0;
- coordsToUse = 4;
- break;
- case 4: /* Nop here */
- break;
- default:
- FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n",
- This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
- }
- }
- }
-
- switch (coordsToUse) { /* Supply the provided texture coords */
- case D3DFVF_TEXTUREFORMAT1:
- VTRACE(("tex:%d, s=%f\n", textureNo, s[coordIdx]));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
- glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s[coordIdx]);
-#else
- glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx]);
-#endif
- } else {
- glTexCoord1f(s[coordIdx]);
- }
- break;
- case D3DFVF_TEXTUREFORMAT2:
- VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s[coordIdx], t[coordIdx]));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
- glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx]);
-#else
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx]);
-#endif
- } else {
- glTexCoord2f(s[coordIdx], t[coordIdx]);
- }
- break;
- case D3DFVF_TEXTUREFORMAT3:
- VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx]));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
- glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
-#else
- glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
-#endif
- } else {
- glTexCoord3f(s[coordIdx], t[coordIdx], r[coordIdx]);
- }
- break;
- case D3DFVF_TEXTUREFORMAT4:
- VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
- glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
-#else
- glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
-#endif
- } else {
- glTexCoord4f(s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
- }
- break;
- default:
- FIXME("Should not get here as numCoords is two bits only (%x)!\n", numCoords[coordIdx]);
- }
- }
- }
-
- }
-
- /** if vertex shader program specified ... using it */
- if (TRUE == useVertexShaderFunction) {
-
- /**
- * this code must become the really
- * vs input params init
- *
- * because its possible to use input registers for anything
- * and some samples use registers for other things than they are
- * declared
- */
-
- /**
- * no really valid declaration, user defined input register use
- * so fill input registers as described in vertex shader declaration
- */
- IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, vertexBufData, StartVertexIndex,
- (!isIndexed) ? (vx_index * skip) :
- (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
- ((pIdxBufL[StartIdx + vx_index]) * skip));
-
- memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
- IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
- /*
- TRACE_VECTOR(vertex_shader->output.oPos);
- TRACE_VECTOR(vertex_shader->output.oD[0]);
- TRACE_VECTOR(vertex_shader->output.oD[1]);
- TRACE_VECTOR(vertex_shader->output.oT[0]);
- TRACE_VECTOR(vertex_shader->output.oT[1]);
- TRACE_VECTOR(vertex_shader->input.V[0]);
- TRACE_VECTOR(vertex_shader->data->C[0]);
- TRACE_VECTOR(vertex_shader->data->C[1]);
- TRACE_VECTOR(vertex_shader->data->C[2]);
- TRACE_VECTOR(vertex_shader->data->C[3]);
- TRACE_VECTOR(vertex_shader->data->C[4]);
- TRACE_VECTOR(vertex_shader->data->C[5]);
- TRACE_VECTOR(vertex_shader->data->C[6]);
- TRACE_VECTOR(vertex_shader->data->C[7]);
- */
- x = vertex_shader->output.oPos.x;
- y = vertex_shader->output.oPos.y;
- z = vertex_shader->output.oPos.z;
-
- if (1.0f != vertex_shader->output.oPos.w || isRHW) {
- rhw = vertex_shader->output.oPos.w;
- }
- /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
- glColor4fv((float*) &vertex_shader->output.oD[0]);
-
- /* Requires secondary color extensions to compile... */
-#if defined(GL_EXT_secondary_color)
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- /*specularColor = D3DCOLORTOCOLORVALUE(vertex_shader->output.oD[1]);*/
- GL_EXTCALL(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);
- checkGLcall("glSecondaryColor3fvEXT");
- }
-#endif
- /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
- for (textureNo = 0; textureNo < 4; ++textureNo) {
- float s, t, r, q;
-
- if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
- FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
- continue ;
- }
- /* Query tex coords */
- if (This->StateBlock->textures[textureNo] != NULL) {
- switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
- case D3DRTYPE_TEXTURE:
- /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
- s = vertex_shader->output.oT[textureNo].x;
- t = vertex_shader->output.oT[textureNo].y;
- VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
- if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
- VTRACE(("Skip tex coords, as being system generated\n"));
- } else {
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
- glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
-#else
- glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
-#endif
- /*checkGLcall("glMultiTexCoord2fARB");*/
- } else {
- glTexCoord2f(s, t);
- /*checkGLcall("gTexCoord2f");*/
- }
- }
- break;
-
- case D3DRTYPE_VOLUMETEXTURE:
- /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
- s = vertex_shader->output.oT[textureNo].x;
- t = vertex_shader->output.oT[textureNo].y;
- r = vertex_shader->output.oT[textureNo].z;
- VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
- if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
- VTRACE(("Skip tex coords, as being system generated\n"));
- } else {
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
- glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
-#else
- glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
-#endif
- /*checkGLcall("glMultiTexCoord2fARB");*/
- } else {
- glTexCoord3f(s, t, r);
- /*checkGLcall("gTexCoord3f");*/
- }
- }
- break;
-
- default:
- /* Avoid compiler warnings, need these vars later for other textures */
- r = 0.0f; q = 0.0f;
- FIXME("Unhandled texture type\n");
- }
- }
- }
-
- if (1.0f == rhw || rhw < 0.01f) {
- TRACE_(d3d_shader)("Vertex: glVertex:x,y,z=%f,%f,%f\n", x, y, z);
- glVertex3f(x, y, z);
- /*checkGLcall("glVertex3f");*/
- } else {
- GLfloat w = 1.0f / rhw;
- TRACE_(d3d_shader)("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw);
-
- /*glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);*/
- glVertex4f(x * w, y * w, z * w, 1.0f);
- /*checkGLcall("glVertex4f");*/
- }
- } else {
- /**
- * FALSE == useVertexShaderFunction
- * using std FVF code
- */
-
- /* Handle these vertexes */
- if (isDiffuse) {
- glColor4ub((diffuseColor >> 16) & 0xFF,
- (diffuseColor >> 8) & 0xFF,
- (diffuseColor >> 0) & 0xFF,
- (diffuseColor >> 24) & 0xFF);
- VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
- ((diffuseColor >> 16) & 0xFF) / 255.0f,
- ((diffuseColor >> 8) & 0xFF) / 255.0f,
- ((diffuseColor >> 0) & 0xFF) / 255.0f,
- ((diffuseColor >> 24) & 0xFF) / 255.0f));
- }
-
- if (normal) {
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
- glNormal3f(nx, ny, nz);
- glVertex3f(x, y, z);
- } else {
- if (1.0f == rhw || rhw < 0.01f) {
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
- glVertex3f(x, y, z);
- } else {
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
- glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
- }
- }
- }
-
- if (!isIndexed) {
- curVtx = curVtx + skip;
- }
- }
-
- glEnd();
- checkGLcall("glEnd and previous calls");
-
- } else {
- TRACE("Using fast vertex array code\n");
-
- /* Faster version, harder to debug */
- /* Shuffle to the beginning of the vertexes to render and index from there */
- curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
- curPos = curVtx;
-
- /* Set up the vertex pointers */
- if (isRHW) {
- glVertexPointer(4, GL_FLOAT, skip, curPos);
- checkGLcall("glVertexPointer(4, ...)");
- curPos += 4 * sizeof(float);
- } else {
- glVertexPointer(3, GL_FLOAT, skip, curPos);
- checkGLcall("glVertexPointer(3, ...)");
- curPos += 3 * sizeof(float);
- }
- glEnableClientState(GL_VERTEX_ARRAY);
- checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
-
- if (numBlends > 0) {
- /* no such functionality in the fixed function GL pipeline */
- /* FIXME: Wont get here as will drop to slow method */
- /* FIXME("Cannot handle blending data here in openGl\n");*/
-#if 0
- if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
- /*FIXME("TODO\n");*/
- } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
- /*FIXME("TODO\n");*/
- /*
- GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
- checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
- glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
- checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
- */
- } else {
- FIXME("unsupported blending in openGl\n");
- }
-#endif
- curPos += numBlends * sizeof(float);
- } else {
-#if 0
- if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
- FIXME("TODO\n");
- } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
- FIXME("TODO\n");
- /*
- glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
- checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
- */
- }
-#endif
- }
-
-
- if (normal) {
- glNormalPointer(GL_FLOAT, skip, curPos);
- checkGLcall("glNormalPointer");
- glEnableClientState(GL_NORMAL_ARRAY);
- checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
- curPos += 3 * sizeof(float);
- } else {
- glDisableClientState(GL_NORMAL_ARRAY);
- checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
- glNormal3f(0, 0, 1);
- checkGLcall("glNormal3f(0, 0, 1)");
- }
-
- if (isPtSize) {
- /* no such functionality in the fixed function GL pipeline */
- /* FIXME: Wont get here as will drop to slow method */
- FIXME("Cannot change ptSize here in openGl\n");
- curPos = curPos + sizeof(float);
- }
-
- if (isDiffuse) {
- glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
- checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
- glEnableClientState(GL_COLOR_ARRAY);
- checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
- curPos += sizeof(DWORD);
- }
- else {
- glDisableClientState(GL_COLOR_ARRAY);
- checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
- glColor4f(1, 1, 1, 1);
- checkGLcall("glColor4f(1, 1, 1, 1)");
- }
-
- /* Requires secondary color extensions to compile... */
- if (isSpecular) {
-#if defined(GL_EXT_secondary_color)
- /* FIXME: check for GL_EXT_secondary_color */
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, skip, curPos);
- vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
- glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
- vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
- }
-#endif
- curPos += sizeof(DWORD);
- } else {
-#if defined(GL_EXT_secondary_color)
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
- vcheckGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
-#if 0
- GL_EXTCALL(glSecondaryColor3fEXT)(0.0f, 0.0f, 0.0f);
- vcheckGLcall("glSecondaryColor3fEXT(0, 0, 0)");
-#endif
- }
-#endif
- }
-
- /* Texture coords */
- /* numTextures indicates the number of texture coordinates supplied */
- /* However, the first set may not be for stage 0 texture - it all */
- /* depends on D3DTSS_TEXCOORDINDEX. */
- /* The number of bytes for each coordinate set is based off */
- /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
-
- /* Initialize unused coords to unsupplied so we can check later */
- for (textureNo = numTextures; textureNo < 7; textureNo++) coordPtr[textureNo] = NULL;
-
- /* So, for each supplied texture extract the coords */
- for (textureNo = 0; textureNo < numTextures; ++textureNo) {
-
- numCoords[textureNo] = coordIdxInfo & 0x03;
- coordPtr[textureNo] = curPos;
-
- /* Always one set */
- curPos = curPos + sizeof(float);
- if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
- curPos = curPos + sizeof(float);
- if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
- curPos = curPos + sizeof(float);
- if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
- curPos = curPos + sizeof(float);
- }
- }
- }
- coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
- }
-
- /* Now use the appropriate set of texture indexes */
- for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
-
- if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
- FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
- continue ;
- }
-
- /* Query tex coords */
- if ((This->StateBlock->textures[textureNo] != NULL) && (useVertexShaderFunction == FALSE)) {
- int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
-
- if (coordIdx > 7) {
- VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
- } else {
- int numFloats = 0;
- int coordsToUse = numCoords[coordIdx];
-#if defined(GL_VERSION_1_3)
- glClientActiveTexture(GL_TEXTURE0 + textureNo);
-#else
- glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
-#endif
-
- /* If texture transform flags in effect, values passed through to vertex
- depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
- if (coordsToUse > 0 &&
- This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)
- {
- /* This indicates how many coords to use regardless of the
- texture type. However, d3d/opengl fill in the rest appropriately */
- coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
-
- /* BUT - Projected is more 'fun' - Cant be done for ptr mode.
- Probably should scan enabled texture units and drop back to
- slow mode if found? */
- if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
- FIXME("Cannot handle projected transform state in fast mode\n");
- }
- }
-
- switch (coordsToUse) { /* Supply the provided texture coords */
- case D3DFVF_TEXTUREFORMAT1: numFloats = 1; break;
- case D3DFVF_TEXTUREFORMAT2: numFloats = 2; break;
- case D3DFVF_TEXTUREFORMAT3: numFloats = 3; break;
- case D3DFVF_TEXTUREFORMAT4: numFloats = 4; break;
- default: numFloats = 0; break;
- }
-
- if (numFloats == 0 || coordIdx >= numTextures) {
- VTRACE(("Skipping as invalid request - numfloats=%d, coordIdx=%d, numTextures=%d\n", numFloats, coordIdx, numTextures));
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
- } else {
- VTRACE(("tex: %d, ptr=%p, numcoords=%d\n", textureNo, coordPtr[coordIdx], numFloats));
- glTexCoordPointer(numFloats, GL_FLOAT, skip, coordPtr[coordIdx]);
- checkGLcall("glTexCoordPointer(x, ...)");
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
- }
- }
- }
- }
-
- /* Finally do the drawing */
- if (isIndexed) {
-
- TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
- if (idxBytes==2) {
-#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
- glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT,
- (char *)idxData+(2 * StartIdx));
-#else
- glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
- GL_UNSIGNED_SHORT, (char *)idxData+(2 * StartIdx));
-#endif
- } else {
-#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
- glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT,
- (char *)idxData+(4 * StartIdx));
-#else
- glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
- GL_UNSIGNED_INT, (char *)idxData+(2 * StartIdx));
-#endif
- }
- checkGLcall("glDrawRangeElements");
-
- } else {
-
- /* Note first is now zero as we shuffled along earlier */
- TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
- glDrawArrays(primType, 0, NumVertexes);
- checkGLcall("glDrawArrays");
-
- }
- }
-
- /* If no normals, restore previous lighting state */
- if (!normal) {
- if (isLightingOn) glEnable(GL_LIGHTING);
- else glDisable(GL_LIGHTING);
- TRACE("Restored lighting to original state\n");
- }
-
- }
- LEAVE_GL();
-
- TRACE("glEnd\n");
-}
-
/* Apply the current values to the specified texture stage */
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
@@ -1219,7 +307,45 @@
glXSwapBuffers(This->display, This->drawable);
/* Dont call checkGLcall, as glGetError is not applicable here */
- TRACE("glXSwapBuffers called, Starting new frame");
+ TRACE("glXSwapBuffers called, Starting new frame\n");
+
+#if defined(FRAME_DEBUGGING)
+{
+ if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
+ if (!isOn) {
+ isOn = TRUE;
+ FIXME("Enabling D3D Trace\n");
+ __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
+#if defined(SHOW_FRAME_MAKEUP)
+ FIXME("Singe Frame snapshots Starting\n");
+ isDumpingFrames = TRUE;
+ glClear(GL_COLOR_BUFFER_BIT);
+#endif
+
+#if defined(SINGLE_FRAME_DEBUGGING)
+ } else {
+#if defined(SHOW_FRAME_MAKEUP)
+ FIXME("Singe Frame snapshots Finishing\n");
+ isDumpingFrames = FALSE;
+#endif
+ FIXME("Singe Frame trace complete\n");
+ DeleteFileA("C:\\D3DTRACE");
+ __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
+#endif
+ }
+ } else {
+ if (isOn) {
+ isOn = FALSE;
+#if defined(SHOW_FRAME_MAKEUP)
+ FIXME("Singe Frame snapshots Finishing\n");
+ isDumpingFrames = FALSE;
+#endif
+ FIXME("Disabling D3D Trace\n");
+ __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
+ }
+ }
+}
+#endif
LEAVE_GL();
@@ -4198,15 +3324,11 @@
}
HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
- IDirect3DVertexBuffer8 *pVB;
-
ICOM_THIS(IDirect3DDevice8Impl,iface);
- pVB = This->StateBlock->stream_source[0];
+ This->StateBlock->streamIsUP = FALSE;
TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), StartVertex, PrimitiveCount);
-
- DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
- This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
+ drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, -1, 0, NULL, 0);
return D3D_OK;
}
@@ -4214,12 +3336,11 @@
UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
UINT idxStride = 2;
IDirect3DIndexBuffer8 *pIB;
- IDirect3DVertexBuffer8 *pVB;
D3DINDEXBUFFER_DESC IdxBufDsc;
ICOM_THIS(IDirect3DDevice8Impl,iface);
pIB = This->StateBlock->pIndexData;
- pVB = This->StateBlock->stream_source[0];
+ This->StateBlock->streamIsUP = FALSE;
TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d \n", This,
PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
@@ -4232,8 +3353,7 @@
idxStride = 4;
}
- DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
- This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
+ drawPrimitive(iface, PrimitiveType, primCount, This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
minIndex);
return D3D_OK;
@@ -4246,11 +3366,13 @@
if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
- This->StateBlock->stream_source[0] = NULL;
+ /* Note in the following, its not this type, but thats the purpose of streamIsUP */
+ This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData;
This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
- DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
- 0, 0, 0, NULL, 0);
+ This->StateBlock->streamIsUP = TRUE;
+ drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, NULL, 0);
This->StateBlock->stream_stride[0] = 0;
+ This->StateBlock->stream_source[0] = NULL;
/*stream zero settings set to null at end */
return D3D_OK;
@@ -4271,12 +3393,14 @@
idxStride = 4;
}
- This->StateBlock->stream_source[0] = NULL;
+ /* Note in the following, its not this type, but thats the purpose of streamIsUP */
+ This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData;
+ This->StateBlock->streamIsUP = TRUE;
This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
- DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
- This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
+ drawPrimitive(iface, PrimitiveType, PrimitiveCount, This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
/*stream zero settings set to null at end */
+ This->StateBlock->stream_source[0] = NULL;
This->StateBlock->stream_stride[0] = 0;
IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
@@ -4313,6 +3437,7 @@
VertexShaders[i] = object;
VertexShaderDeclarations[i] = attached_decl;
*pHandle = VS_HIGHESTFIXEDFXF + i;
+ TRACE("Finished creating vertex shader %lx\n", *pHandle);
return D3D_OK;
}
Index: dlls/d3d8/shader.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/shader.c,v
retrieving revision 1.13
diff -u -r1.13 shader.c
--- dlls/d3d8/shader.c 4 Jun 2003 22:45:57 -0000 1.13
+++ dlls/d3d8/shader.c 7 Jun 2003 23:27:23 -0000
@@ -34,12 +34,12 @@
/* Shader debugging - Change the following line to enable debugging of software
vertex shaders */
-#if 0
+#if 0 /* Must not be 1 in cvs version */
# define VSTRACE(A) TRACE A
-# define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
+# define TRACE_VSVECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
#else
# define VSTRACE(A)
-# define TRACE_VECTOR(name)
+# define TRACE_VSVECTOR(name)
#endif
@@ -584,30 +584,30 @@
memset(R, 0, 12 * sizeof(D3DSHADERVECTOR));
/* vshader_program_parse(vshader); */
-#if 0
+#if 0 /* Must not be 1 in cvs */
TRACE("Input:\n");
- TRACE_VECTOR(vshader->data->C[0]);
- TRACE_VECTOR(vshader->data->C[1]);
- TRACE_VECTOR(vshader->data->C[2]);
- TRACE_VECTOR(vshader->data->C[3]);
- TRACE_VECTOR(vshader->data->C[4]);
- TRACE_VECTOR(vshader->data->C[5]);
- TRACE_VECTOR(vshader->data->C[6]);
- TRACE_VECTOR(vshader->data->C[7]);
- TRACE_VECTOR(vshader->data->C[8]);
- TRACE_VECTOR(vshader->data->C[64]);
- TRACE_VECTOR(input->V[D3DVSDE_POSITION]);
- TRACE_VECTOR(input->V[D3DVSDE_BLENDWEIGHT]);
- TRACE_VECTOR(input->V[D3DVSDE_BLENDINDICES]);
- TRACE_VECTOR(input->V[D3DVSDE_NORMAL]);
- TRACE_VECTOR(input->V[D3DVSDE_PSIZE]);
- TRACE_VECTOR(input->V[D3DVSDE_DIFFUSE]);
- TRACE_VECTOR(input->V[D3DVSDE_SPECULAR]);
- TRACE_VECTOR(input->V[D3DVSDE_TEXCOORD0]);
- TRACE_VECTOR(input->V[D3DVSDE_TEXCOORD1]);
+ TRACE_VSVECTOR(vshader->data->C[0]);
+ TRACE_VSVECTOR(vshader->data->C[1]);
+ TRACE_VSVECTOR(vshader->data->C[2]);
+ TRACE_VSVECTOR(vshader->data->C[3]);
+ TRACE_VSVECTOR(vshader->data->C[4]);
+ TRACE_VSVECTOR(vshader->data->C[5]);
+ TRACE_VSVECTOR(vshader->data->C[6]);
+ TRACE_VSVECTOR(vshader->data->C[7]);
+ TRACE_VSVECTOR(vshader->data->C[8]);
+ TRACE_VSVECTOR(vshader->data->C[64]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_POSITION]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_BLENDWEIGHT]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_BLENDINDICES]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_NORMAL]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_PSIZE]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_DIFFUSE]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_SPECULAR]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_TEXCOORD0]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_TEXCOORD1]);
#endif
- TRACE_VECTOR(vshader->data->C[64]);
+ TRACE_VSVECTOR(vshader->data->C[64]);
/* the first dword is the version tag */
/* TODO: parse it */
@@ -756,17 +756,17 @@
}
#if 0
- TRACE_VECTOR(output->oPos);
- TRACE_VECTOR(output->oD[0]);
- TRACE_VECTOR(output->oD[1]);
- TRACE_VECTOR(output->oT[0]);
- TRACE_VECTOR(output->oT[1]);
- TRACE_VECTOR(R[0]);
- TRACE_VECTOR(R[1]);
- TRACE_VECTOR(R[2]);
- TRACE_VECTOR(R[3]);
- TRACE_VECTOR(R[4]);
- TRACE_VECTOR(R[5]);
+ TRACE_VSVECTOR(output->oPos);
+ TRACE_VSVECTOR(output->oD[0]);
+ TRACE_VSVECTOR(output->oD[1]);
+ TRACE_VSVECTOR(output->oT[0]);
+ TRACE_VSVECTOR(output->oT[1]);
+ TRACE_VSVECTOR(R[0]);
+ TRACE_VSVECTOR(R[1]);
+ TRACE_VSVECTOR(R[2]);
+ TRACE_VSVECTOR(R[3]);
+ TRACE_VSVECTOR(R[4]);
+ TRACE_VSVECTOR(R[5]);
#endif
/* to next opcode token */
@@ -774,26 +774,26 @@
}
#if 0
TRACE("End of current instruction:\n");
- TRACE_VECTOR(output->oPos);
- TRACE_VECTOR(output->oD[0]);
- TRACE_VECTOR(output->oD[1]);
- TRACE_VECTOR(output->oT[0]);
- TRACE_VECTOR(output->oT[1]);
- TRACE_VECTOR(R[0]);
- TRACE_VECTOR(R[1]);
- TRACE_VECTOR(R[2]);
- TRACE_VECTOR(R[3]);
- TRACE_VECTOR(R[4]);
- TRACE_VECTOR(R[5]);
+ TRACE_VSVECTOR(output->oPos);
+ TRACE_VSVECTOR(output->oD[0]);
+ TRACE_VSVECTOR(output->oD[1]);
+ TRACE_VSVECTOR(output->oT[0]);
+ TRACE_VSVECTOR(output->oT[1]);
+ TRACE_VSVECTOR(R[0]);
+ TRACE_VSVECTOR(R[1]);
+ TRACE_VSVECTOR(R[2]);
+ TRACE_VSVECTOR(R[3]);
+ TRACE_VSVECTOR(R[4]);
+ TRACE_VSVECTOR(R[5]);
#endif
}
-#if 0
+#if 0 /* Must not be 1 in cvs */
TRACE("Output:\n");
- TRACE_VECTOR(output->oPos);
- TRACE_VECTOR(output->oD[0]);
- TRACE_VECTOR(output->oD[1]);
- TRACE_VECTOR(output->oT[0]);
- TRACE_VECTOR(output->oT[1]);
+ TRACE_VSVECTOR(output->oPos);
+ TRACE_VSVECTOR(output->oD[0]);
+ TRACE_VSVECTOR(output->oD[1]);
+ TRACE_VSVECTOR(output->oT[0]);
+ TRACE_VSVECTOR(output->oT[1]);
#endif
return D3D_OK;
}
Index: dlls/d3d8/surface.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/surface.c,v
retrieving revision 1.15
diff -u -r1.15 surface.c
--- dlls/d3d8/surface.c 4 Jun 2003 23:05:46 -0000 1.15
+++ dlls/d3d8/surface.c 7 Jun 2003 23:27:23 -0000
@@ -31,14 +31,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
-/* trace: */
-#if 0
-# define VTRACE(A) TRACE A
-#else
-# define VTRACE(A)
-#endif
-
-
/* IDirect3DVolume IUnknown parts follow: */
HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface,REFIID riid,LPVOID *ppobj)
{
Index: dlls/d3d8/utils.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/utils.c,v
retrieving revision 1.5
diff -u -r1.5 utils.c
--- dlls/d3d8/utils.c 6 Jun 2003 18:12:59 -0000 1.5
+++ dlls/d3d8/utils.c 7 Jun 2003 23:27:23 -0000
@@ -35,13 +35,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-
-#if 0
-# define VTRACE(A) TRACE A
-#else
-# define VTRACE(A)
-#endif
-
const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
switch (devtype) {
#define DEVTYPE_TO_STR(dev) case dev: return #dev
Index: dlls/d3d8/vshaderdeclaration.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/vshaderdeclaration.c,v
retrieving revision 1.3
diff -u -r1.3 vshaderdeclaration.c
--- dlls/d3d8/vshaderdeclaration.c 17 May 2003 18:33:02 -0000 1.3
+++ dlls/d3d8/vshaderdeclaration.c 7 Jun 2003 23:27:24 -0000
@@ -203,6 +203,7 @@
/*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/
object->device = This; /* FIXME: AddRef(This) */
object->ref = 1;
+ object->allFVF = 0;
while (D3DVSD_END() != *pToken) {
token = *pToken;
@@ -215,16 +216,27 @@
* how really works streams,
* in DolphinVS dx8 dsk sample they seems to decal reg numbers !!!
*/
+ DWORD oldStream = stream;
stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
- if (stream > 0) {
- /** fvf cannot map mutliple streams, so invalid fvf computing */
- invalid_fvf = TRUE;
+ /* copy fvf if valid */
+ if (FALSE == invalid_fvf) {
+ fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
+ tex = 0;
+ object->fvf[oldStream] = fvf;
+ object->allFVF |= fvf;
+ } else {
+ object->fvf[oldStream] = 0;
+ tex = 0;
}
+ /* reset valid/invalid fvf */
+ fvf = 0;
+ invalid_fvf = FALSE;
+
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
- DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT) - stream;
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
switch (reg) {
case D3DVSDE_POSITION:
@@ -241,7 +253,7 @@
}
}
break;
-
+
case D3DVSDE_BLENDWEIGHT:
switch (type) {
case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break;
@@ -305,40 +317,54 @@
}
break;
- /**
- * TODO: for TEX* only FLOAT2 supported
- * by default using texture type info
- */
- case D3DVSDE_TEXCOORD0: tex = max(tex, D3DFVF_TEX1); break;
- case D3DVSDE_TEXCOORD1: tex = max(tex, D3DFVF_TEX2); break;
- case D3DVSDE_TEXCOORD2: tex = max(tex, D3DFVF_TEX3); break;
- case D3DVSDE_TEXCOORD3: tex = max(tex, D3DFVF_TEX4); break;
- case D3DVSDE_TEXCOORD4: tex = max(tex, D3DFVF_TEX5); break;
- case D3DVSDE_TEXCOORD5: tex = max(tex, D3DFVF_TEX6); break;
- case D3DVSDE_TEXCOORD6: tex = max(tex, D3DFVF_TEX7); break;
- case D3DVSDE_TEXCOORD7: tex = max(tex, D3DFVF_TEX8); break;
+ case D3DVSDE_TEXCOORD0:
+ case D3DVSDE_TEXCOORD1:
+ case D3DVSDE_TEXCOORD2:
+ case D3DVSDE_TEXCOORD3:
+ case D3DVSDE_TEXCOORD4:
+ case D3DVSDE_TEXCOORD5:
+ case D3DVSDE_TEXCOORD6:
+ case D3DVSDE_TEXCOORD7:
+ /* Fixme? - assume all tex coords in same stream */
+ {
+ int texNo = 1 + (reg - D3DVSDE_TEXCOORD0);
+ tex = max(tex, texNo);
+ switch (type) {
+ case D3DVSDT_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break;
+ case D3DVSDT_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break;
+ case D3DVSDT_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break;
+ case D3DVSDT_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_TEXCOORD? register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ }
+ break;
case D3DVSDE_POSITION2: /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */
case D3DVSDE_NORMAL2: /* FIXME i don't know what to do here ;( */
- FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token);
+ TRACE("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token);
break;
}
- /*TRACE("VertexShader declaration define %x as current FVF\n", fvf);*/
+ TRACE("VertexShader declaration define %lx as current FVF\n", fvf);
}
len += tokenlen;
pToken += tokenlen;
}
- if (tex > 0) {
- /*TRACE("VertexShader declaration define %x as texture level\n", tex);*/
- fvf |= tex;
- }
/* here D3DVSD_END() */
len += Direct3DVextexShaderDeclarationImpl_ParseToken(pToken);
+
/* copy fvf if valid */
- if (FALSE == invalid_fvf)
- object->fvf = fvf;
- else
- object->fvf = 0;
+ if (FALSE == invalid_fvf) {
+ fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
+ object->fvf[stream] = fvf;
+ object->allFVF |= fvf;
+ } else {
+ object->fvf[stream] = 0;
+ }
+ TRACE("Completed, allFVF = %lx\n", object->allFVF);
+
/* compute size */
object->declaration8Length = len * sizeof(DWORD);
/* copy the declaration */
@@ -352,9 +378,7 @@
HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* This,
IDirect3DVertexShaderImpl* vshader,
- const void* vertexFirstStream,
- DWORD StartVertexIndex,
- DWORD idxDecal) {
+ DWORD SkipnStrides) {
/** parser data */
const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8;
DWORD stream = 0;
@@ -367,7 +391,7 @@
SHORT u, v, r, t;
DWORD dw;
- TRACE("(%p) - This:%p - stream:%p, startIdx=%lu, idxDecal=%lu\n", vshader, This, vertexFirstStream, StartVertexIndex, idxDecal);
+ TRACE("(%p) - This:%p, skipstrides=%lu\n", vshader, This, SkipnStrides);
while (D3DVSD_END() != *pToken) {
token = *pToken;
@@ -376,7 +400,6 @@
/** FVF generation block */
if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
IDirect3DVertexBuffer8* pVB;
- const char* startVtx = NULL;
int skip = 0;
++pToken;
@@ -385,25 +408,21 @@
* in DolphinVS dx8 dsk sample use it !!!
*/
stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
-
- if (0 == stream) {
- skip = This->StateBlock->stream_stride[0];
- startVtx = (const char*) vertexFirstStream + (StartVertexIndex * skip);
- curPos = startVtx + idxDecal;
- /*TRACE(" using stream[%lu] with %lu decal => curPos %p\n", stream, idxDecal, curPos);*/
- } else {
- skip = This->StateBlock->stream_stride[stream];
- pVB = This->StateBlock->stream_source[stream];
-
- if (NULL == pVB) {
+ skip = This->StateBlock->stream_stride[stream];
+ pVB = This->StateBlock->stream_source[stream];
+
+ if (NULL == pVB) {
ERR("using unitialised stream[%lu]\n", stream);
return D3DERR_INVALIDCALL;
- } else {
- startVtx = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (StartVertexIndex * skip);
- /** do we need to decal if we use idxBuffer */
- curPos = startVtx + idxDecal;
- /*TRACE(" using stream[%lu] with %lu decal\n", stream, idxDecal);*/
- }
+ } else {
+ if (This->StateBlock->streamIsUP == TRUE) {
+ curPos = ((char *) pVB) + (SkipnStrides * skip); /* Not really a VB */
+ } else {
+ curPos = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (SkipnStrides * skip);
+ }
+
+ TRACE(" using stream[%lu] with %p (%p + (Stride %d * skip %ld))\n", stream, curPos,
+ ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory, skip, SkipnStrides);
}
} else if (D3DVSD_TOKEN_CONSTMEM == tokentype) {
/** Const decl */
--- /dev/null 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3d8/drawprim.c 2003-06-08 01:20:44.000000000 +0100
@@ -0,0 +1,1343 @@
+/*
+ * D3D8 utils
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <math.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
+
+extern IDirect3DVertexShaderImpl* VertexShaders[64];
+extern IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
+extern IDirect3DPixelShaderImpl* PixelShaders[64];
+
+/* Useful holding place for 4 floats */
+typedef struct _D3DVECTOR_4 {
+ float x;
+ float y;
+ float z;
+ float w;
+} D3DVECTOR_4;
+
+#undef GL_VERSION_1_4 /* To be fixed, caused by mesa headers */
+
+/* Returns bits for what is expected from the fixed function pipeline, and whether
+ a vertex shader will be in use. Note the fvf bits returned may be split over
+ multiple streams only if the vertex shader was created, otherwise it all relates
+ to stream 0 */
+BOOL initializeFVF(LPDIRECT3DDEVICE8 iface,
+ DWORD *FVFbits, /* What to expect in the FVF across all streams */
+ BOOL *useVertexShaderFunction) /* Should we use the vertex shader */
+{
+
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ /* The first thing to work out is if we are using the fixed function pipeline
+ which is either SetVertexShader with < VS_HIGHESTFIXEDFXF - in which case this
+ is the FVF, or with a shader which was created with no function - in which
+ case there is an FVF per declared stream. If this occurs, we also maintain
+ an 'OR' of all the FVF's together so we know what to expect across all the
+ streams */
+
+ if (This->UpdateStateBlock->VertexShader <= VS_HIGHESTFIXEDFXF) {
+
+ /* Use this as the FVF */
+ *FVFbits = This->UpdateStateBlock->VertexShader;
+ *useVertexShaderFunction = FALSE;
+ TRACE("FVF explicitally defined, using fixed function pipeline with FVF=%lx\n", *FVFbits);
+
+ } else {
+
+ /* Use created shader */
+ IDirect3DVertexShaderImpl* vertex_shader = NULL;
+ vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader);
+
+ if (vertex_shader == NULL) {
+
+ /* Hmm - User pulled figure out of the air? Unlikely, probably a bug */
+ ERR("trying to use unitialised vertex shader: %lu\n", This->UpdateStateBlock->VertexShader);
+ return TRUE;
+
+ } else {
+
+ *FVFbits = This->UpdateStateBlock->vertexShaderDecl->allFVF;
+
+ if (vertex_shader->function == NULL) {
+ /* No function, so many streams supplied plus FVF definition pre stream */
+ *useVertexShaderFunction = FALSE;
+ TRACE("vertex shader (%lx) declared without program, using fixed function pipeline with FVF=%lx\n",
+ This->StateBlock->VertexShader, *FVFbits);
+ } else {
+ /* Vertex shader needs calling */
+ *useVertexShaderFunction = TRUE;
+ TRACE("vertex shader will be used (unusued FVF=%lx)\n", *FVFbits);
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* Issues the glBegin call for gl given the primitive type and count */
+DWORD primitiveToGl(D3DPRIMITIVETYPE PrimitiveType,
+ DWORD NumPrimitives,
+ GLenum *primType)
+{
+ DWORD NumVertexes = NumPrimitives;
+
+ switch (PrimitiveType) {
+ case D3DPT_POINTLIST:
+ TRACE("POINTS\n");
+ *primType = GL_POINTS;
+ NumVertexes = NumPrimitives;
+ break;
+
+ case D3DPT_LINELIST:
+ TRACE("LINES\n");
+ *primType = GL_LINES;
+ NumVertexes = NumPrimitives * 2;
+ break;
+
+ case D3DPT_LINESTRIP:
+ TRACE("LINE_STRIP\n");
+ *primType = GL_LINE_STRIP;
+ NumVertexes = NumPrimitives + 1;
+ break;
+
+ case D3DPT_TRIANGLELIST:
+ TRACE("TRIANGLES\n");
+ *primType = GL_TRIANGLES;
+ NumVertexes = NumPrimitives * 3;
+ break;
+
+ case D3DPT_TRIANGLESTRIP:
+ TRACE("TRIANGLE_STRIP\n");
+ *primType = GL_TRIANGLE_STRIP;
+ NumVertexes = NumPrimitives + 2;
+ break;
+
+ case D3DPT_TRIANGLEFAN:
+ TRACE("TRIANGLE_FAN\n");
+ *primType = GL_TRIANGLE_FAN;
+ NumVertexes = NumPrimitives + 2;
+ break;
+
+ default:
+ FIXME("Unhandled primitive\n");
+ *primType = GL_POINTS;
+ break;
+ }
+ return NumVertexes;
+}
+
+/* Setup views - Transformed & lit if RHW, else untransformed.
+ Only unlit if Normals are supplied
+ Returns: Whether to restore lighting afterwards */
+BOOL primitiveInitState(LPDIRECT3DDEVICE8 iface, BOOL vtx_transformed, BOOL vtx_lit) {
+
+ BOOL isLightingOn = FALSE;
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
+ set by the appropriate render state */
+ if (vtx_lit) {
+ isLightingOn = glIsEnabled(GL_LIGHTING);
+ glDisable(GL_LIGHTING);
+ checkGLcall("glDisable(GL_LIGHTING);");
+ TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
+ }
+
+ if (vtx_transformed) {
+ double X, Y, height, width, minZ, maxZ;
+
+ /* Transformed already into viewport coordinates, so we do not need transform
+ matrices. Reset all matrices to identity and leave the default matrix in world
+ mode. */
+ glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity");
+ /**
+ * As seen in d3d7 code:
+ * See the OpenGL Red Book for an explanation of the following translation (in the OpenGL
+ * Correctness Tips section).
+ */
+ glTranslatef(0.375f, 0.375f, 0.0f);
+ checkGLcall("glTranslatef(0.375f, 0.375f, 0.0f)");
+
+ glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity");
+
+ /* Set up the viewport to be full viewport */
+ X = This->StateBlock->viewport.X;
+ Y = This->StateBlock->viewport.Y;
+ height = This->StateBlock->viewport.Height;
+ width = This->StateBlock->viewport.Width;
+ minZ = This->StateBlock->viewport.MinZ;
+ maxZ = This->StateBlock->viewport.MaxZ;
+ TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
+ glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
+ checkGLcall("glOrtho");
+
+ } else {
+
+ /* Untransformed, so relies on the view and projection matrices */
+ glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode");
+ glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
+ checkGLcall("glMultMatrixf");
+
+
+ glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode");
+ glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ }
+ return isLightingOn;
+}
+
+void primitiveConvertToStridedData(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *strided, LONG BaseVertexIndex) {
+
+ short LoopThroughTo = 0;
+ short nStream;
+ BOOL canDoViaGLPointers = TRUE;
+ int numBlends;
+ int numTextures;
+ int textureNo;
+ int coordIdxInfo = 0x00; /* Information on number of coords supplied */
+ int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */
+
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ /* OK, Now to setup the data locations
+ For the non-created vertex shaders, the VertexShader var holds the real
+ FVF and only stream 0 matters
+ For the created vertex shaders, there is an FVF per stream */
+ if (This->UpdateStateBlock->VertexShader > VS_HIGHESTFIXEDFXF) {
+ LoopThroughTo = MAX_STREAMS;
+ } else {
+ LoopThroughTo = 1;
+ }
+
+ /* Work through stream by stream */
+ for (nStream=0; nStream<LoopThroughTo; nStream++) {
+ DWORD stride = This->StateBlock->stream_stride[nStream];
+ BYTE *data = NULL;
+ DWORD thisFVF = 0;
+
+ /* Skip empty streams */
+ if (This->StateBlock->stream_source[nStream] == NULL) continue;
+
+ /* Retrieve appropriate FVF */
+ if (LoopThroughTo == 1) { /* VertexShader is FVF */
+ thisFVF = This->UpdateStateBlock->VertexShader;
+ /* Handle memory passed directly as well as vertex buffers */
+ if (This->StateBlock->streamIsUP == TRUE) {
+ data = (BYTE *)This->StateBlock->stream_source[nStream];
+ } else {
+ data = ((IDirect3DVertexBuffer8Impl *)This->StateBlock->stream_source[nStream])->allocatedMemory;
+ }
+ } else {
+ thisFVF = This->StateBlock->vertexShaderDecl->fvf[nStream];
+ data = ((IDirect3DVertexBuffer8Impl *)This->StateBlock->stream_source[nStream])->allocatedMemory;
+ }
+ VTRACE(("FVF for stream %d is %lx\n", nStream, thisFVF));
+ if (thisFVF == 0) continue;
+
+ /* Now convert the stream into pointers */
+
+ /* Shuffle to the beginning of the vertexes to render and index from there */
+ data = data + (BaseVertexIndex * stride);
+
+ /* Either 3 or 4 floats depending on the FVF */
+ /* FIXME: Can blending data be in a different stream to the position data?
+ and if so using the fixed pipeline how do we handle it */
+ if (thisFVF & D3DFVF_POSITION_MASK) {
+ strided->u.s.position.lpData = data;
+ strided->u.s.position.dwType = D3DVSDT_FLOAT3;
+ strided->u.s.position.dwStride = stride;
+ data += 3 * sizeof(float);
+ if (thisFVF & D3DFVF_XYZRHW) {
+ strided->u.s.position.dwType = D3DVSDT_FLOAT4;
+ data += sizeof(float);
+ }
+ }
+
+ /* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */
+ /** do we have to Check This->UpdateStateBlock->renderstate[D3DRS_INDEXEDVERTEXBLENDENABLE] ? */
+ numBlends = ((thisFVF & D3DFVF_POSITION_MASK) >> 1) - 2 +
+ ((FALSE == (thisFVF & D3DFVF_LASTBETA_UBYTE4)) ? 0 : -1); /* WARNING can be < 0 because -2 */
+ if (numBlends > 0) {
+ canDoViaGLPointers = FALSE;
+ strided->u.s.blendWeights.lpData = data;
+ strided->u.s.blendWeights.dwType = D3DVSDT_FLOAT1 + (numBlends - 1);
+ strided->u.s.blendWeights.dwStride = stride;
+ data += numBlends * sizeof(FLOAT);
+
+ if (thisFVF & D3DFVF_LASTBETA_UBYTE4) {
+ strided->u.s.blendMatrixIndices.lpData = data;
+ strided->u.s.blendMatrixIndices.dwType = D3DVSDT_UBYTE4;
+ strided->u.s.blendMatrixIndices.dwStride= stride;
+ data += sizeof(DWORD);
+ }
+ }
+
+ /* Normal is always 3 floats */
+ if (thisFVF & D3DFVF_NORMAL) {
+ strided->u.s.normal.lpData = data;
+ strided->u.s.normal.dwType = D3DVSDT_FLOAT3;
+ strided->u.s.normal.dwStride = stride;
+ data += 3 * sizeof(FLOAT);
+ }
+
+ /* Pointsize is a single float */
+ if (thisFVF & D3DFVF_PSIZE) {
+ strided->u.s.pSize.lpData = data;
+ strided->u.s.pSize.dwType = D3DVSDT_FLOAT1;
+ strided->u.s.pSize.dwStride = stride;
+ data += sizeof(FLOAT);
+ }
+
+ /* Diffuse is 4 unsigned bytes */
+ if (thisFVF & D3DFVF_DIFFUSE) {
+ strided->u.s.diffuse.lpData = data;
+ strided->u.s.diffuse.dwType = D3DVSDT_SHORT4;
+ strided->u.s.diffuse.dwStride = stride;
+ data += sizeof(DWORD);
+ }
+
+ /* Specular is 4 unsigned bytes */
+ if (thisFVF & D3DFVF_SPECULAR) {
+ strided->u.s.specular.lpData = data;
+ strided->u.s.specular.dwType = D3DVSDT_SHORT4;
+ strided->u.s.specular.dwStride = stride;
+ data += sizeof(DWORD);
+ }
+
+ /* Texture coords */
+ numTextures = (thisFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
+ coordIdxInfo = (thisFVF & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */
+
+ /* numTextures indicates the number of texture coordinates supplied */
+ /* However, the first set may not be for stage 0 texture - it all */
+ /* depends on D3DTSS_TEXCOORDINDEX. */
+ /* The number of bytes for each coordinate set is based off */
+ /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
+
+ /* So, for each supplied texture extract the coords */
+ for (textureNo = 0; textureNo < numTextures; ++textureNo) {
+
+ strided->u.s.texCoords[textureNo].lpData = data;
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT1;
+ strided->u.s.texCoords[textureNo].dwStride = stride;
+ numCoords[textureNo] = coordIdxInfo & 0x03;
+
+ /* Always one set */
+ data += sizeof(float);
+ if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT2;
+ data += sizeof(float);
+ if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT3;
+ data += sizeof(float);
+ if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT4;
+ data += sizeof(float);
+ }
+ }
+ }
+ coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
+ }
+ }
+}
+
+/* Draw a single vertex using this information */
+void draw_vertex(LPDIRECT3DDEVICE8 iface, /* interface */
+ BOOL isXYZ, float x, float y, float z, float rhw, /* xyzn position*/
+ BOOL isNormal, float nx, float ny, float nz, /* normal */
+ BOOL isDiffuse, float *dRGBA, /* 1st colors */
+ BOOL isSpecular, float *sRGB, /* 2ndry colors */
+ BOOL isPtSize, float ptSize, /* pointSize */
+ D3DVECTOR_4 *texcoords, int *numcoords) /* texture info */
+{
+ int textureNo;
+ float s, t, r, q;
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ /* Diffuse -------------------------------- */
+ if (isDiffuse == TRUE) {
+ glColor4fv(dRGBA);
+ VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n", dRGBA[0], dRGBA[1], dRGBA[2], dRGBA[3]));
+ }
+
+ /* Specular Colour ------------------------------------------*/
+ if (isSpecular == TRUE) {
+#if defined(GL_EXT_secondary_color)
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+ GL_EXTCALL(glSecondaryColor3fvEXT(sRGB));
+ VTRACE(("glSecondaryColor4f: r,g,b=%f,%f,%f\n", sRGB[0], sRGB[1], sRGB[2]));
+ }
+#endif
+ }
+
+ /* Normal -------------------------------- */
+ if (isNormal == TRUE) {
+ VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
+ glNormal3f(nx, ny, nz);
+ }
+
+ /* Point Size ----------------------------------------------*/
+ if (isPtSize == TRUE) {
+
+ /* no such functionality in the fixed function GL pipeline */
+ FIXME("Cannot change ptSize here in openGl\n");
+ }
+
+ /* Texture coords --------------------------- */
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+ continue ;
+ }
+
+ /* Query tex coords */
+ if (This->StateBlock->textures[textureNo] != NULL) {
+
+ int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
+ if (coordIdx > 7) {
+ VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
+ continue;
+ } else if (numcoords[coordIdx] == 0) {
+ TRACE("tex: %d - Skipping tex coords, as no data supplied or no coords supplied\n", textureNo);
+ continue;
+ } else {
+
+ /* Initialize vars */
+ s = 0.0f;
+ t = 0.0f;
+ r = 0.0f;
+ q = 0.0f;
+
+ switch (numcoords[coordIdx]) {
+ case 4: q = texcoords[coordIdx].w; /* drop through */
+ case 3: r = texcoords[coordIdx].z; /* drop through */
+ case 2: t = texcoords[coordIdx].y; /* drop through */
+ case 1: s = texcoords[coordIdx].x;
+ }
+
+ switch (numcoords[coordIdx]) { /* Supply the provided texture coords */
+ case D3DTTFF_COUNT1:
+ VTRACE(("tex:%d, s=%f\n", textureNo, s));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s);
+#else
+ glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s);
+#endif
+ } else {
+ glTexCoord1f(s);
+ }
+ break;
+ case D3DTTFF_COUNT2:
+ VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
+#else
+ glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
+#endif
+ } else {
+ glTexCoord2f(s, t);
+ }
+ break;
+ case D3DTTFF_COUNT3:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
+#else
+ glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
+#endif
+ } else {
+ glTexCoord3f(s, t, r);
+ }
+ break;
+ case D3DTTFF_COUNT4:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s, t, r, q);
+#else
+ glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s, t, r, q);
+#endif
+ } else {
+ glTexCoord4f(s, t, r, q);
+ }
+ break;
+ default:
+ FIXME("Should not get here as numCoords should be 0->4 (%x)!\n", numcoords[coordIdx]);
+ }
+ }
+ }
+ } /* End of textures */
+
+ /* Position -------------------------------- */
+ if (isXYZ == TRUE) {
+ if (1.0f == rhw || rhw < 0.01f) {
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
+ glVertex3f(x, y, z);
+ } else {
+ GLfloat w = 1.0f / rhw;
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
+ glVertex4f(x * w, y * w, z * w, 1.0f);
+ }
+ }
+}
+
+/*
+ * Actually draw using the supplied information.
+ * Faster GL version using pointers to data, harder to debug though
+ * Note does not handle vertex shaders yet
+ */
+void drawStridedFast(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd,
+ int PrimitiveType, ULONG NumPrimitives,
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+ int textureNo = 0;
+ GLenum glPrimType = GL_POINTS;
+ int NumVertexes = NumPrimitives;
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ TRACE("Using fast vertex array code\n");
+
+ /* Vertex Pointers -----------------------------------------*/
+ if (sd->u.s.position.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glVertexPointer(%ld, GL_FLOAT, %ld, %p)\n",
+ sd->u.s.position.dwStride,
+ sd->u.s.position.dwType + 1,
+ sd->u.s.position.lpData));
+ glVertexPointer(sd->u.s.position.dwType + 1, GL_FLOAT,
+ sd->u.s.position.dwStride,
+ sd->u.s.position.lpData);
+ checkGLcall("glVertexPointer(...)");
+ glEnableClientState(GL_VERTEX_ARRAY);
+ checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
+
+ } else {
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
+ }
+
+ /* Blend Data ----------------------------------------------*/
+ if ((sd->u.s.blendWeights.lpData != NULL) ||
+ (sd->u.s.blendMatrixIndices.lpData != NULL)) {
+ /* FIXME: Wont get here as will drop to slow method */
+ FIXME("Blending not supported in fast draw routine\n");
+
+#if 0 /* Vertex blend support needs to be added */
+ if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
+ /*FIXME("TODO\n");*/
+ } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
+ /*FIXME("TODO\n");*/
+ /*
+ GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
+ checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
+ glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
+ checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
+ */
+ } else {
+ FIXME("unsupported blending in openGl\n");
+ }
+ } else {
+ if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
+ FIXME("TODO\n");
+ } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
+ FIXME("TODO\n");
+ /*
+ glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
+ checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
+ */
+ }
+#endif
+ }
+
+ /* Normals -------------------------------------------------*/
+ if (sd->u.s.normal.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glNormalPointer(GL_FLOAT, %ld, %p)\n",
+ sd->u.s.normal.dwStride,
+ sd->u.s.normal.lpData));
+ glNormalPointer(GL_FLOAT,
+ sd->u.s.normal.dwStride,
+ sd->u.s.normal.lpData);
+ checkGLcall("glNormalPointer(...)");
+ glEnableClientState(GL_NORMAL_ARRAY);
+ checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
+
+ } else {
+
+ glDisableClientState(GL_NORMAL_ARRAY);
+ checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
+ glNormal3f(0, 0, 1);
+ checkGLcall("glNormal3f(0, 0, 1)");
+ }
+
+ /* Point Size ----------------------------------------------*/
+ if (sd->u.s.pSize.lpData != NULL) {
+
+ /* no such functionality in the fixed function GL pipeline */
+ /* FIXME: Wont get here as will drop to slow method */
+ FIXME("Cannot change ptSize here in openGl\n");
+ }
+
+ /* Diffuse Colour ------------------------------------------*/
+ /* WARNING: Data here MUST be in RGBA format, so cannot */
+ /* go directly into fast mode from app pgm, because */
+ /* directx requires data in BGRA format. */
+ if (sd->u.s.diffuse.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %ld, %p)\n",
+ sd->u.s.diffuse.dwStride,
+ sd->u.s.diffuse.lpData));
+ glColorPointer(4, GL_UNSIGNED_BYTE,
+ sd->u.s.diffuse.dwStride,
+ sd->u.s.diffuse.lpData);
+ checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
+ glEnableClientState(GL_COLOR_ARRAY);
+ checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
+
+ } else {
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ checkGLcall("glColor4f(1, 1, 1, 1)");
+ }
+
+ /* Specular Colour ------------------------------------------*/
+ if (sd->u.s.specular.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %ld, %p)\n",
+ sd->u.s.specular.dwStride,
+ sd->u.s.specular.lpData));
+
+#if defined(GL_VERSION_1_4)
+ glSecondaryColorPointer(4, GL_UNSIGNED_BYTE,
+ sd->u.s.specular.dwStride,
+ sd->u.s.specular.lpData);
+ vcheckGLcall("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, ...)");
+ glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
+ vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY)");
+#elif defined(GL_EXT_secondary_color)
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+ GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
+ sd->u.s.specular.dwStride,
+ sd->u.s.specular.lpData);
+ checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
+ glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
+ checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
+ }
+#else
+ /* Missing specular color is not critical, no warnings */
+ VTRACE(("Specular colour is not supported in this GL implementation\n"));
+#endif
+
+ } else {
+
+#if defined(GL_VERSION_1_4)
+ glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
+ checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY)");
+ glSecondaryColor3f(0, 0, 0);
+ checkGLcall("glSecondaryColor3f(0, 0, 0)");
+#elif defined(GL_EXT_secondary_color)
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+ glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
+ checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
+ GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+ checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
+ }
+#else
+ /* Do not worry if specular colour missing and disable request */
+#endif
+ }
+
+ /* Texture coords -------------------------------------------*/
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+ continue ;
+ }
+
+ /* Query tex coords */
+ if (This->StateBlock->textures[textureNo] != NULL) {
+ int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
+
+ if (coordIdx > 7) {
+ VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
+ } else if (sd->u.s.texCoords[coordIdx].lpData == NULL) {
+ VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
+ } else {
+ int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DVSDT_FLOAT1 etc */
+ int numFloats = coordsToUse;
+#if defined(GL_VERSION_1_3)
+ glClientActiveTexture(GL_TEXTURE0 + textureNo);
+#else
+ glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
+#endif
+ /* If texture transform flags in effect, values passed through to vertex
+ depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
+
+ /* This indicates how many coords to use regardless of the
+ texture type. However, d3d/opengl fill in the rest appropriately */
+ coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
+
+ /* BUT - Projected is more 'fun' - Cant be done for ptr mode.
+ Probably should scan enabled texture units and drop back to
+ slow mode if found? */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+ FIXME("Cannot handle projected transform state in fast mode\n");
+ }
+
+ /* coordsToUse maps to D3DTTFF_COUNT1,2,3,4 == 1,2,3,4 which is correct */
+ }
+ if (numFloats == 0) {
+ FIXME("Skipping as invalid request - numfloats=%d, coordIdx=%d\n", numFloats, coordIdx);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
+ } else {
+ VTRACE(("tex: %d, ptr=%p, numcoords=%d\n", textureNo, sd->u.s.texCoords[coordIdx].lpData, numFloats));
+ glTexCoordPointer(numFloats, GL_FLOAT, sd->u.s.texCoords[coordIdx].dwStride, sd->u.s.texCoords[coordIdx].lpData);
+ checkGLcall("glTexCoordPointer(x, ...)");
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
+ }
+ }
+ }
+ }
+
+ /* Ok, Work out which primitive is requested and how many vertexes that
+ will be */
+ NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
+
+ /* Finally do the drawing */
+ if (idxData != NULL) {
+
+ TRACE("glElements(%x, %d, %ld, ...)\n", glPrimType, NumVertexes, minIndex);
+ if (idxSize==2) {
+#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
+ glDrawElements(glPrimType, NumVertexes, GL_UNSIGNED_SHORT,
+ (char *)idxData+(2 * startIdx));
+#else
+ glDrawRangeElements(glPrimType, minIndex, minIndex+NumVertexes-1, NumVertexes,
+ GL_UNSIGNED_SHORT, (char *)idxData+(2 * startIdx));
+#endif
+ } else {
+#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
+ glDrawElements(glPrimType, NumVertexes, GL_UNSIGNED_INT,
+ (char *)idxData+(4 * startIdx));
+#else
+ glDrawRangeElements(glPrimType, minIndex, minIndex+NumVertexes-1, NumVertexes,
+ GL_UNSIGNED_INT, (char *)idxData+(2 * startIdx));
+#endif
+ }
+ checkGLcall("glDrawRangeElements");
+
+ } else {
+
+ /* Note first is now zero as we shuffled along earlier */
+ TRACE("glDrawArrays(%x, 0, %d)\n", glPrimType, NumVertexes);
+ glDrawArrays(glPrimType, 0, NumVertexes);
+ checkGLcall("glDrawArrays");
+
+ }
+}
+
+/*
+ * Actually draw using the supplied information.
+ * Slower GL version which extracts info about each vertex in turn
+ */
+void drawStridedSlow(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd,
+ int PrimitiveType, ULONG NumPrimitives,
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+
+ int textureNo = 0;
+ GLenum glPrimType = GL_POINTS;
+ int NumVertexes = NumPrimitives;
+ const short *pIdxBufS = NULL;
+ const long *pIdxBufL = NULL;
+ LONG SkipnStrides = 0;
+ LONG vx_index;
+ float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
+ float nx = 0.0f, ny = 0.0, nz = 0.0f; /* normal x,y,z coordinates */
+ float rhw = 0.0f; /* rhw */
+ float ptSize = 0.0f; /* Point size */
+ DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
+ DWORD specularColor = 0; /* Specular Color */
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ TRACE("Using slow vertex array code\n");
+
+ /* Variable Initialization */
+ if (idxData != NULL) {
+ if (idxSize == 2) pIdxBufS = (short *) idxData;
+ else pIdxBufL = (long *) idxData;
+ }
+
+ /* Ok, Work out which primitive is requested and how many vertexes that will be */
+ NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
+
+ /* Start drawing in GL */
+ VTRACE(("glBegin(%x)\n", glPrimType));
+ glBegin(glPrimType);
+
+ /* For each primitive */
+ for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
+
+ /* Initialize diffuse color */
+ diffuseColor = 0xFFFFFFFF;
+
+ /* For indexed data, we need to go a few more strides in */
+ if (idxData != NULL) {
+
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2) {
+ VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ SkipnStrides = pIdxBufS[startIdx+vx_index];
+ } else {
+ VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ SkipnStrides = pIdxBufL[startIdx+vx_index];
+ }
+ }
+
+ /* Position Information ------------------ */
+ if (sd->u.s.position.lpData != NULL) {
+
+ float *ptrToCoords = (float *)(sd->u.s.position.lpData + (SkipnStrides * sd->u.s.position.dwStride));
+ x = ptrToCoords[0];
+ y = ptrToCoords[1];
+ z = ptrToCoords[2];
+ rhw = 1.0;
+ VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
+
+ /* RHW follows, only if transformed, ie 4 floats were provided */
+ if (sd->u.s.position.dwType == D3DVSDT_FLOAT4) {
+ rhw = ptrToCoords[3];
+ VTRACE(("rhw=%f\n", rhw));
+ }
+ }
+
+ /* Blending data -------------------------- */
+ if (sd->u.s.blendWeights.lpData != NULL) {
+ /*float *ptrToCoords = (float *)(sd->u.s.blendWeights.lpData + (SkipnStrides * sd->u.s.blendWeights.dwStride));*/
+ FIXME("Blending not supported yet\n");
+
+ if (sd->u.s.blendMatrixIndices.lpData != NULL) {
+ /*DWORD *ptrToCoords = (DWORD *)(sd->u.s.blendMatrixIndices.lpData + (SkipnStrides * sd->u.s.blendMatrixIndices.dwStride));*/
+ }
+ }
+
+ /* Vertex Normal Data (untransformed only)- */
+ if (sd->u.s.normal.lpData != NULL) {
+
+ float *ptrToCoords = (float *)(sd->u.s.normal.lpData + (SkipnStrides * sd->u.s.normal.dwStride));
+ nx = ptrToCoords[0];
+ ny = ptrToCoords[1];
+ nz = ptrToCoords[2];
+ VTRACE(("nx,ny,nz=%f,%f,%f\n", nx, ny, nz));
+ }
+
+ /* Point Size ----------------------------- */
+ if (sd->u.s.pSize.lpData != NULL) {
+
+ float *ptrToCoords = (float *)(sd->u.s.pSize.lpData + (SkipnStrides * sd->u.s.pSize.dwStride));
+ ptSize = ptrToCoords[0];
+ VTRACE(("ptSize=%f\n", ptSize));
+ FIXME("No support for ptSize yet\n");
+ }
+
+ /* Diffuse -------------------------------- */
+ if (sd->u.s.diffuse.lpData != NULL) {
+
+ DWORD *ptrToCoords = (DWORD *)(sd->u.s.diffuse.lpData + (SkipnStrides * sd->u.s.diffuse.dwStride));
+ diffuseColor = ptrToCoords[0];
+ VTRACE(("diffuseColor=%lx\n", diffuseColor));
+ }
+
+ /* Specular -------------------------------- */
+ if (sd->u.s.specular.lpData != NULL) {
+
+ DWORD *ptrToCoords = (DWORD *)(sd->u.s.specular.lpData + (SkipnStrides * sd->u.s.specular.dwStride));
+ specularColor = ptrToCoords[0];
+ VTRACE(("specularColor=%lx\n", specularColor));
+ }
+
+ /* Texture coords --------------------------- */
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+ continue ;
+ }
+
+ /* Query tex coords */
+ if (This->StateBlock->textures[textureNo] != NULL) {
+
+ int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
+ float *ptrToCoords = (float *)(sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
+ float s = 0.0, t = 0.0, r = 0.0, q = 0.0;
+
+ if (coordIdx > 7) {
+ VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
+ continue;
+ } else if (sd->u.s.texCoords[coordIdx].lpData == NULL) {
+ TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
+ continue;
+ } else {
+
+ int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DVSDT_FLOAT1 etc */
+
+ /* If texture transform flags in effect, values passed through to vertex
+ depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
+
+ /* This indicates how many coords to use regardless of the
+ texture type. However, d3d/opengl fill in the rest appropriately */
+ coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
+
+ switch (coordsToUse) {
+ case 4: q = ptrToCoords[3]; /* drop through */
+ case 3: r = ptrToCoords[2]; /* drop through */
+ case 2: t = ptrToCoords[1]; /* drop through */
+ case 1: s = ptrToCoords[0];
+ }
+
+ /* BUT - Projected is more 'fun' - Move the last coord to the 'q'
+ parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+ switch (coordsToUse) {
+ case 0: /* Drop Through */
+ case 1:
+ FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n");
+ break;
+ case 2:
+ q = t;
+ t = 0.0;
+ coordsToUse = 4;
+ break;
+ case 3:
+ q = r;
+ r = 0.0;
+ coordsToUse = 4;
+ break;
+ case 4: /* Nop here */
+ break;
+ default:
+ FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n",
+ This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
+ }
+ }
+ } else {
+ switch (coordsToUse) {
+ case 4: q = ptrToCoords[3]; /* drop through */
+ case 3: r = ptrToCoords[2]; /* drop through */
+ case 2: t = ptrToCoords[1]; /* drop through */
+ case 1: s = ptrToCoords[0];
+ }
+ }
+
+ switch (coordsToUse) { /* Supply the provided texture coords */
+ case D3DTTFF_COUNT1:
+ VTRACE(("tex:%d, s=%f\n", textureNo, s));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s);
+#else
+ glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s);
+#endif
+ } else {
+ glTexCoord1f(s);
+ }
+ break;
+ case D3DTTFF_COUNT2:
+ VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
+#else
+ glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
+#endif
+ } else {
+ glTexCoord2f(s, t);
+ }
+ break;
+ case D3DTTFF_COUNT3:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
+#else
+ glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
+#endif
+ } else {
+ glTexCoord3f(s, t, r);
+ }
+ break;
+ case D3DTTFF_COUNT4:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s, t, r, q);
+#else
+ glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s, t, r, q);
+#endif
+ } else {
+ glTexCoord4f(s, t, r, q);
+ }
+ break;
+ default:
+ FIXME("Should not get here as coordsToUse is two bits only (%x)!\n", coordsToUse);
+ }
+ }
+ }
+ } /* End of textures */
+
+ /* Diffuse -------------------------------- */
+ if (sd->u.s.diffuse.lpData != NULL) {
+ glColor4ub((diffuseColor >> 16) & 0xFF,
+ (diffuseColor >> 8) & 0xFF,
+ (diffuseColor >> 0) & 0xFF,
+ (diffuseColor >> 24) & 0xFF);
+ VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
+ ((diffuseColor >> 16) & 0xFF) / 255.0f,
+ ((diffuseColor >> 8) & 0xFF) / 255.0f,
+ ((diffuseColor >> 0) & 0xFF) / 255.0f,
+ ((diffuseColor >> 24) & 0xFF) / 255.0f));
+ }
+
+ /* Normal -------------------------------- */
+ if (sd->u.s.normal.lpData != NULL) {
+ VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
+ glNormal3f(nx, ny, nz);
+ }
+
+ /* Position -------------------------------- */
+ if (sd->u.s.position.lpData != NULL) {
+ if (1.0f == rhw || rhw < 0.01f) {
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
+ glVertex3f(x, y, z);
+ } else {
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
+ glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
+ }
+ }
+
+ /* For non indexed mode, step onto next parts */
+ if (idxData == NULL) {
+ SkipnStrides += 1;
+ }
+ }
+
+ glEnd();
+ checkGLcall("glEnd and previous calls");
+}
+
+/*
+ * Draw with emulated vertex shaders
+ * Note: strided data is uninitialized, as we need to pass the vertex
+ * shader directly as ordering irs yet
+ */
+void drawStridedSoftwareVS(LPDIRECT3DDEVICE8 iface, Direct3DVertexStridedData *sd,
+ int PrimitiveType, ULONG NumPrimitives,
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+
+ int textureNo = 0;
+ GLenum glPrimType = GL_POINTS;
+ int NumVertexes = NumPrimitives;
+ const short *pIdxBufS = NULL;
+ const long *pIdxBufL = NULL;
+ LONG SkipnStrides = 0;
+ LONG vx_index;
+ float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
+ float rhw = 0.0f; /* rhw */
+ float ptSize = 0.0f; /* Point size */
+ D3DVECTOR_4 texcoords[8]; /* Texture Coords */
+ int numcoords[8]; /* Number of coords */
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ IDirect3DVertexShaderImpl* vertex_shader = NULL;
+
+ TRACE("Using slow software vertex shader code\n");
+
+ /* Variable Initialization */
+ if (idxData != NULL) {
+ if (idxSize == 2) pIdxBufS = (short *) idxData;
+ else pIdxBufL = (long *) idxData;
+ }
+
+ /* Ok, Work out which primitive is requested and how many vertexes that will be */
+ NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
+
+ /* Retrieve the VS information */
+ vertex_shader = VERTEX_SHADER(This->StateBlock->VertexShader);
+
+ /* Start drawing in GL */
+ VTRACE(("glBegin(%x)\n", glPrimType));
+ glBegin(glPrimType);
+
+ /* For each primitive */
+ for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
+
+ /* For indexed data, we need to go a few more strides in */
+ if (idxData != NULL) {
+
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2) {
+ VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ SkipnStrides = pIdxBufS[startIdx+vx_index];
+ } else {
+ VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ SkipnStrides = pIdxBufL[startIdx+vx_index];
+ }
+ }
+
+ /* Fill the vertex shader input */
+ IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, SkipnStrides);
+
+ /* Now execute the vertex shader */
+ memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
+ IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
+
+ /*
+ TRACE_VECTOR(vertex_shader->output.oPos);
+ TRACE_VECTOR(vertex_shader->output.oD[0]);
+ TRACE_VECTOR(vertex_shader->output.oD[1]);
+ TRACE_VECTOR(vertex_shader->output.oT[0]);
+ TRACE_VECTOR(vertex_shader->output.oT[1]);
+ TRACE_VECTOR(vertex_shader->input.V[0]);
+ TRACE_VECTOR(vertex_shader->data->C[0]);
+ TRACE_VECTOR(vertex_shader->data->C[1]);
+ TRACE_VECTOR(vertex_shader->data->C[2]);
+ TRACE_VECTOR(vertex_shader->data->C[3]);
+ TRACE_VECTOR(vertex_shader->data->C[4]);
+ TRACE_VECTOR(vertex_shader->data->C[5]);
+ TRACE_VECTOR(vertex_shader->data->C[6]);
+ TRACE_VECTOR(vertex_shader->data->C[7]);
+ */
+
+ /* Extract out the output */
+ /*FIXME: Fog coords? */
+ x = vertex_shader->output.oPos.x;
+ y = vertex_shader->output.oPos.y;
+ z = vertex_shader->output.oPos.z;
+ rhw = vertex_shader->output.oPos.w;
+ ptSize = vertex_shader->output.oPts.x; /* Fixme - Is this right? */
+
+ /** Update textures coords using vertex_shader->output.oT[0->7] */
+ memset(texcoords, 0x00, sizeof(texcoords));
+ memset(numcoords, 0x00, sizeof(numcoords));
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+ if (This->StateBlock->textures[textureNo] != NULL) {
+ texcoords[textureNo].x = vertex_shader->output.oT[textureNo].x;
+ texcoords[textureNo].y = vertex_shader->output.oT[textureNo].y;
+ texcoords[textureNo].z = vertex_shader->output.oT[textureNo].z;
+ texcoords[textureNo].w = vertex_shader->output.oT[textureNo].w;
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
+ numcoords[textureNo] = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
+ } else {
+ switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
+ case D3DRTYPE_TEXTURE: numcoords[textureNo] = 2; break;
+ case D3DRTYPE_VOLUMETEXTURE: numcoords[textureNo] = 3; break;
+ default: numcoords[textureNo] = 4;
+ }
+ }
+ } else {
+ numcoords[textureNo] = 0;
+ }
+ }
+
+ /* Draw using this information */
+ draw_vertex(iface,
+ TRUE, x, y, z, rhw,
+ FALSE, 0.0f, 0.0f, 0.0f,
+ TRUE, (float*) &vertex_shader->output.oD[0],
+ TRUE, (float*) &vertex_shader->output.oD[1],
+ FALSE, ptSize, /* FIXME: Change back when supported */
+ texcoords, numcoords);
+
+ /* For non indexed mode, step onto next parts */
+ if (idxData == NULL) {
+ SkipnStrides += 1;
+ }
+
+ } /* for each vertex */
+
+ glEnd();
+ checkGLcall("glEnd and previous calls");
+}
+
+/* Routine common to the draw primitive and draw indexed primitive routines */
+void drawPrimitive(LPDIRECT3DDEVICE8 iface,
+ int PrimitiveType, long NumPrimitives,
+
+ /* for Indexed: */
+ long StartVertexIndex,
+ long StartIdx,
+ short idxSize,
+ const void *idxData,
+ int minIndex) {
+
+ BOOL rc = FALSE;
+ DWORD fvf = 0;
+ IDirect3DVertexShaderImpl *vertex_shader = NULL;
+ BOOL useVertexShaderFunction = FALSE;
+ BOOL isLightingOn = FALSE;
+ Direct3DVertexStridedData dataLocations;
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+
+ /* Work out what the FVF should look like */
+ rc = initializeFVF(iface, &fvf, &useVertexShaderFunction);
+ if (rc) return;
+
+ /* If we will be using a vertex shader, do some initialization for it */
+ if (useVertexShaderFunction == TRUE) {
+ vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader);
+ memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8));
+
+ /** init Constants */
+ if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) {
+ TRACE_(d3d_shader)("vertex shader init Constant\n");
+ IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96);
+ }
+ }
+
+ /* Ok, we will be updating the screen from here onwards so grab the lock */
+ ENTER_GL();
+
+ /* Setup transform matrices and sort out */
+ isLightingOn = primitiveInitState(iface,
+ fvf & D3DFVF_XYZRHW,
+ !(fvf & D3DFVF_NORMAL));
+
+ /* Initialize all values to null */
+ if (useVertexShaderFunction == FALSE) {
+ memset(&dataLocations, 0x00, sizeof(dataLocations));
+
+ /* Convert to strided data */
+ primitiveConvertToStridedData(iface, &dataLocations, StartVertexIndex);
+
+ /* Dump out what parts we have supplied */
+ TRACE("Strided Data (from FVF/VS): %lx\n", fvf);
+ TRACE_STRIDED((&dataLocations), position);
+ TRACE_STRIDED((&dataLocations), blendWeights);
+ TRACE_STRIDED((&dataLocations), blendMatrixIndices);
+ TRACE_STRIDED((&dataLocations), normal);
+ TRACE_STRIDED((&dataLocations), pSize);
+ TRACE_STRIDED((&dataLocations), diffuse);
+ TRACE_STRIDED((&dataLocations), specular);
+ TRACE_STRIDED((&dataLocations), texCoords[0]);
+ TRACE_STRIDED((&dataLocations), texCoords[1]);
+ TRACE_STRIDED((&dataLocations), texCoords[2]);
+ TRACE_STRIDED((&dataLocations), texCoords[3]);
+ TRACE_STRIDED((&dataLocations), texCoords[4]);
+ TRACE_STRIDED((&dataLocations), texCoords[5]);
+ TRACE_STRIDED((&dataLocations), texCoords[6]);
+ TRACE_STRIDED((&dataLocations), texCoords[7]);
+ }
+
+ /* Now draw the graphics to the screen */
+ if (useVertexShaderFunction == TRUE) {
+
+ /* Ideally, we should have software FV and hardware VS, possibly
+ depending on the device type? */
+
+ /* We will have to use the very, very slow emulation layer */
+ drawStridedSoftwareVS(iface, &dataLocations, PrimitiveType, NumPrimitives,
+ idxData, idxSize, minIndex, StartIdx);
+
+ } else if ((dataLocations.u.s.pSize.lpData != NULL) ||
+ (dataLocations.u.s.diffuse.lpData != NULL) ||
+ (dataLocations.u.s.blendWeights.lpData != NULL)) {
+
+ /* Fixme, Ideally, only use the per-vertex code for software HAL
+ but until opengl supports all the functions returned to setup
+ vertex arrays, we need to drop down to the slow mechanism for
+ certain functions */
+
+ /* We will have to use the slow version of GL per vertex setup */
+ drawStridedSlow(iface, &dataLocations, PrimitiveType, NumPrimitives,
+ idxData, idxSize, minIndex, StartIdx);
+
+ } else {
+
+ /* We can use the fast version of GL pointers */
+ drawStridedFast(iface, &dataLocations, PrimitiveType, NumPrimitives,
+ idxData, idxSize, minIndex, StartIdx);
+ }
+
+ /* If no normals, restore previous lighting state */
+ if (!(fvf & D3DFVF_NORMAL)) {
+ if (isLightingOn) glEnable(GL_LIGHTING);
+ else glDisable(GL_LIGHTING);
+ TRACE("Restored lighting to original state\n");
+ }
+
+ /* Finshed updating the screen, restore lock */
+ LEAVE_GL();
+ TRACE("Done all gl drawing\n");
+
+ /* Diagnostics */
+#if defined(SHOW_FRAME_MAKEUP)
+ {
+ if (isDumpingFrames == TRUE) {
+ D3DLOCKED_RECT r;
+ char buffer[80];
+ IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) This->backBuffer, &r, NULL, D3DLOCK_READONLY);
+ sprintf(buffer, "/tmp/backbuffer_%ld.ppm", primCounter++);
+ TRACE("Saving screenshot %s\n", buffer);
+ IDirect3DSurface8Impl_SaveSnapshot((LPDIRECT3DSURFACE8) This->backBuffer, buffer);
+ IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) This->backBuffer);
+ }
+ }
+#endif
+}