Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
- index 4df04fa..41939e7 100644
- --- a/dlls/wined3d/directx.c
- +++ b/dlls/wined3d/directx.c
- @@ -4553,8 +4553,13 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
- pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
- pCaps->MaxActiveLights = gl_info->limits.lights;
- - pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
- - pCaps->MaxVertexBlendMatrixIndex = 0;
- + if (gl_info->supported[ARB_VERTEX_BLEND]) {
- + pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
- + pCaps->MaxVertexBlendMatrixIndex = 0;
- + } else {
- + pCaps->MaxVertexBlendMatrices = 4;
- + pCaps->MaxVertexBlendMatrixIndex = 255;
- + }
- pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
- pCaps->MaxPointSize = gl_info->limits.pointsize_max;
- diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
- index 1f904ea..adc9eca 100644
- --- a/dlls/wined3d/drawprim.c
- +++ b/dlls/wined3d/drawprim.c
- @@ -55,6 +55,75 @@ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type,
- }
- /*
- + * Emit a vertex using swoftware vertex blending
- + */
- +static void emitBlendedVertex(IWineD3DStateBlockImpl *stateBlock,
- + const float *weights, int nweights, const BYTE *indices,
- + const float *pos, const float *norm)
- +{
- + const float *m;
- + float vec[4];
- + float mat[4*4];
- + float last = 1.f;
- + int i, j;
- +
- + /* compute the weighted sum of the matrices */
- + m = &stateBlock->transforms[WINED3DTS_WORLDMATRIX((indices ? indices[0] : 0))].u.m[0][0];
- + for (j = 0; j < 16; j++)
- + mat[j] = m[j] * weights[0];
- + last -= weights[0];
- +
- + for (i = 1; i < nweights; i++) {
- + if (weights[i]) {
- + m = &stateBlock->transforms[WINED3DTS_WORLDMATRIX((indices ? indices[i] : i))].u.m[0][0];
- + for (j = 0; j < 16; j++)
- + mat[j] += m[j] * weights[i];
- + last -= weights[i];
- + }
- + }
- +
- + /* do the last */
- + if (last) {
- + m = &stateBlock->transforms[WINED3DTS_WORLDMATRIX((indices ? indices[i] : i))].u.m[0][0];
- + for (j = 0; j < 16; j++)
- + mat[j] += m[j] * last;
- + }
- +
- + if (norm) {
- + /* compute the resulting normal */
- + vec[0] = norm[0] * mat[0] + norm[1] * mat[4] + norm[2] * mat[8];
- + vec[1] = norm[0] * mat[1] + norm[1] * mat[5] + norm[2] * mat[9];
- + vec[2] = norm[0] * mat[2] + norm[1] * mat[6] + norm[2] * mat[10];
- + /* normalize */
- + vec[3] = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
- + if (vec[3]) {
- + vec[3] = 1.f / sqrtf(vec[3]);
- + vec[0] *= vec[3];
- + vec[1] *= vec[3];
- + vec[2] *= vec[3];
- + }
- +
- + glNormal3fv(vec);
- + }
- +
- + if (pos) {
- + /* compute the resulting position */
- + vec[0] = pos[0] * mat[0] + pos[1] * mat[4] + pos[2] * mat[8] + mat[12];
- + vec[1] = pos[0] * mat[1] + pos[1] * mat[5] + pos[2] * mat[9] + mat[13];
- + vec[2] = pos[0] * mat[2] + pos[1] * mat[6] + pos[2] * mat[10] + mat[14];
- + vec[3] = pos[0] * mat[3] + pos[1] * mat[7] + pos[2] * mat[11] + mat[15];
- + /* normalize */
- + if (vec[3]) {
- + vec[0] /= vec[3];
- + vec[1] /= vec[3];
- + vec[2] /= vec[3];
- + }
- +
- + glVertex3fv(vec);
- + }
- +}
- +
- +/*
- * Actually draw using the supplied information.
- * Slower GL version which extracts info about each vertex in turn
- */
- @@ -74,7 +74,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
- BOOL pixelShader = use_ps(This->stateBlock);
- BOOL specular_fog = FALSE;
- const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
- - const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
- + const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL, *weights = NULL, *indices = NULL;
- + int nweights = 0;
- const struct wined3d_gl_info *gl_info = context->gl_info;
- UINT texture_stages = gl_info->limits.texture_stages;
- const struct wined3d_stream_info_element *element;
- @@ -166,6 +236,31 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
- {
- GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
- }
- +
- + if (This->vertexBlendSW) {
- + if (!si->elements[WINED3D_FFP_BLENDWEIGHT].data) {
- + WARN("vertex blending enabled but blendWeights.data=NULL\n");
- + } else if (si->elements[WINED3D_FFP_BLENDWEIGHT].format_desc->gl_vtx_type != GL_FLOAT) {
- + FIXME("unsupported blend weights datatype (%d)\n", si->elements[WINED3D_FFP_BLENDWEIGHT].format_desc->format);
- + } else if (position && si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx != WINED3D_FFP_EMIT_FLOAT3) {
- + FIXME("unsupported postion datatype (%d)\n", si->elements[WINED3D_FFP_POSITION].format_desc->format);
- + } else if (normal && si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx != WINED3D_FFP_EMIT_FLOAT3) {
- + FIXME("unsupported normal datatype (%d)\n", si->elements[WINED3D_FFP_NORMAL].format_desc->format);
- + } else {
- + element = &si->elements[WINED3D_FFP_BLENDWEIGHT];
- + weights = element->data + streamOffset[element->stream_idx];
- + nweights = element->format_desc->gl_vtx_format;
- + }
- +
- + if (si->elements[WINED3D_FFP_BLENDINDICES].data) {
- + if (si->elements[WINED3D_FFP_BLENDINDICES].format_desc->emit_idx != WINED3D_FFP_EMIT_UBYTE4) {
- + FIXME("unsupported blend indices datatype (%d)\n", si->elements[WINED3D_FFP_BLENDINDICES].format_desc->format);
- + } else {
- + element = &si->elements[WINED3D_FFP_BLENDINDICES];
- + indices = element->data + streamOffset[element->stream_idx];
- + }
- + }
- + }
- for (textureNo = 0; textureNo < texture_stages; ++textureNo)
- {
- @@ -283,16 +378,24 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
- }
- }
- - /* Normal -------------------------------- */
- - if (normal != NULL) {
- - const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
- - normal_funcs[si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx](ptrToCoords);
- - }
- + if (weights) {
- + emitBlendedVertex(This->stateBlock,
- + (const float*)(weights + SkipnStrides * si->elements[WINED3D_FFP_BLENDWEIGHT].stride), nweights,
- + indices ? (indices + SkipnStrides * si->elements[WINED3D_FFP_BLENDINDICES].stride) : NULL,
- + (const float*)(position ? (position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride) : NULL),
- + (const float*)(normal ? (normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride) : NULL));
- + } else {
- + /* Normal -------------------------------- */
- + if (normal != NULL) {
- + const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
- + normal_funcs[si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx](ptrToCoords);
- + }
- - /* Position -------------------------------- */
- - if (position) {
- - const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
- - position_funcs[si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx](ptrToCoords);
- + /* Position -------------------------------- */
- + if (position) {
- + const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
- + position_funcs[si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx](ptrToCoords);
- + }
- }
- /* For non indexed mode, step onto next parts */
- @@ -680,6 +783,17 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
- }
- emulation = TRUE;
- }
- + else if (This->vertexBlendSW)
- + {
- + static BOOL warned;
- + if (!warned) {
- + FIXME("Using software emulation because vertex blending is enabled\n");
- + warned = TRUE;
- + } else {
- + TRACE("Using software emulation because vertex blending is enabled\n");
- + }
- + emulation = TRUE;
- + }
- if(emulation) {
- stream_info = &stridedlcl;
- diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
- index 28de4ea..a13423b 100644
- --- a/dlls/wined3d/state.c
- +++ b/dlls/wined3d/state.c
- @@ -3670,7 +3670,7 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str
- if(context->last_was_rhw) {
- glLoadIdentity();
- checkGLcall("glLoadIdentity()");
- - } else {
- + } else if (!stateblock->device->vertexBlendSW) {
- /* In the general case, the view matrix is the identity matrix */
- if (stateblock->device->view_ident)
- {
- @@ -3684,6 +3684,9 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str
- glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
- checkGLcall("glMultMatrixf");
- }
- + } else {
- + glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
- + checkGLcall("glLoadMatrixf");
- }
- }
- @@ -3769,13 +3772,33 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s
- static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
- {
- - WINED3DVERTEXBLENDFLAGS f = stateblock->renderState[WINED3DRS_VERTEXBLEND];
- + WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
- static unsigned int once;
- - if (f == WINED3DVBF_DISABLE) return;
- -
- - if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
- - else WARN("Vertex blend flags %#x not supported.\n", f);
- + switch (val) {
- + case WINED3DVBF_0WEIGHTS:
- + case WINED3DVBF_1WEIGHTS:
- + case WINED3DVBF_2WEIGHTS:
- + case WINED3DVBF_3WEIGHTS:
- + if(!once) {
- + once = TRUE;
- + FIXME("Vertex blending enabled, but not supported by hardware. Using software emulation.\n");
- + }
- + if (!stateblock->device->vertexBlendSW) {
- + stateblock->device->vertexBlendSW = TRUE;
- + transform_world(state, stateblock, context);
- + }
- + break;
- + case WINED3DVBF_TWEENING:
- + WARN("Vertex blend flags %#x not supported.\n", val);
- + /* fall through */
- + default:
- + if (stateblock->device->vertexBlendSW) {
- + stateblock->device->vertexBlendSW = FALSE;
- + transform_world(state, stateblock, context);
- + }
- + break;
- + }
- }
- static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
- diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
- index 0bc141a..9a87f7e 100644
- --- a/dlls/wined3d/vertexdeclaration.c
- +++ b/dlls/wined3d/vertexdeclaration.c
- @@ -125,6 +125,15 @@ static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
- default:
- return FALSE;
- }
- +
- + case WINED3DDECLUSAGE_BLENDINDICES:
- + switch(element->format)
- + {
- + case WINED3DFMT_R8G8B8A8_UINT:
- + return TRUE;
- + default:
- + return FALSE;
- + }
- case WINED3DDECLUSAGE_NORMAL:
- switch(element->format)
- diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
- index 179b4c4..b35ff81 100644
- --- a/dlls/wined3d/wined3d_private.h
- +++ b/dlls/wined3d/wined3d_private.h
- @@ -1624,6 +1624,7 @@ struct IWineD3DDeviceImpl
- WORD view_ident : 1; /* true iff view matrix is identity */
- WORD untransformed : 1;
- WORD vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
- + WORD vertexBlendSW : 1; /* vertexBlend software fallback used */
- WORD isRecordingState : 1;
- WORD isInDraw : 1;
- WORD bCursorVisible : 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement