- rework how texturing is done in the D3D driver

- added the generic path for DrawPrimitive API in D3D 3 / 7
This commit is contained in:
Lionel Ulmer 2002-12-15 01:17:59 +00:00 committed by Alexandre Julliard
parent cc1577cddc
commit 91c6f817b9
10 changed files with 650 additions and 457 deletions

View File

@ -32,7 +32,6 @@
typedef struct IDirect3DImpl IDirect3DImpl;
typedef struct IDirect3DLightImpl IDirect3DLightImpl;
typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl;
typedef struct IDirect3DTextureImpl IDirect3DTextureImpl;
typedef struct IDirect3DViewportImpl IDirect3DViewportImpl;
typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl;
typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;
@ -53,6 +52,9 @@ struct IDirect3DImpl
DWORD ref;
/* IDirect3D fields */
IDirectDrawImpl* ddraw;
/* Used as a callback function to create a texture */
HRESULT (*create_texture)(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main, DWORD mipmap_level);
};
/*****************************************************************************
@ -94,21 +96,6 @@ struct IDirect3DMaterialImpl
void (*activate)(IDirect3DMaterialImpl* this);
};
/*****************************************************************************
* IDirect3DTexture implementation structure
*/
struct IDirect3DTextureImpl
{
ICOM_VFIELD_MULTI(IDirect3DTexture2);
ICOM_VFIELD_MULTI(IDirect3DTexture);
DWORD ref;
/* IDirect3DTexture fields */
IDirect3DImpl *d3d;
IDirect3DDeviceImpl *d3ddevice;
IDirectDrawSurfaceImpl *surface;
BOOL loaded;
};
/*****************************************************************************
* IDirect3DViewport implementation structure
*/
@ -183,7 +170,7 @@ struct IDirect3DDeviceImpl
IDirect3DViewportImpl *viewport_list;
IDirect3DViewportImpl *current_viewport;
IDirect3DTextureImpl *current_texture[MAX_TEXTURES];
IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES];
void (*set_context)(IDirect3DDeviceImpl*);
};

View File

@ -160,7 +160,7 @@ static void fill_opengl_caps(D3DDEVICEDESC *d1)
fill_opengl_primcaps(&(d1->dpcLineCaps));
fill_opengl_primcaps(&(d1->dpcTriCaps));
d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
d1->dwDeviceZBufferBitDepth = DDBD_16;
d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
d1->dwMaxBufferSize = 0;
d1->dwMaxVertexCount = 65536;
d1->dwMinTextureWidth = 1;
@ -842,19 +842,23 @@ GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
return ret_value;
}
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType)
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
{
DWORD size = 0;
DWORD elts = 0;
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_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; }
switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; 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;
}
@ -908,6 +912,48 @@ typedef struct {
float tu1, tv1;
} D3DFVF_TLVERTEX_1;
typedef struct {
int offset;
int extra;
void (*handler)(char *vertex, int offset, int extra);
} D3DFVF_GENERIC;
/* These are the various handler used in the generic path */
static void handle_xyz(char *vertex, int offset, int extra) {
glVertex3fv((float *) (vertex + offset));
}
static void handle_xyzrhw(char *vertex, int offset, int extra) {
float *coords = (float *) (vertex + offset);
if (coords[3] < 0.00001)
glVertex3f(coords[0], coords[1], coords[2]);
else
glVertex4f(coords[0] / coords[3],
coords[1] / coords[3],
coords[2] / coords[3],
1.0 / coords[3]);
}
static void handle_normal(char *vertex, int offset, int extra) {
glNormal3fv((float *) (vertex + offset));
}
static void handle_specular(char *vertex, int offset, int extra) {
/* Specular not handled yet properly... */
}
static void handle_diffuse(char *vertex, int offset, int extra) {
DWORD color = *((DWORD *) (vertex + offset));
glColor4ub((color >> 24) & 0xFF,
(color >> 16) & 0xFF,
(color >> 8) & 0xFF,
(color >> 0) & 0xFF);
}
static void handle_texture(char *vertex, int offset, int extra) {
if (extra == 0xFF) {
/* Special case for single texture... */
glTexCoord2fv((float *) (vertex + offset));
} else {
/* Multitexturing not handled yet */
}
}
static void draw_primitive_7(IDirect3DDeviceImpl *This,
D3DPRIMITIVETYPE d3dptPrimitiveType,
DWORD d3dvtVertexType,
@ -936,9 +982,9 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index];
glNormal3f(vertices[i].nx, vertices[i].ny, vertices[i].nz);
glTexCoord2f(vertices[i].tu1, vertices[i].tv1);
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
glNormal3fv(&(vertices[i].nx));
glTexCoord2fv(&(vertices[i].tu1));
glVertex3fv(&(vertices[i].x));
TRACE(" %f %f %f / %f %f %f (%f %f)\n",
vertices[i].x, vertices[i].y, vertices[i].z,
vertices[i].nx, vertices[i].ny, vertices[i].nz,
@ -956,7 +1002,7 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
(vertices[i].diffuse >> 8) & 0xFF,
(vertices[i].diffuse >> 0) & 0xFF);
/* Todo : handle specular... */
glTexCoord2f(vertices[i].tu1, vertices[i].tv1);
glTexCoord2fv(&(vertices[i].tu1));
if (vertices[i].rhw < 0.00001)
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
else
@ -976,6 +1022,76 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
(vertices[i].specular >> 0) & 0xFF,
vertices[i].tu1, vertices[i].tv1);
}
} else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
/* This is the 'slow path' but that should support all possible vertex formats out there...
Note that people should write a fast path for all vertex formats out there...
*/
DWORD elements;
DWORD size = get_flexible_vertex_size(d3dvtVertexType, &elements);
char *vertices = (char *) lpvVertices;
int index;
int current_offset = 0;
int current_position = 0;
D3DFVF_GENERIC *handler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, elements * sizeof(D3DFVF_GENERIC));
WARN(" using draw_primitive generic path - for better performance, add a fast path for your vertex case !\n");
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
handler[elements - 1].handler = handle_xyz;
handler[elements - 1].offset = current_offset;
current_offset += 3 * sizeof(D3DVALUE);
} else {
handler[elements - 1].handler = handle_xyzrhw;
handler[elements - 1].offset = current_offset;
current_offset += 4 * sizeof(D3DVALUE);
}
if (d3dvtVertexType & D3DFVF_NORMAL) {
handler[current_position].handler = handle_normal;
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += 3 * sizeof(D3DVALUE);
}
if (d3dvtVertexType & D3DFVF_DIFFUSE) {
handler[current_position].handler = handle_diffuse;
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += sizeof(DWORD);
}
if (d3dvtVertexType & D3DFVF_SPECULAR) {
handler[current_position].handler = handle_specular;
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += sizeof(DWORD);
}
if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
handler[current_position].handler = handle_texture;
handler[current_position].offset = current_offset;
handler[current_position].extra = 0xFF;
current_position += 1;
current_offset += 2 * sizeof(D3DVALUE);
} else {
int tex_index;
for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
handler[current_position].handler = handle_texture;
handler[current_position].offset = current_offset;
handler[current_position].extra = tex_index;
current_position += 1;
current_offset += 2 * sizeof(D3DVALUE);
}
}
for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index];
int elt;
char *vertex = vertices + (i * size);
for (elt = 0; elt < elements; elt++) {
handler[elt].handler(vertex, handler[elt].offset, handler[elt].extra);
}
}
} else {
ERR(" matrix weighting not handled yet....\n");
}
glEnd();
@ -1130,11 +1246,11 @@ GL_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
} else {
IDirect3DTextureImpl *tex_impl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpTexture2);
IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl;
IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpTexture2);
IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
This->current_texture[dwStage] = tex_impl;
IDirect3DTexture2_AddRef(lpTexture2);
IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7));
TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
@ -1453,7 +1569,6 @@ static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
LEAVE_GL();
return;
}
glRasterPos2f(0.0, 0.0);
glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
GL_RGB, buffer_type, This->surface_desc.lpSurface);

View File

@ -130,27 +130,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
/*******************************************************************************
* IDirectSurface callback methods
*/
HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
HRESULT WINAPI gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
{
DDSURFACEDESC *tex_d;
GLuint current_texture;
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture;
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture->tex_private;
TRACE("(%p) : colorkey callback\n", texture);
/* Get the texture description */
tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc);
tex_d = (DDSURFACEDESC *)&(texture->surface_desc);
/* Now, save the current texture */
ENTER_GL();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
/* If the GetHandle was not done yet, it's an error */
if (glThis->tex_name == 0) {
ERR("Unloaded texture !\n");
LEAVE_GL();
return DD_OK;
}
if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
@ -180,14 +174,13 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDD
}
}
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
tex_d->dwWidth, tex_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
dest);
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
tex_d->dwWidth, tex_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
dest);
/* Frees the temporary surface */
HeapFree(GetProcessHeap(),0,dest);
@ -208,66 +201,280 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDD
} else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n");
}
glBindTexture(GL_TEXTURE_2D, current_texture);
LEAVE_GL();
return DD_OK;
}
HRESULT WINAPI
Main_IDirect3DTextureImpl_2_1T_QueryInterface(LPDIRECT3DTEXTURE2 iface,
REFIID riid,
LPVOID* obp)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
TRACE("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp);
static void
gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
GLuint current_texture;
#if 0
static BOOL color_table_queried = FALSE;
#endif
void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
*obp = NULL;
DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(This->surface_desc);
if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
*obp = iface;
TRACE(" Creating IUnknown interface at %p.\n", *obp);
return S_OK;
}
if ( IsEqualGUID( &IID_IDirect3DTexture, riid ) ) {
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
*obp = ICOM_INTERFACE(This, IDirect3DTexture);
TRACE(" Creating IDirect3DTexture interface %p\n", *obp);
return S_OK;
}
if ( IsEqualGUID( &IID_IDirect3DTexture2, riid ) ) {
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
*obp = ICOM_INTERFACE(This, IDirect3DTexture2);
TRACE(" Creating IDirect3DTexture2 interface %p\n", *obp);
return S_OK;
}
FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
return OLE_E_ENUM_NOMORE;
}
TRACE(" uploading texture to GL id %d (initial = %d).\n", glThis->tex_name, init_upload);
ULONG WINAPI
Main_IDirect3DTextureImpl_2_1T_AddRef(LPDIRECT3DTEXTURE2 iface)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
return ++(This->ref);
}
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
ULONG WINAPI
Main_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
if (!--(This->ref)) {
/* Release surface */
IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
/* ****************
Paletted Texture
**************** */
IDirectDrawPaletteImpl* pal = This->palette;
BYTE table[256][4];
int i;
HeapFree(GetProcessHeap(),0,This);
return 0;
}
#if 0
if (color_table_queried == FALSE) {
ptr_ColorTableEXT =
((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
}
#endif
if (pal == NULL) {
ERR("Palettized texture Loading with a NULL palette !\n");
LEAVE_GL();
return;
}
/* Get the surface's palette */
for (i = 0; i < 256; i++) {
table[i][0] = pal->palents[i].peRed;
table[i][1] = pal->palents[i].peGreen;
table[i][2] = pal->palents[i].peBlue;
if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
table[i][3] = 0x00;
else
table[i][3] = 0xFF;
}
return This->ref;
/* Texture snooping */
SNOOP_PALETTED();
if (ptr_ColorTableEXT != NULL) {
/* use Paletted Texture Extension */
ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
GL_RGBA, /* internal format */
256, /* table size */
GL_RGBA, /* table format */
GL_UNSIGNED_BYTE, /* table type */
table); /* the color table */
glTexImage2D(GL_TEXTURE_2D, /* target */
glThis->mipmap_level, /* level */
GL_COLOR_INDEX8_EXT, /* internal format */
src_d->dwWidth, src_d->dwHeight, /* width, height */
0, /* border */
GL_COLOR_INDEX, /* texture format */
GL_UNSIGNED_BYTE, /* texture type */
src_d->lpSurface); /* the texture */
} else {
DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
DWORD i;
BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
BYTE color = *src++;
*dst++ = table[color][0];
*dst++ = table[color][1];
*dst++ = table[color][2];
*dst++ = table[color][3];
}
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
surface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_BYTE,
surface);
HeapFree(GetProcessHeap(), 0, surface);
}
} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
/* ************
RGB Textures
************ */
if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
/* **********************
GL_UNSIGNED_BYTE_3_3_2
********************** */
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE_3_3_2,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGB,
GL_UNSIGNED_BYTE_3_3_2,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
/* Texture snooping */
SNOOP_5650();
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
/* Texture snooping */
SNOOP_5551();
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
/* Converting the 1555 format in 5551 packed */
WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
*dst++ = (((*src & 0x8000) >> 15) |
((*src & 0x7FFF) << 1));
src++;
}
SNOOP_1555();
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
surface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
surface);
HeapFree(GetProcessHeap(), 0, surface);
} else {
ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGB,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else {
ERR("Unhandled texture format (bad RGB count)\n");
}
} else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n");
}
glBindTexture(GL_TEXTURE_2D, current_texture);
}
HRESULT WINAPI
@ -275,7 +482,7 @@ Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface,
LPDIRECT3DDEVICE lpDirect3DDevice,
LPDIRECTDRAWSURFACE lpDDSurface)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface);
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
return DD_OK;
}
@ -285,7 +492,7 @@ Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
DWORD dwStart,
DWORD dwCount)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
return DD_OK;
}
@ -293,7 +500,7 @@ Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
HRESULT WINAPI
Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface);
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
FIXME("(%p/%p)->(): stub!\n", This, iface);
return DD_OK;
}
@ -303,7 +510,7 @@ Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DDEVICE2 lpDirect3DDevice2,
LPD3DTEXTUREHANDLE lpHandle)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpDirect3DDevice2, lpHandle);
return DD_OK;
}
@ -312,45 +519,60 @@ HRESULT WINAPI
Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DTEXTURE2 lpD3DTexture2)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
return DD_OK;
}
ULONG WINAPI
GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
static void
gltex_final_release(IDirectDrawSurfaceImpl *This)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
if (!--(This->ref)) {
DWORD mem_used;
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
DWORD mem_used;
TRACE(" deleting texture with GL id %d.\n", glThis->tex_name);
/* Release surface */
IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
/* And delete texture handle */
ENTER_GL();
if (glThis->tex_name != 0)
glDeleteTextures(1, &(glThis->tex_name));
LEAVE_GL();
/* And delete texture handle */
ENTER_GL();
glDeleteTextures(1, &(glThis->tex_name));
LEAVE_GL();
/* And if this texture was the current one, remove it at the device level */
if (This->d3ddevice != NULL)
if (This->d3ddevice->current_texture[0] == This)
This->d3ddevice->current_texture[0] = NULL;
/* And if this texture was the current one, remove it at the device level */
if (This->d3ddevice != NULL)
if (This->d3ddevice->current_texture[0] == This)
This->d3ddevice->current_texture[0] = NULL;
if (This->loaded) {
mem_used = This->surface->surface_desc.dwHeight *
This->surface->surface_desc.dwHeight *
This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
This->surface->ddraw_owner->free_memory(This->surface->ddraw_owner, mem_used);
}
HeapFree(GetProcessHeap(),0,This);
return 0;
/* All this should be part of main surface management not just a hack for texture.. */
if (glThis->loaded) {
mem_used = This->surface_desc.dwHeight *
This->surface_desc.dwHeight *
This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
This->ddraw_owner->free_memory(This->ddraw_owner, mem_used);
}
return This->ref;
glThis->final_release(This);
}
static void
gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
{
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
glThis->lock_update(This, pRect, dwFlags);
}
static void
gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
{
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
ENTER_GL();
gltex_upload_texture(This, glThis->first_unlock);
LEAVE_GL();
glThis->first_unlock = FALSE;
glThis->unlock_update(This, pRect);
}
HRESULT WINAPI
@ -358,8 +580,8 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DDEVICE2 lpDirect3DDevice2,
LPD3DTEXTUREHANDLE lpHandle)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
@ -371,16 +593,12 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
/* Now, bind a new texture */
This->d3ddevice = lpDeviceImpl;
ENTER_GL();
if (glThis->tex_name == 0)
glGenTextures(1, &(glThis->tex_name));
LEAVE_GL();
/* Associate the texture with the device and perform the appropriate AddRef/Release */
/* FIXME: Is there only one or several textures associated with the device ? */
if (lpDeviceImpl->current_texture[0] != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirect3DTexture2));
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
IDirectDrawSurface7_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirectDrawSurface7));
IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7));
lpDeviceImpl->current_texture[0] = This;
TRACE("OpenGL texture handle is : %d\n", glThis->tex_name);
@ -394,49 +612,43 @@ HRESULT WINAPI
GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DTEXTURE2 lpD3DTexture2)
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
IDirect3DTextureImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpD3DTexture2);
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
IDirectDrawSurfaceImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
DWORD mem_used;
DDSURFACEDESC *src_d, *dst_d;
static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
#if 0
static BOOL color_table_queried = FALSE;
#endif
DDSURFACEDESC *src_d, *dst_d;
TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
if (This->loaded == FALSE) {
if (glThis->loaded == FALSE) {
/* Only check memory for not already loaded texture... */
mem_used = This->surface->surface_desc.dwHeight *
This->surface->surface_desc.dwHeight *
This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
if (This->surface->ddraw_owner->allocate_memory(This->surface->ddraw_owner, mem_used) < 0) {
mem_used = This->surface_desc.dwHeight *
This->surface_desc.dwHeight *
This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
TRACE(" out of virtual memory... Warning application.\n");
return D3DERR_TEXTURE_LOAD_FAILED;
}
}
This->loaded = TRUE;
glThis->loaded = TRUE;
TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl->surface, This->surface);
TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl, This);
if ( This->surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
/* If the surface is not allocated and its location is not yet specified,
force it to video memory */
if ( !(This->surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
This->surface->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) {
This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
WARN("This case is not properly handled yet.. Expect errors !\n");
}
/* Suppress the ALLOCONLOAD flag */
This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
This->palette = lpD3DTextureImpl->palette;
/* Copy one surface on the other */
dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc);
src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface->surface_desc);
/* Install the callbacks to the destination surface */
This->surface->texture = This;
This->surface->SetColorKey_cb = SetColorKey_cb;
dst_d = (DDSURFACEDESC *)&(This->surface_desc);
src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface_desc);
if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
/* Should also check for same pixel format, u1.lPitch, ... */
@ -445,204 +657,27 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
} else {
/* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
/* I should put a macro for the calculus of bpp */
GLuint current_texture;
/* Copy also the ColorKeying stuff */
if (src_d->dwFlags & DDSD_CKSRCBLT) {
dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
}
/* Copy the main memry texture into the surface that corresponds to the OpenGL
texture object. */
memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
/* If the GetHandle was not done, it is an error... */
if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
ENTER_GL();
/* Now, load the texture */
/* d3dd->set_context(d3dd); We need to set the context somehow.... */
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
/* If the GetHandle was not done, get the texture name here */
if (glThis->tex_name == 0)
glGenTextures(1, &(glThis->tex_name));
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
/* ****************
Paletted Texture
**************** */
IDirectDrawPaletteImpl* pal = lpD3DTextureImpl->surface->palette;
BYTE table[256][4];
int i;
#if 0
if (color_table_queried == FALSE) {
ptr_ColorTableEXT =
((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
}
#endif
if (pal == NULL) {
ERR("Palettized texture Loading with a NULL palette !\n");
LEAVE_GL();
return D3DERR_TEXTURE_LOAD_FAILED;
}
/* Get the surface's palette */
for (i = 0; i < 256; i++) {
table[i][0] = pal->palents[i].peRed;
table[i][1] = pal->palents[i].peGreen;
table[i][2] = pal->palents[i].peBlue;
if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
(i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
(i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
table[i][3] = 0x00;
else
table[i][3] = 0xFF;
}
/* Texture snooping */
SNOOP_PALETTED();
if (ptr_ColorTableEXT != NULL) {
/* use Paletted Texture Extension */
ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
GL_RGBA, /* internal format */
256, /* table size */
GL_RGBA, /* table format */
GL_UNSIGNED_BYTE, /* table type */
table); /* the color table */
glTexImage2D(GL_TEXTURE_2D, /* target */
0, /* level */
GL_COLOR_INDEX8_EXT, /* internal format */
src_d->dwWidth, src_d->dwHeight, /* width, height */
0, /* border */
GL_COLOR_INDEX, /* texture format */
GL_UNSIGNED_BYTE, /* texture type */
src_d->lpSurface); /* the texture */
} else {
DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
DWORD i;
BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
BYTE color = *src++;
*dst++ = table[color][0];
*dst++ = table[color][1];
*dst++ = table[color][2];
*dst++ = table[color][3];
}
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
surface);
HeapFree(GetProcessHeap(), 0, surface);
}
} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
/* ************
RGB Textures
************ */
if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
/* **********************
GL_UNSIGNED_BYTE_3_3_2
********************** */
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE_3_3_2,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
/* Texture snooping */
SNOOP_5650();
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
/* Texture snooping */
SNOOP_5551();
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
/* Converting the 1555 format in 5551 packed */
WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
*dst++ = (((*src & 0x8000) >> 15) |
((*src & 0x7FFF) << 1));
src++;
}
SNOOP_1555();
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
surface);
HeapFree(GetProcessHeap(), 0, surface);
} else {
ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else {
ERR("Unhandled texture format (bad RGB count)\n");
}
} else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n");
}
glBindTexture(GL_TEXTURE_2D, current_texture);
gltex_upload_texture(This, glThis->first_unlock);
glThis->first_unlock = FALSE;
LEAVE_GL();
}
@ -650,29 +685,54 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
return D3D_OK;
}
HRESULT WINAPI
Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface,
REFIID riid,
LPVOID* obp)
{
TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface),
riid,
obp);
}
ULONG WINAPI
Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface)
{
TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
}
ULONG WINAPI
Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface)
{
TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
}
HRESULT WINAPI
Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
REFIID riid,
LPVOID* obp)
{
TRACE("(%p)->(%s,%p) thunking to IDirect3DTexture2 interface.\n", iface, debugstr_guid(riid), obp);
return IDirect3DTexture2_QueryInterface(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
riid,
obp);
TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface),
riid,
obp);
}
ULONG WINAPI
Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
{
TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface);
return IDirect3DTexture2_AddRef(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface));
TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
}
ULONG WINAPI
Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
{
TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface);
return IDirect3DTexture2_Release(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface));
TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
}
HRESULT WINAPI
@ -681,7 +741,7 @@ Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface,
DWORD dwCount)
{
TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
dwStart,
dwCount);
}
@ -692,7 +752,7 @@ Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface,
LPD3DTEXTUREHANDLE lpHandle)
{
TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
lpHandle);
}
@ -702,8 +762,8 @@ Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
LPDIRECT3DTEXTURE lpD3DTexture)
{
TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
}
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
@ -715,9 +775,9 @@ Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
XCAST(QueryInterface) Main_IDirect3DTextureImpl_2_1T_QueryInterface,
XCAST(AddRef) Main_IDirect3DTextureImpl_2_1T_AddRef,
XCAST(Release) GL_IDirect3DTextureImpl_2_1T_Release,
XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
XCAST(GetHandle) GL_IDirect3DTextureImpl_2_1T_GetHandle,
XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
@ -751,26 +811,50 @@ ICOM_VTABLE(IDirect3DTexture) VTABLE_IDirect3DTexture =
#undef XCAST
#endif
HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf)
HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation,
IDirectDrawSurfaceImpl *main, DWORD mipmap_level)
{
IDirect3DTextureImpl *object;
IDirect3DTextureGLImpl *private;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
if (object == NULL) return DDERR_OUTOFMEMORY;
private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
if (private == NULL) return DDERR_OUTOFMEMORY;
object->ref = 1;
object->d3d = d3d;
object->surface = surf;
private->final_release = surf->final_release;
private->lock_update = surf->lock_update;
private->unlock_update = surf->unlock_update;
private->mipmap_level = mipmap_level;
ICOM_INIT_INTERFACE(object, IDirect3DTexture, VTABLE_IDirect3DTexture);
ICOM_INIT_INTERFACE(object, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
*obj = object;
TRACE(" creating implementation at %p.\n", *obj);
/* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
Otherwise, it will be uploaded here (and may be invalid). */
if (at_creation == TRUE)
private->first_unlock = TRUE;
else
private->first_unlock = FALSE;
surf->final_release = gltex_final_release;
surf->lock_update = gltex_lock_update;
surf->unlock_update = gltex_unlock_update;
surf->tex_private = private;
surf->SetColorKey_cb = gltex_setcolorkey_cb;
ICOM_INIT_INTERFACE(surf, IDirect3DTexture, VTABLE_IDirect3DTexture);
ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
if (mipmap_level == 0) {
ENTER_GL();
glGenTextures(1, &(private->tex_name));
if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
TRACE(" GL texture created (private data at %p and GL id %d).\n", private, private->tex_name);
} else {
private->tex_name = ((IDirect3DTextureGLImpl *) main->tex_private)->tex_name;
TRACE(" GL texture created (private data at %p and GL id reusing id %d).\n", private, private->tex_name);
}
if ((at_creation == FALSE) &&
((surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) == 0))
{
gltex_upload_texture(surf, TRUE);
}
LEAVE_GL();
return D3D_OK;
}

View File

@ -303,7 +303,7 @@ HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d
object->ref = 1;
object->d3d = d3d;
object->desc = *lpD3DVertBufDesc;
object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF, NULL) * lpD3DVertBufDesc->dwNumVertices;
object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);

View File

@ -177,7 +177,10 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface(
*obj = ICOM_INTERFACE(This, IDirectDraw4);
}
#ifdef HAVE_OPENGL
else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
IsEqualGUID( &IID_IDirect3D7 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
@ -185,48 +188,22 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface(
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D);
if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D);
TRACE(" returning Direct3D interface at %p.\n", *obj);
} else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
TRACE(" returning Direct3D2 interface at %p.\n", *obj);
} else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
TRACE(" returning Direct3D3 interface at %p.\n", *obj);
} else {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
TRACE(" returning Direct3D7 interface at %p.\n", *obj);
}
/* And store the D3D object */
This->d3d = d3d_impl;
TRACE(" returning Direct3D interface at %p.\n", *obj);
}
else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
TRACE(" returning Direct3D2 interface at %p.\n", *obj);
}
else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
TRACE(" returning Direct3D3 interface at %p.\n", *obj);
}
else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
TRACE(" returning Direct3D7 interface at %p.\n", *obj);
}
#endif
else
@ -375,6 +352,9 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);
if (FAILED(hr)) return hr;
if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE,
ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level);
/* Create attached mipmaps if required. */
if (more_mipmaps(&ddsd))
{
@ -411,6 +391,8 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
IDirectDrawSurface7_Release(*ppSurf);
return hr;
}
if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE,
ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level);
IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
IDirectDrawSurface7_Release(prev_mipmap);
@ -1131,6 +1113,11 @@ Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
ICOM_THIS(IDirectDrawImpl,iface);
TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
if (TRACE_ON(ddraw)) {
TRACE(" Asking for memory of type : \n");
DDRAW_dump_DDSCAPS2(ddscaps);
}
/* We have 16 MB videomemory */
if (total) *total= This->total_vidmem;
if (free) *free = This->available_vidmem;

View File

@ -26,6 +26,7 @@
#include "wingdi.h"
#include "winuser.h"
#include "ddraw.h"
#include "d3d.h"
#include "ddcomimpl.h"
#include "ddrawi.h"
@ -220,6 +221,8 @@ struct IDirectDrawSurfaceImpl
ICOM_VFIELD_MULTI(IDirectDrawSurface7);
ICOM_VFIELD_MULTI(IDirectDrawSurface3);
ICOM_VFIELD_MULTI(IDirectDrawGammaControl);
ICOM_VFIELD_MULTI(IDirect3DTexture2);
ICOM_VFIELD_MULTI(IDirect3DTexture);
DWORD ref;
struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */
@ -289,10 +292,10 @@ struct IDirectDrawSurfaceImpl
void (*aux_release)(LPVOID ctx, LPVOID data);
BOOL (*aux_flip)(LPVOID ctx, LPVOID data);
void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect);
struct IDirect3DTextureImpl *texture;
HRESULT (WINAPI *SetColorKey_cb)(struct IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
HRESULT (WINAPI *SetColorKey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
/* This is to get the D3DDevice object associated to this surface */
struct IDirect3DDeviceImpl *d3ddevice;
LPVOID tex_private;
};
/*****************************************************************************

View File

@ -387,6 +387,7 @@ HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw)
object->ref = 1;
object->ddraw = ddraw;
object->create_texture = d3dtexture_create;
ICOM_INIT_INTERFACE(object, IDirect3D, VTABLE_IDirect3D);
ICOM_INIT_INTERFACE(object, IDirect3D2, VTABLE_IDirect3D2);

View File

@ -81,7 +81,7 @@ Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
DDRAW_IDDS3_Thunk_VTable);
ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
DDRAW_IDDGC_VTable);
/* There is no generic implementation of IDDS7 */
/* There is no generic implementation of IDDS7 or texture */
Main_DirectDraw_AddSurface(pDD, This);
return DD_OK;
@ -101,6 +101,7 @@ static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
{
This->final_release(This);
if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private);
HeapFree(GetProcessHeap(), 0, This);
}
@ -146,6 +147,8 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
ICOM_THIS(IDirectDrawSurfaceImpl, iface);
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);
*ppObj = NULL;
if (IsEqualGUID(&IID_IUnknown, riid)
|| IsEqualGUID(&IID_IDirectDrawSurface7, riid)
|| IsEqualGUID(&IID_IDirectDrawSurface4, riid))
@ -184,32 +187,38 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
This->ref++; /* No idea if this is correct.. Need to check using real Windows */
return ret_value;
}
else if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
IsEqualGUID( &IID_IDirect3DTexture2, riid ))
{
IDirect3DTextureImpl *d3dteximpl;
HRESULT ret_value;
HRESULT ret_value = S_OK;
ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
if (FAILED(ret_value)) return ret_value;
/* In case the texture surface was created before the D3D creation */
if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) == 0) return E_NOINTERFACE;
/* Create a 'delayed' private field only if it is not an offscreen texture... */
if ((This->tex_private == NULL) &&
((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY)) == 0)) {
if (This->ddraw_owner->d3d == NULL) {
ERR("Texture created with no D3D object yet.. Not supported !\n");
return E_NOINTERFACE;
}
*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture);
TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
This->ref++; /* No idea if this is correct.. Need to check using real Windows */
return ret_value;
}
else if (IsEqualGUID( &IID_IDirect3DTexture2, riid ))
{
IDirect3DTextureImpl *d3dteximpl;
HRESULT ret_value;
if (((This->surface_desc.dwFlags & DDSD_MIPMAPCOUNT) &&
(This->surface_desc.u2.dwMipMapCount > 1)) ||
(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)) {
ERR(" need to fix mipmaping in this case !!\n");
}
ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
if (FAILED(ret_value)) return ret_value;
*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture2);
TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
This->ref++; /* No idea if this is correct.. Need to check using real Windows */
ret_value = This->ddraw_owner->d3d->create_texture(This->ddraw_owner->d3d, This, FALSE, NULL, 0);
if (FAILED(ret_value)) return ret_value;
}
if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
*ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
} else {
*ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
}
This->ref++;
return ret_value;
}
#endif

View File

@ -46,14 +46,14 @@ void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
/* All others state variables */
switch (dwRenderStateType) {
case D3DRENDERSTATE_TEXTUREHANDLE: { /* 1 */
IDirect3DTextureImpl *tex = (IDirect3DTextureImpl*) dwRenderState;
IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
if (tex == NULL) {
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
TRACE("disabling texturing\n");
} else {
IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex;
IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex->tex_private;
glEnable(GL_TEXTURE_2D);
/* Default parameters */

View File

@ -82,10 +82,17 @@ typedef struct IDirect3DLightGLImpl
GLenum light_num;
} IDirect3DLightGLImpl;
/* This structure is used for the 'private' field of the IDirectDrawSurfaceImpl structure */
typedef struct IDirect3DTextureGLImpl
{
struct IDirect3DTextureImpl parent;
GLuint tex_name;
BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */
BOOLEAN first_unlock;
DWORD mipmap_level;
/* This is for now used to override 'standard' surface stuff to be as transparent as possible */
void (*final_release)(struct IDirectDrawSurfaceImpl *This);
void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
} IDirect3DTextureGLImpl;
typedef struct IDirect3DDeviceGLImpl
@ -111,7 +118,7 @@ typedef struct IDirect3DDeviceGLImpl
/* All non-static functions 'exported' by various sub-objects */
extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw);
extern HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf);
extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf, DWORD mipmap_level);
extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirect3DImpl *d3d, GLenum light_num);
extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirect3DImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirect3DImpl *d3d);
@ -126,7 +133,7 @@ extern HRESULT d3ddevice_find(IDirect3DImpl *d3d, LPD3DFINDDEVICESEARCH lpD3DDFS
/* Some helper functions.. Would need to put them in a better place */
extern void dump_flexible_vertex(DWORD d3dvtVertexType);
extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements);
/* Matrix copy WITH transposition */
#define conv_mat2(mat,gl_mat) \