Commit 3da729ea authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard

Update and clean-up draw_primitive_strided_7.

Make draw_primitive_7 based on draw_primitive_strided_7.
parent 3542c9c4
...@@ -930,12 +930,30 @@ typedef struct { ...@@ -930,12 +930,30 @@ typedef struct {
float tu1, tv1; float tu1, tv1;
} D3DFVF_TLVERTEX_1; } D3DFVF_TLVERTEX_1;
typedef struct {
float x, y, z, rhw;
} VERTEX_COORDS;
typedef struct {
float nx,ny,nz;
} NORMAL_COORDS;
typedef struct {
float u,v;
} TEXTURE_COORDS;
#define GET_COMPONENT(cpnt,i,type) ((type*)(lpD3DDrawPrimStrideData->cpnt.lpvData+i*lpD3DDrawPrimStrideData->cpnt.dwStride))
#define GET_POSITION(i) GET_COMPONENT(position,i,VERTEX_COORDS)
#define GET_NORMAL(i) GET_COMPONENT(normal,i,NORMAL_COORDS)
#define GET_DIFFUSE(i) *GET_COMPONENT(diffuse,i,DWORD)
#define GET_SPECULAR(i) *GET_COMPONENT(specular,i,DWORD)
#define GET_TEXTURE(i,n) GET_COMPONENT(textureCoords[n],i,TEXTURE_COORDS)
/* These are the various handler used in the generic path */ /* These are the various handler used in the generic path */
static void handle_xyz(char *vertex, int offset, int extra) { inline static void handle_xyz(float *coords) {
glVertex3fv((float *) (vertex + offset)); glVertex3fv(coords);
} }
static void handle_xyzrhw(char *vertex, int offset, int extra) { inline static void handle_xyzrhw(float *coords) {
float *coords = (float *) (vertex + offset);
if (coords[3] < 0.00001) if (coords[3] < 0.00001)
glVertex3f(coords[0], coords[1], coords[2]); glVertex3f(coords[0], coords[1], coords[2]);
else else
...@@ -944,32 +962,31 @@ static void handle_xyzrhw(char *vertex, int offset, int extra) { ...@@ -944,32 +962,31 @@ static void handle_xyzrhw(char *vertex, int offset, int extra) {
coords[2] / coords[3], coords[2] / coords[3],
1.0 / coords[3]); 1.0 / coords[3]);
} }
static void handle_normal(char *vertex, int offset, int extra) { inline static void handle_normal(float *coords) {
glNormal3fv((float *) (vertex + offset)); glNormal3fv(coords);
} }
static void handle_specular(char *vertex, int offset, int extra) { inline static void handle_specular(DWORD color) {
/* Specular not handled yet properly... */ /* Specular not handled yet properly... */
} }
static void handle_diffuse(char *vertex, int offset, int extra) { inline static void handle_diffuse(DWORD color) {
DWORD color = *((DWORD *) (vertex + offset));
glColor4ub((color >> 16) & 0xFF, glColor4ub((color >> 16) & 0xFF,
(color >> 8) & 0xFF, (color >> 8) & 0xFF,
(color >> 0) & 0xFF, (color >> 0) & 0xFF,
(color >> 24) & 0xFF); (color >> 24) & 0xFF);
} }
static void handle_texture(char *vertex, int offset, int extra) { inline static void handle_texture(float *coords, int stage, int single) {
if (extra == 0xFF) { if (single) {
/* Special case for single texture... */ /* Special case for single texture... */
glTexCoord2fv((float *) (vertex + offset)); glTexCoord2fv(coords);
} else { } else {
/* Multitexturing not handled yet */ /* Multitexturing not handled yet */
} }
} }
static void draw_primitive_7(IDirect3DDeviceImpl *This, static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
D3DPRIMITIVETYPE d3dptPrimitiveType, D3DPRIMITIVETYPE d3dptPrimitiveType,
DWORD d3dvtVertexType, DWORD d3dvtVertexType,
LPVOID lpvVertices, LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
DWORD dwVertexCount, DWORD dwVertexCount,
LPWORD dwIndices, LPWORD dwIndices,
DWORD dwIndexCount, DWORD dwIndexCount,
...@@ -988,134 +1005,82 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This, ...@@ -988,134 +1005,82 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
/* Some fast paths first before the generic case.... */ /* Some fast paths first before the generic case.... */
if (d3dvtVertexType == D3DFVF_VERTEX) { if (d3dvtVertexType == D3DFVF_VERTEX) {
D3DFVF_VERTEX_1 *vertices = (D3DFVF_VERTEX_1 *) lpvVertices;
int index; int index;
for (index = 0; index < dwIndexCount; index++) { for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index]; int i = (dwIndices == NULL) ? index : dwIndices[index];
glNormal3fv(&(vertices[i].nx)); glNormal3fv(&GET_NORMAL(i)->nx);
glTexCoord2fv(&(vertices[i].tu1)); glTexCoord2fv(&GET_TEXTURE(i,0)->u);
glVertex3fv(&(vertices[i].x)); glVertex3fv(&GET_POSITION(i)->x);
TRACE(" %f %f %f / %f %f %f (%f %f)\n", TRACE(" %f %f %f / %f %f %f (%f %f)\n",
vertices[i].x, vertices[i].y, vertices[i].z, GET_POSITION(i)->x,GET_POSITION(i)->y,GET_POSITION(i)->z,
vertices[i].nx, vertices[i].ny, vertices[i].nz, GET_NORMAL(i)->nx,GET_NORMAL(i)->ny,GET_NORMAL(i)->nz,
vertices[i].tu1, vertices[i].tv1); GET_TEXTURE(i,0)->u,GET_TEXTURE(i,0)->v);
} }
} else if (d3dvtVertexType == D3DFVF_TLVERTEX) { } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
D3DFVF_TLVERTEX_1 *vertices = (D3DFVF_TLVERTEX_1 *) lpvVertices;
int index; int index;
for (index = 0; index < dwIndexCount; index++) { for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index]; int i = (dwIndices == NULL) ? index : dwIndices[index];
glColor4ub((vertices[i].diffuse >> 16) & 0xFF, glColor4ub((GET_DIFFUSE(i) >> 16) & 0xFF,
(vertices[i].diffuse >> 8) & 0xFF, (GET_DIFFUSE(i) >> 8) & 0xFF,
(vertices[i].diffuse >> 0) & 0xFF, (GET_DIFFUSE(i) >> 0) & 0xFF,
(vertices[i].diffuse >> 24) & 0xFF); (GET_DIFFUSE(i) >> 24) & 0xFF);
/* Todo : handle specular... */ /* Todo : handle specular... */
glTexCoord2fv(&(vertices[i].tu1)); glTexCoord2fv(&GET_TEXTURE(i,0)->u);
if (vertices[i].rhw < 0.00001) if (GET_POSITION(i)->rhw < 0.00001)
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z); glVertex3fv(&GET_POSITION(i)->x);
else else {
glVertex4f(vertices[i].x / vertices[i].rhw, glVertex4f(GET_POSITION(i)->x / GET_POSITION(i)->rhw,
vertices[i].y / vertices[i].rhw, GET_POSITION(i)->y / GET_POSITION(i)->rhw,
vertices[i].z / vertices[i].rhw, GET_POSITION(i)->z / GET_POSITION(i)->rhw,
1.0 / vertices[i].rhw); 1.0 / GET_POSITION(i)->rhw);
}
TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
vertices[i].x, vertices[i].y, vertices[i].z, vertices[i].rhw, GET_POSITION(i)->x,GET_POSITION(i)->y,GET_POSITION(i)->z,GET_POSITION(i)->rhw,
(vertices[i].diffuse >> 16) & 0xFF, (GET_DIFFUSE(i) >> 16) & 0xFF,
(vertices[i].diffuse >> 8) & 0xFF, (GET_DIFFUSE(i) >> 8) & 0xFF,
(vertices[i].diffuse >> 0) & 0xFF, (GET_DIFFUSE(i) >> 0) & 0xFF,
(vertices[i].diffuse >> 24) & 0xFF, (GET_DIFFUSE(i) >> 24) & 0xFF,
(vertices[i].specular >> 16) & 0xFF, (GET_SPECULAR(i) >> 16) & 0xFF,
(vertices[i].specular >> 8) & 0xFF, (GET_SPECULAR(i) >> 8) & 0xFF,
(vertices[i].specular >> 0) & 0xFF, (GET_SPECULAR(i) >> 0) & 0xFF,
(vertices[i].specular >> 24) & 0xFF, (GET_SPECULAR(i) >> 24) & 0xFF,
vertices[i].tu1, vertices[i].tv1); GET_TEXTURE(i,0)->u,GET_TEXTURE(i,0)->v);
} }
} else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) || } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) { ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
/* This is the 'slow path' but that should support all possible vertex formats out there... /* 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... Note that people should write a fast path for all vertex formats out there...
*/ */
DWORD elements;
DWORD size;
char *vertices = (char *) lpvVertices;
int index; int index;
int current_offset = 0; for (index = 0; index < dwIndexCount; index++) {
int current_position = 0; int i = (dwIndices == NULL) ? index : dwIndices[index];
D3DFVF_GENERIC *handler;
if ((glThis->last_vertex_format != d3dvtVertexType) ||
(glThis->handler == NULL)) {
if (glThis->handler == NULL) HeapFree(GetProcessHeap(), 0, glThis->handler);
size = get_flexible_vertex_size(d3dvtVertexType, &elements);
glThis->handler = handler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, elements * sizeof(D3DFVF_GENERIC));
glThis->last_vertex_format = d3dvtVertexType;
glThis->last_vertex_format_size = size;
glThis->last_vertex_format_elements = elements;
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
handler[elements - 1].handler = handle_xyz; handle_xyz(&GET_POSITION(i)->x);
handler[elements - 1].offset = current_offset;
current_offset += 3 * sizeof(D3DVALUE);
} else { } else {
handler[elements - 1].handler = handle_xyzrhw; handle_xyzrhw(&GET_POSITION(i)->x);
handler[elements - 1].offset = current_offset;
current_offset += 4 * sizeof(D3DVALUE);
} }
if (d3dvtVertexType & D3DFVF_NORMAL) { if (d3dvtVertexType & D3DFVF_NORMAL) {
handler[current_position].handler = handle_normal; handle_normal(&GET_NORMAL(i)->nx);
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += 3 * sizeof(D3DVALUE);
} }
if (d3dvtVertexType & D3DFVF_DIFFUSE) { if (d3dvtVertexType & D3DFVF_DIFFUSE) {
handler[current_position].handler = handle_diffuse; handle_diffuse(GET_DIFFUSE(i));
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += sizeof(DWORD);
} }
if (d3dvtVertexType & D3DFVF_SPECULAR) { if (d3dvtVertexType & D3DFVF_SPECULAR) {
handler[current_position].handler = handle_specular; /* Todo : handle specular... */
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += sizeof(DWORD);
} }
if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) { if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
handler[current_position].handler = handle_texture; /* Special case for single texture... */
handler[current_position].offset = current_offset; handle_texture(&GET_TEXTURE(i,0)->u,0,1);
handler[current_position].extra = 0xFF;
current_position += 1;
current_offset += 2 * sizeof(D3DVALUE);
} else { } else {
int tex_index; int tex_index;
for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
handler[current_position].handler = handle_texture; /* Multitexturing not handled yet */
handler[current_position].offset = current_offset;
handler[current_position].extra = tex_index;
current_position += 1;
current_offset += 2 * sizeof(D3DVALUE);
} }
} }
} else {
handler = glThis->handler;
size = glThis->last_vertex_format_size;
elements = glThis->last_vertex_format_elements;
}
WARN(" using draw_primitive generic path - for better performance, add a fast path for your vertex case !\n");
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 { } else {
ERR(" matrix weighting not handled yet....\n"); ERR(" matrix weighting not handled yet....\n");
...@@ -1126,78 +1091,52 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This, ...@@ -1126,78 +1091,52 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
TRACE("End\n"); TRACE("End\n");
} }
#define CPNT(cpnt,i,n,type) ((type*)(lpD3DDrawPrimStrideData->cpnt.lpvData+i*lpD3DDrawPrimStrideData->cpnt.dwStride))[n] static void draw_primitive_7(IDirect3DDeviceImpl *This,
static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
D3DPRIMITIVETYPE d3dptPrimitiveType, D3DPRIMITIVETYPE d3dptPrimitiveType,
DWORD d3dvtVertexType, DWORD d3dvtVertexType,
LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, LPVOID lpvVertices,
DWORD dwVertexCount, DWORD dwVertexCount,
LPWORD dwIndices, LPWORD dwIndices,
DWORD dwIndexCount, DWORD dwIndexCount,
DWORD dwFlags) DWORD dwFlags)
{ {
IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; D3DDRAWPRIMITIVESTRIDEDDATA strided;
if (TRACE_ON(ddraw)) { int current_offset = 0;
TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType); int tex_index;
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
strided.position.lpvData = lpvVertices;
current_offset += 3 * sizeof(D3DVALUE);
} else {
strided.position.lpvData = lpvVertices;
current_offset += 4 * sizeof(D3DVALUE);
} }
if (d3dvtVertexType & D3DFVF_NORMAL) {
ENTER_GL(); strided.normal.lpvData = lpvVertices + current_offset;
draw_primitive_handle_GL_state(glThis, current_offset += 3 * sizeof(D3DVALUE);
(d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ, }
(d3dvtVertexType & D3DFVF_NORMAL) == 0); if (d3dvtVertexType & D3DFVF_DIFFUSE) {
draw_primitive_start_GL(d3dptPrimitiveType); strided.diffuse.lpvData = lpvVertices + current_offset;
current_offset += sizeof(DWORD);
/* Some fast paths first before the generic case.... */ }
if (d3dvtVertexType == D3DFVF_VERTEX) { if (d3dvtVertexType & D3DFVF_SPECULAR) {
int index; strided.specular.lpvData = lpvVertices + current_offset;
current_offset += sizeof(DWORD);
for (index = 0; index < dwIndexCount; index++) { }
int i = (dwIndices == NULL) ? index : dwIndices[index]; for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
strided.textureCoords[tex_index].lpvData = lpvVertices + current_offset;
glNormal3f(CPNT(normal,i,0,D3DVALUE),CPNT(normal,i,1,D3DVALUE),CPNT(normal,i,2,D3DVALUE)); current_offset += 2*sizeof(D3DVALUE);
glTexCoord2f(CPNT(textureCoords[1],i,0,D3DVALUE),CPNT(textureCoords[1],i,1,D3DVALUE));
glVertex3f(CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE));
TRACE(" %f %f %f / %f %f %f (%f %f)\n",
CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE),
CPNT(normal,i,0,D3DVALUE),CPNT(normal,i,1,D3DVALUE),CPNT(normal,i,2,D3DVALUE),
CPNT(textureCoords[1],i,0,D3DVALUE),CPNT(textureCoords[1],i,1,D3DVALUE));
}
} else if (d3dvtVertexType == D3DFVF_LVERTEX) {
int index;
for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index];
glColor4ub((CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF,
(CPNT(diffuse,i,0,DWORD) >> 8) & 0xFF,
(CPNT(diffuse,i,0,DWORD) >> 0) & 0xFF,
(CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF);
/* Todo : handle specular... */
glTexCoord2f(CPNT(textureCoords[1],i,0,D3DVALUE),CPNT(textureCoords[1],i,1,D3DVALUE));
glVertex3f(CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE));
TRACE(" %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE),
(CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF,
(CPNT(diffuse,i,0,DWORD) >> 8) & 0xFF,
(CPNT(diffuse,i,0,DWORD) >> 0) & 0xFF,
(CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF,
(CPNT(specular,i,0,DWORD) >> 16) & 0xFF,
(CPNT(specular,i,0,DWORD) >> 8) & 0xFF,
(CPNT(specular,i,0,DWORD) >> 0) & 0xFF,
(CPNT(specular,i,0,DWORD) >> 24) & 0xFF,
CPNT(textureCoords[0],i,0,D3DVALUE),CPNT(textureCoords[0],i,1,D3DVALUE));
}
} }
strided.position.dwStride = current_offset;
strided.normal.dwStride = current_offset;
strided.diffuse.dwStride = current_offset;
strided.specular.dwStride = current_offset;
for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
strided.textureCoords[tex_index].dwStride = current_offset;
glEnd(); draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
LEAVE_GL();
TRACE("End\n");
} }
#undef CPNT
HRESULT WINAPI HRESULT WINAPI
GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface, GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
D3DPRIMITIVETYPE d3dptPrimitiveType, D3DPRIMITIVETYPE d3dptPrimitiveType,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment