- 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:
parent
cc1577cddc
commit
91c6f817b9
|
@ -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*);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¤t_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;
|
||||
TRACE(" uploading texture to GL id %d (initial = %d).\n", glThis->tex_name, init_upload);
|
||||
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
|
||||
|
||||
if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
|
||||
/* ****************
|
||||
Paletted Texture
|
||||
**************** */
|
||||
IDirectDrawPaletteImpl* pal = This->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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return This->ref;
|
||||
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);
|
||||
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
|
||||
DWORD mem_used;
|
||||
|
||||
if (!--(This->ref)) {
|
||||
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, ¤t_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);
|
||||
/* 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;
|
||||
|
||||
*obj = object;
|
||||
ICOM_INIT_INTERFACE(surf, IDirect3DTexture, VTABLE_IDirect3DTexture);
|
||||
ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
|
||||
|
||||
TRACE(" creating implementation at %p.\n", *obj);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
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");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) \
|
||||
|
|
Loading…
Reference in New Issue