Commit c064dcf5 authored by Lionel Ulmer's avatar Lionel Ulmer Committed by Alexandre Julliard

- hack for one case of the ProcessVertices case

- some changes in the execute buffer to reuse the new Matrix code - always reinitialize the enumeration structures in case some games modify them - added support for the (unused) Reserved1 field in the FVF formats - fix 32 bit texturing and added more checks - remove some useless and annoying fixme
parent 0114945b
......@@ -226,6 +226,8 @@ struct IDirect3DVertexBufferImpl
D3DVERTEXBUFFERDESC desc;
LPVOID *vertices;
DWORD vertex_buffer_size;
BOOLEAN processed;
};
/* Various dump and helper functions */
......@@ -237,6 +239,11 @@ extern void dump_DPFLAGS(DWORD dwFlags);
extern void dump_D3DMATRIX(D3DMATRIX *mat);
extern void dump_D3DVECTOR(D3DVECTOR *lpVec);
extern void dump_flexible_vertex(DWORD d3dvtVertexType);
extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements);
extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
extern void convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided);
extern void dump_D3DVOP(DWORD dwVertexOp);
extern void dump_D3DPV(DWORD dwFlags);
extern const float id_mat[16];
#endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */
......@@ -230,23 +230,20 @@ dump_D3DMATRIX(D3DMATRIX *mat)
}
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType)
{
DWORD size = 0;
DWORD elts = 0;
if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE);
if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD);
if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD);
if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD);
switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
default: TRACE(" matrix weighting not handled yet...\n");
}
size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
if (elements) *elements = elts;
return size;
}
......@@ -290,3 +287,64 @@ void dump_flexible_vertex(DWORD d3dvtVertexType)
}
DPRINTF("\n");
}
void
convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided)
{
int current_offset = 0;
int tex_index;
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
strided->position.lpvData = lpvVertices;
current_offset += 3 * sizeof(D3DVALUE);
} else {
strided->position.lpvData = lpvVertices;
current_offset += 4 * sizeof(D3DVALUE);
}
if (d3dvtVertexType & D3DFVF_RESERVED1) {
current_offset += sizeof(DWORD);
}
if (d3dvtVertexType & D3DFVF_NORMAL) {
strided->normal.lpvData = ((char *) lpvVertices) + current_offset;
current_offset += 3 * sizeof(D3DVALUE);
}
if (d3dvtVertexType & D3DFVF_DIFFUSE) {
strided->diffuse.lpvData = ((char *) lpvVertices) + current_offset;
current_offset += sizeof(DWORD);
}
if (d3dvtVertexType & D3DFVF_SPECULAR) {
strided->specular.lpvData = ((char *) lpvVertices) + current_offset;
current_offset += sizeof(DWORD);
}
for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
strided->textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
current_offset += 2 * sizeof(D3DVALUE);
}
strided->position.dwStride = current_offset;
strided->normal.dwStride = current_offset;
strided->diffuse.dwStride = current_offset;
strided->specular.dwStride = current_offset;
for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
strided->textureCoords[tex_index].dwStride = current_offset;
}
void
dump_D3DVOP(DWORD dwVertexOp)
{
static const flag_info flags[] =
{
FE(D3DVOP_LIGHT),
FE(D3DVOP_CLIP),
FE(D3DVOP_EXTENTS),
FE(D3DVOP_TRANSFORM)
};
DDRAW_dump_flags(dwVertexOp, flags, sizeof(flags)/sizeof(flags[0]));
}
void
dump_D3DPV(DWORD dwFlags)
{
if (dwFlags == D3DPV_DONOTCOPYDATA) DPRINTF("D3DPV_DONOTCOPYDATA\n");
else if (dwFlags != 0) DPRINTF("Unknown !!!\n");
else DPRINTF("\n");
}
......@@ -724,7 +724,7 @@ Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface,
DWORD dwSize)
{
ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize);
TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize);
if (TRACE_ON(ddraw)) {
TRACE(" info requested : ");
......
......@@ -238,43 +238,34 @@ static void execute(IDirect3DExecuteBufferImpl *This,
/* This time, there is lighting */
glEnable(GL_LIGHTING);
/* Use given matrixes */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); /* The model transformation was done during the
transformation phase */
glMatrixMode(GL_PROJECTION);
TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat);
dump_D3DMATRIX(lpDevice->proj_mat);
TRACE(" View Matrix : (%p)\n", lpDevice->view_mat);
dump_D3DMATRIX(lpDevice->view_mat);
/* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates
are always 0.0 at the front viewing volume and 1.0 at the back with Direct 3D and with
the default behaviour of OpenGL. So, no additional transformation is required. */
glLoadMatrixf((float *) lpDevice->proj_mat);
glMultMatrixf((float *) lpDevice->view_mat);
if (TRACE_ON(ddraw)) {
TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat);
dump_D3DMATRIX(lpDevice->proj_mat);
TRACE(" View Matrix : (%p)\n", lpDevice->view_mat);
dump_D3DMATRIX(lpDevice->view_mat);
}
/* Using the identity matrix as the world matrix as the world transformation was
already done. */
lpDevice->set_matrices(lpDevice, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
(D3DMATRIX *) id_mat, lpDevice->view_mat, lpDevice->proj_mat);
break;
case D3DVT_LVERTEX:
/* No lighting */
glDisable(GL_LIGHTING);
/* Use given matrixes */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); /* The model transformation was done during the
transformation phase */
glMatrixMode(GL_PROJECTION);
TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat);
dump_D3DMATRIX(lpDevice->proj_mat);
TRACE(" View Matrix : (%p)\n", lpDevice->view_mat);
dump_D3DMATRIX(lpDevice->view_mat);
/* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates
are always 0 at the front viewing volume and 1 at the back with Direct 3D and with
the default behaviour of OpenGL. So, no additional transformation is required. */
glLoadMatrixf((float *) lpDevice->proj_mat);
glMultMatrixf((float *) lpDevice->view_mat);
if (TRACE_ON(ddraw)) {
TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat);
dump_D3DMATRIX(lpDevice->proj_mat);
TRACE(" View Matrix : (%p)\n", lpDevice->view_mat);
dump_D3DMATRIX(lpDevice->view_mat);
}
/* Using the identity matrix as the world matrix as the world transformation was
already done. */
lpDevice->set_matrices(lpDevice, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
(D3DMATRIX *) id_mat, lpDevice->view_mat, lpDevice->proj_mat);
break;
case D3DVT_TLVERTEX: {
......
......@@ -237,22 +237,40 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
RGB Textures
************ */
if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) {
/* **********************
GL_UNSIGNED_BYTE_3_3_2
********************** */
format = GL_RGB;
pixel_format = GL_UNSIGNED_BYTE_3_3_2;
format = GL_RGB;
pixel_format = GL_UNSIGNED_BYTE_3_3_2;
} else {
error = TRUE;
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
format = GL_RGB;
pixel_format = GL_UNSIGNED_SHORT_5_6_5;
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07C0) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x003E) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) {
format = GL_RGBA;
pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF000) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0F00) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x00F0) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) {
format = GL_RGBA;
pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000F000) {
} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x0F00) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00F0) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000F) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) {
/* Move the four Alpha bits... */
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
......@@ -268,7 +286,10 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
format = GL_RGBA;
pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) {
/* Converting the 1555 format in 5551 packed */
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst;
......@@ -284,21 +305,47 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
format = GL_RGBA;
pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
} else {
ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
error = TRUE;
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
format = GL_RGB;
pixel_format = GL_UNSIGNED_BYTE;
if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
format = GL_BGR;
pixel_format = GL_UNSIGNED_BYTE;
} else {
error = TRUE;
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
format = GL_RGBA;
pixel_format = GL_UNSIGNED_BYTE;
if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xFF000000) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00FF0000) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x0000FF00) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) {
format = GL_RGBA;
pixel_format = GL_UNSIGNED_INT_8_8_8_8;
} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
(src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
(src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
(src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
/* Just add an alpha component... */
DWORD i;
DWORD *src = (DWORD *) src_d->lpSurface, *dst;
surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
dst = (DWORD *) surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
*dst++ = (*src++ << 8) | 0xFF;
}
format = GL_RGBA;
pixel_format = GL_UNSIGNED_INT_8_8_8_8;
} else {
error = TRUE;
}
} else {
ERR("Unhandled texture format (bad RGB count)\n");
error = TRUE;
}
} else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n");
error = TRUE;
}
......@@ -321,6 +368,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
pixel_format,
surface == NULL ? src_d->lpSurface : surface);
if (surface) HeapFree(GetProcessHeap(), 0, surface);
} else if (error == TRUE) {
if (ERR_ON(ddraw)) {
ERR("Unsupported pixel format for textures : \n");
DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat);
}
}
glBindTexture(GL_TEXTURE_2D, current_texture);
......
......@@ -137,6 +137,15 @@ typedef struct IDirect3DDeviceGLImpl
Drawable drawable;
} IDirect3DDeviceGLImpl;
/* This is for the OpenGL additions... */
typedef struct {
struct IDirect3DVertexBufferImpl parent;
DWORD dwVertexTypeDesc;
D3DMATRIX world_mat, view_mat, proj_mat;
LPVOID vertices;
} IDirect3DVertexBufferGLImpl;
/* All non-static functions 'exported' by various sub-objects */
extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw);
extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment