/*
 * WINED3D draw functions
 *
 * Copyright 2002-2004 Jason Edmeades
 * Copyright 2002-2004 Raphael Junqueira
 * Copyright 2004 Christian Costa
 * Copyright 2005 Oliver Stieber
 * Copyright 2006 Henri Verbeet
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wined3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info

#include <stdio.h>

#if 0 /* TODO */
extern IWineD3DVertexShaderImpl*            VertexShaders[64];
extern IWineD3DVertexDeclarationImpl*       VertexShaderDeclarations[64];
extern IWineD3DPixelShaderImpl*             PixelShaders[64];

#undef GL_VERSION_1_4 /* To be fixed, caused by mesa headers */
#endif

/* Issues the glBegin call for gl given the primitive type and count */
static DWORD primitiveToGl(WINED3DPRIMITIVETYPE PrimitiveType,
                    DWORD            NumPrimitives,
                    GLenum          *primType)
{
    DWORD   NumVertexes = NumPrimitives;

    switch (PrimitiveType) {
    case WINED3DPT_POINTLIST:
        TRACE("POINTS\n");
        *primType   = GL_POINTS;
        NumVertexes = NumPrimitives;
        break;

    case WINED3DPT_LINELIST:
        TRACE("LINES\n");
        *primType   = GL_LINES;
        NumVertexes = NumPrimitives * 2;
        break;

    case WINED3DPT_LINESTRIP:
        TRACE("LINE_STRIP\n");
        *primType   = GL_LINE_STRIP;
        NumVertexes = NumPrimitives + 1;
        break;

    case WINED3DPT_TRIANGLELIST:
        TRACE("TRIANGLES\n");
        *primType   = GL_TRIANGLES;
        NumVertexes = NumPrimitives * 3;
        break;

    case WINED3DPT_TRIANGLESTRIP:
        TRACE("TRIANGLE_STRIP\n");
        *primType   = GL_TRIANGLE_STRIP;
        NumVertexes = NumPrimitives + 2;
        break;

    case WINED3DPT_TRIANGLEFAN:
        TRACE("TRIANGLE_FAN\n");
        *primType   = GL_TRIANGLE_FAN;
        NumVertexes = NumPrimitives + 2;
        break;

    default:
        FIXME("Unhandled primitive\n");
        *primType    = GL_POINTS;
        break;
    }
    return NumVertexes;
}

/* Ensure the appropriate material states are set up - only change
   state if really required                                        */
static void init_materials(IWineD3DDevice *iface, BOOL isDiffuseSupplied) {

    BOOL requires_material_reset = FALSE;
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    if (This->tracking_color == NEEDS_TRACKING && isDiffuseSupplied) {
        /* If we have not set up the material color tracking, do it now as required */
        glDisable(GL_COLOR_MATERIAL); /* Note: Man pages state must enable AFTER calling glColorMaterial! Required?*/
        checkGLcall("glDisable GL_COLOR_MATERIAL");
        TRACE("glColorMaterial Parm=%x\n", This->tracking_parm);
        glColorMaterial(GL_FRONT_AND_BACK, This->tracking_parm);
        checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
        glEnable(GL_COLOR_MATERIAL);
        checkGLcall("glEnable GL_COLOR_MATERIAL");
        This->tracking_color = IS_TRACKING;
        requires_material_reset = TRUE; /* Restore material settings as will be used */

    } else if ((This->tracking_color == IS_TRACKING && !isDiffuseSupplied) ||
               (This->tracking_color == NEEDS_TRACKING && !isDiffuseSupplied)) {
        /* If we are tracking the current color but one isn't supplied, don't! */
        glDisable(GL_COLOR_MATERIAL);
        checkGLcall("glDisable GL_COLOR_MATERIAL");
        This->tracking_color = NEEDS_TRACKING;
        requires_material_reset = TRUE; /* Restore material settings as will be used */

    } else if (This->tracking_color == IS_TRACKING && isDiffuseSupplied) {
        /* No need to reset material colors since no change to gl_color_material */
        requires_material_reset = FALSE;

    } else if (This->tracking_color == NEEDS_DISABLE) {
        glDisable(GL_COLOR_MATERIAL);
        checkGLcall("glDisable GL_COLOR_MATERIAL");
        This->tracking_color = DISABLED_TRACKING;
        requires_material_reset = TRUE; /* Restore material settings as will be used */
    }

    /* Reset the material colors which may have been tracking the color*/
    if (requires_material_reset) {
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->stateBlock->material.Ambient);
        checkGLcall("glMaterialfv");
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->stateBlock->material.Diffuse);
        checkGLcall("glMaterialfv");
        if (This->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
           glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->stateBlock->material.Specular);
           checkGLcall("glMaterialfv");
        } else {
           float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
           glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
           checkGLcall("glMaterialfv");
        }
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->stateBlock->material.Emissive);
        checkGLcall("glMaterialfv");
    }

}

static const GLfloat invymat[16] = {
	1.0f, 0.0f, 0.0f, 0.0f,
	0.0f, -1.0f, 0.0f, 0.0f,
	0.0f, 0.0f, 1.0f, 0.0f,
	0.0f, 0.0f, 0.0f, 1.0f};

void d3ddevice_set_ortho(IWineD3DDeviceImpl *This) {
    /* If the last draw was transformed as well, no need to reapply all the matrixes */
    if ( (!This->last_was_rhw) || (This->viewport_changed) ) {

        double X, Y, height, width, minZ, maxZ;
        This->last_was_rhw = TRUE;
        This->viewport_changed = FALSE;

        /* Transformed already into viewport coordinates, so we do not need transform
            matrices. Reset all matrices to identity and leave the default matrix in world
            mode.                                                                         */
        glMatrixMode(GL_MODELVIEW);
        checkGLcall("glMatrixMode(GL_MODELVIEW)");
        glLoadIdentity();
        checkGLcall("glLoadIdentity");

        glMatrixMode(GL_PROJECTION);
        checkGLcall("glMatrixMode(GL_PROJECTION)");
        glLoadIdentity();
        checkGLcall("glLoadIdentity");

        /* Set up the viewport to be full viewport */
        X      = This->stateBlock->viewport.X;
        Y      = This->stateBlock->viewport.Y;
        height = This->stateBlock->viewport.Height;
        width  = This->stateBlock->viewport.Width;
        minZ   = This->stateBlock->viewport.MinZ;
        maxZ   = This->stateBlock->viewport.MaxZ;
        if(!This->untransformed) {
            TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
            glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
        } else {
            TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
            glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
        }
        checkGLcall("glOrtho");

        /* Window Coord 0 is the middle of the first pixel, so translate by half
            a pixel (See comment above glTranslate below)                         */
        glTranslatef(0.375, 0.375, 0);
        checkGLcall("glTranslatef(0.375, 0.375, 0)");
        /* D3D texture coordinates are flipped compared to OpenGL ones, so
         * render everything upside down when rendering offscreen. */
        if (This->render_offscreen) {
            glMultMatrixf(invymat);
            checkGLcall("glMultMatrixf(invymat)");
        }

        /* Vertex fog on transformed vertices? Use the calculated fog factor stored in the specular color */
        if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] && This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != WINED3DFOG_NONE) {
            if(GL_SUPPORT(EXT_FOG_COORD)) {
                glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
                checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
                glFogi(GL_FOG_MODE, GL_LINEAR);
                checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
                /* The dx fog range in this case is fixed to 0 - 255,
                 * but in GL it still depends on the fog start and end (according to the ext)
                 * Use this to turn around the fog as it's needed. That prevents some
                 * calculations during drawing :-)
                 */
                glFogf(GL_FOG_START, (float) 0xff);
                checkGLcall("glFogfv GL_FOG_END");
                glFogf(GL_FOG_END, 0.0);
                checkGLcall("glFogfv GL_FOG_START");
            } else {
                /* Disable GL fog, handle this in software in drawStridedSlow */
                glDisable(GL_FOG);
                checkGLcall("glDisable(GL_FOG)");
            }
        }
    }
}
/* Setup views - Transformed & lit if RHW, else untransformed.
       Only unlit if Normals are supplied
    Returns: Whether to restore lighting afterwards           */
static void primitiveInitState(
    IWineD3DDevice *iface,
    WineDirect3DVertexStridedData* strided,
    BOOL useVS,
    BOOL* lighting_changed,
    BOOL* lighting_original) {

    BOOL fixed_vtx_transformed =
       (strided->u.s.position.lpData != NULL || strided->u.s.position.VBO != 0 ||
        strided->u.s.position2.lpData != NULL || strided->u.s.position2.VBO != 0) && 
        strided->u.s.position_transformed;

    BOOL fixed_vtx_lit = 
        strided->u.s.normal.lpData == NULL && strided->u.s.normal.VBO == 0 &&
        strided->u.s.normal2.lpData == NULL && strided->u.s.normal2.VBO == 0;

    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    *lighting_changed = FALSE;

    /* If no normals, DISABLE lighting otherwise, don't touch lighing as it is
       set by the appropriate render state. Note Vertex Shader output is already lit */
    if (fixed_vtx_lit || useVS) {
        *lighting_changed = TRUE;
        *lighting_original = glIsEnabled(GL_LIGHTING);
        glDisable(GL_LIGHTING);
        checkGLcall("glDisable(GL_LIGHTING);");
        TRACE("Disabled lighting, old state = %d\n", *lighting_original);
    }

    if (!useVS && fixed_vtx_transformed) {
        d3ddevice_set_ortho(This);

    } else {

        /* Untransformed, so relies on the view and projection matrices */
        This->untransformed = TRUE;

        if (!useVS && (This->last_was_rhw || !This->modelview_valid)) {
            /* Only reapply when have to */
            This->modelview_valid = TRUE;
            glMatrixMode(GL_MODELVIEW);
            checkGLcall("glMatrixMode");

            /* In the general case, the view matrix is the identity matrix */
            if (This->view_ident) {
                glLoadMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
                checkGLcall("glLoadMatrixf");
            } else {
                glLoadMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_VIEW].u.m[0][0]);
                checkGLcall("glLoadMatrixf");
                glMultMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
                checkGLcall("glMultMatrixf");
            }
        }

        if (!useVS && (This->last_was_rhw || !This->proj_valid)) {
            /* Only reapply when have to */
            This->proj_valid = TRUE;
            glMatrixMode(GL_PROJECTION);
            checkGLcall("glMatrixMode");

            /* The rule is that the window coordinate 0 does not correspond to the
               beginning of the first pixel, but the center of the first pixel.
               As a consequence if you want to correctly draw one line exactly from
               the left to the right end of the viewport (with all matrices set to
               be identity), the x coords of both ends of the line would be not
               -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
               instead.                                                               */
            glLoadIdentity();

            glTranslatef(0.9 / This->stateBlock->viewport.Width, -0.9 / This->stateBlock->viewport.Height, 0);
            checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");

            /* D3D texture coordinates are flipped compared to OpenGL ones, so
             * render everything upside down when rendering offscreen. */
            if (This->render_offscreen) {
                glMultMatrixf(invymat);
                checkGLcall("glMultMatrixf(invymat)");
            }
            glMultMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
            checkGLcall("glLoadMatrixf");
        }

        /* Vertex Shader output is already transformed, so set up identity matrices */
        if (useVS) {
            This->posFixup[1] = This->render_offscreen ? -1.0 : 1.0;
            This->posFixup[2] = 0.9 / This->stateBlock->viewport.Width;
            This->posFixup[3] = -0.9 / This->stateBlock->viewport.Height;
        }
        This->last_was_rhw = FALSE;

        /* Setup fogging */
        if (useVS && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->usesFog) {
            /* In D3D vertex shader return the 'final' fog value, while in OpenGL it is the 'input' fog value.
             * The code below 'disables' the OpenGL postprocessing by setting the formula to '1'. */
            glFogi(GL_FOG_MODE, GL_LINEAR);
            glFogf(GL_FOG_START, 1.0f);
            glFogf(GL_FOG_END, 0.0f);

        } else if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] 
                  && This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != WINED3DFOG_NONE) {
            /* Reapply the fog */
            StateTable[STATE_RENDER(WINED3DRS_FOGENABLE)].apply(STATE_RENDER(WINED3DRS_FOGSTART), This->stateBlock);
        }
    }
}

static BOOL fixed_get_input(
    BYTE usage, BYTE usage_idx,
    unsigned int* regnum) {

    *regnum = -1;

    /* Those positions must have the order in the
     * named part of the strided data */

    if ((usage == D3DDECLUSAGE_POSITION || usage == D3DDECLUSAGE_POSITIONT) && usage_idx == 0)
        *regnum = 0;
    else if (usage == D3DDECLUSAGE_BLENDWEIGHT && usage_idx == 0)
        *regnum = 1;
    else if (usage == D3DDECLUSAGE_BLENDINDICES && usage_idx == 0)
        *regnum = 2;
    else if (usage == D3DDECLUSAGE_NORMAL && usage_idx == 0)
        *regnum = 3;
    else if (usage == D3DDECLUSAGE_PSIZE && usage_idx == 0)
        *regnum = 4;
    else if (usage == D3DDECLUSAGE_COLOR && usage_idx == 0)
        *regnum = 5;
    else if (usage == D3DDECLUSAGE_COLOR && usage_idx == 1)
        *regnum = 6;
    else if (usage == D3DDECLUSAGE_TEXCOORD && usage_idx < WINED3DDP_MAXTEXCOORD)
        *regnum = 7 + usage_idx;
    else if ((usage == D3DDECLUSAGE_POSITION || usage == D3DDECLUSAGE_POSITIONT) && usage_idx == 1)
        *regnum = 7 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_NORMAL && usage_idx == 1)
        *regnum = 8 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_TANGENT && usage_idx == 0)
        *regnum = 9 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_BINORMAL && usage_idx == 0)
        *regnum = 10 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_TESSFACTOR && usage_idx == 0)
        *regnum = 11 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_FOG && usage_idx == 0)
        *regnum = 12 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_DEPTH && usage_idx == 0)
        *regnum = 13 + WINED3DDP_MAXTEXCOORD;
    else if (usage == D3DDECLUSAGE_SAMPLE && usage_idx == 0)
        *regnum = 14 + WINED3DDP_MAXTEXCOORD;

    if (*regnum < 0) {
        FIXME("Unsupported input stream [usage=%s, usage_idx=%u]\n",
            debug_d3ddeclusage(usage), usage_idx);
        return FALSE;
    }
    return TRUE;
}

void primitiveDeclarationConvertToStridedData(
     IWineD3DDevice *iface,
     BOOL useVertexShaderFunction,
     WineDirect3DVertexStridedData *strided,
     LONG BaseVertexIndex, 
     BOOL *fixup) {

     /* We need to deal with frequency data!*/

    BYTE  *data    = NULL;
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    IWineD3DVertexDeclarationImpl* vertexDeclaration = NULL;
    int i;
    WINED3DVERTEXELEMENT *element;
    DWORD stride;
    int reg;

    /* Locate the vertex declaration */
    if (This->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration) {
        TRACE("Using vertex declaration from shader\n");
        vertexDeclaration = (IWineD3DVertexDeclarationImpl *)((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration;
    } else {
        TRACE("Using vertex declaration\n");
        vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl;
    }

    /* Translate the declaration into strided data */
    for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
        GLint streamVBO = 0;
        BOOL stride_used;
        unsigned int idx;

        element = vertexDeclaration->pDeclarationWine + i;
        TRACE("%p Element %p (%d of %d)\n", vertexDeclaration->pDeclarationWine,
            element,  i + 1, vertexDeclaration->declarationWNumElements - 1);

        if (This->stateBlock->streamSource[element->Stream] == NULL)
            continue;

        if (This->stateBlock->streamIsUP) {
            TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
            streamVBO = 0;
            data    = (BYTE *)This->stateBlock->streamSource[element->Stream];
            if(fixup && *fixup) FIXME("Missing fixed and unfixed vertices, expect graphics glitches\n");
        } else {
            TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
            IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[element->Stream]);
            data    = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
            if(fixup) {
                if( streamVBO != 0) *fixup = TRUE;
                else if(*fixup) FIXME("Missing fixed and unfixed vertices, expect graphics glitches\n");
            }
        }
        stride  = This->stateBlock->streamStride[element->Stream];
        data += (BaseVertexIndex * stride);
        data += element->Offset;
        reg = element->Reg;

        TRACE("Offset %d Stream %d UsageIndex %d\n", element->Offset, element->Stream, element->UsageIndex);

        if (useVertexShaderFunction)
            stride_used = vshader_get_input(This->stateBlock->vertexShader,
                element->Usage, element->UsageIndex, &idx);
        else
            stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx);

        if (stride_used) {
           TRACE("Loaded %s array %u [usage=%s, usage_idx=%u, "
                 "stream=%u, offset=%u, stride=%u, VBO=%u]\n",
                 useVertexShaderFunction? "shader": "fixed function", idx,
                 debug_d3ddeclusage(element->Usage), element->UsageIndex,
                 element->Stream, element->Offset, stride, streamVBO);

           strided->u.input[idx].lpData = data;
           strided->u.input[idx].dwType = element->Type;
           strided->u.input[idx].dwStride = stride;
           strided->u.input[idx].VBO = streamVBO;
           if (!useVertexShaderFunction) {
               if (element->Usage == D3DDECLUSAGE_POSITION)
                   strided->u.s.position_transformed = FALSE;
               else if (element->Usage == D3DDECLUSAGE_POSITIONT)
                   strided->u.s.position_transformed = TRUE;
           }
        }
    };
}

void primitiveConvertFVFtoOffset(DWORD thisFVF, DWORD stride, BYTE *data, WineDirect3DVertexStridedData *strided, GLint streamVBO) {
    int           numBlends;
    int           numTextures;
    int           textureNo;
    int           coordIdxInfo = 0x00;    /* Information on number of coords supplied */
    int           numCoords[8];           /* Holding place for WINED3DFVF_TEXTUREFORMATx  */

    /* Either 3 or 4 floats depending on the FVF */
    /* FIXME: Can blending data be in a different stream to the position data?
          and if so using the fixed pipeline how do we handle it               */
    if (thisFVF & WINED3DFVF_POSITION_MASK) {
        strided->u.s.position.lpData    = data;
        strided->u.s.position.dwType    = WINED3DDECLTYPE_FLOAT3;
        strided->u.s.position.dwStride  = stride;
        strided->u.s.position.VBO       = streamVBO;
        data += 3 * sizeof(float);
        if (thisFVF & WINED3DFVF_XYZRHW) {
            strided->u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
            strided->u.s.position_transformed = TRUE;
            data += sizeof(float);
        } else
            strided->u.s.position_transformed = FALSE;
    }

    /* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */
    /** do we have to Check This->stateBlock->renderState[D3DRS_INDEXEDVERTEXBLENDENABLE] ? */
    numBlends = 1 + (((thisFVF & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1);
    if(thisFVF & WINED3DFVF_LASTBETA_UBYTE4) numBlends--;

    if ((thisFVF & WINED3DFVF_XYZB5 ) > WINED3DFVF_XYZRHW) {
        TRACE("Setting blend Weights to %p\n", data);
        strided->u.s.blendWeights.lpData    = data;
        strided->u.s.blendWeights.dwType    = WINED3DDECLTYPE_FLOAT1 + numBlends - 1;
        strided->u.s.blendWeights.dwStride  = stride;
        strided->u.s.blendWeights.VBO       = streamVBO;
        data += numBlends * sizeof(FLOAT);

        if (thisFVF & WINED3DFVF_LASTBETA_UBYTE4) {
            strided->u.s.blendMatrixIndices.lpData = data;
            strided->u.s.blendMatrixIndices.dwType  = WINED3DDECLTYPE_UBYTE4;
            strided->u.s.blendMatrixIndices.dwStride= stride;
            strided->u.s.blendMatrixIndices.VBO     = streamVBO;
            data += sizeof(DWORD);
        }
    }

    /* Normal is always 3 floats */
    if (thisFVF & WINED3DFVF_NORMAL) {
        strided->u.s.normal.lpData    = data;
        strided->u.s.normal.dwType    = WINED3DDECLTYPE_FLOAT3;
        strided->u.s.normal.dwStride  = stride;
        strided->u.s.normal.VBO     = streamVBO;
        data += 3 * sizeof(FLOAT);
    }

    /* Pointsize is a single float */
    if (thisFVF & WINED3DFVF_PSIZE) {
        strided->u.s.pSize.lpData    = data;
        strided->u.s.pSize.dwType    = WINED3DDECLTYPE_FLOAT1;
        strided->u.s.pSize.dwStride  = stride;
        strided->u.s.pSize.VBO       = streamVBO;
        data += sizeof(FLOAT);
    }

    /* Diffuse is 4 unsigned bytes */
    if (thisFVF & WINED3DFVF_DIFFUSE) {
        strided->u.s.diffuse.lpData    = data;
        strided->u.s.diffuse.dwType    = WINED3DDECLTYPE_SHORT4;
        strided->u.s.diffuse.dwStride  = stride;
        strided->u.s.diffuse.VBO       = streamVBO;
        data += sizeof(DWORD);
    }

    /* Specular is 4 unsigned bytes */
    if (thisFVF & WINED3DFVF_SPECULAR) {
        strided->u.s.specular.lpData    = data;
        strided->u.s.specular.dwType    = WINED3DDECLTYPE_SHORT4;
        strided->u.s.specular.dwStride  = stride;
        strided->u.s.specular.VBO       = streamVBO;
        data += sizeof(DWORD);
    }

    /* Texture coords */
    numTextures   = (thisFVF & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
    coordIdxInfo  = (thisFVF & 0x00FF0000) >> 16; /* 16 is from definition of WINED3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */

    /* numTextures indicates the number of texture coordinates supplied */
    /* However, the first set may not be for stage 0 texture - it all   */
    /*   depends on WINED3DTSS_TEXCOORDINDEX.                           */
    /* The number of bytes for each coordinate set is based off         */
    /*   WINED3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits              */

    /* So, for each supplied texture extract the coords */
    for (textureNo = 0; textureNo < numTextures; ++textureNo) {

        strided->u.s.texCoords[textureNo].lpData    = data;
        strided->u.s.texCoords[textureNo].dwType    = WINED3DDECLTYPE_FLOAT1;
        strided->u.s.texCoords[textureNo].dwStride  = stride;
        strided->u.s.texCoords[textureNo].VBO       = streamVBO;
        numCoords[textureNo] = coordIdxInfo & 0x03;

        /* Always one set */
        data += sizeof(float);
        if (numCoords[textureNo] != WINED3DFVF_TEXTUREFORMAT1) {
            strided->u.s.texCoords[textureNo].dwType = WINED3DDECLTYPE_FLOAT2;
            data += sizeof(float);
            if (numCoords[textureNo] != WINED3DFVF_TEXTUREFORMAT2) {
                strided->u.s.texCoords[textureNo].dwType = WINED3DDECLTYPE_FLOAT3;
                data += sizeof(float);
                if (numCoords[textureNo] != WINED3DFVF_TEXTUREFORMAT3) {
                    strided->u.s.texCoords[textureNo].dwType = WINED3DDECLTYPE_FLOAT4;
                    data += sizeof(float);
                }
            }
        }
        coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
    }
}

void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *strided, LONG BaseVertexIndex, BOOL *fixup) {

    short         LoopThroughTo = 0;
    short         nStream;
    GLint         streamVBO = 0;

    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    /* OK, Now to setup the data locations
       For the non-created vertex shaders, the VertexShader var holds the real
          FVF and only stream 0 matters
       For the created vertex shaders, there is an FVF per stream              */
    if (!This->stateBlock->streamIsUP && !(This->stateBlock->vertexShader == NULL)) {
        LoopThroughTo = MAX_STREAMS;
    } else {
        LoopThroughTo = 1;
    }

    /* Work through stream by stream */
    for (nStream=0; nStream<LoopThroughTo; ++nStream) {
        DWORD  stride  = This->stateBlock->streamStride[nStream];
        BYTE  *data    = NULL;
        DWORD  thisFVF = 0;

        /* Skip empty streams */
        if (This->stateBlock->streamSource[nStream] == NULL) continue;

        /* Retrieve appropriate FVF */
        if (LoopThroughTo == 1) { /* Use FVF, not vertex shader */
            thisFVF = This->stateBlock->fvf;
            /* Handle memory passed directly as well as vertex buffers */
            if (This->stateBlock->streamIsUP) {
                streamVBO = 0;
                data    = (BYTE *)This->stateBlock->streamSource[nStream];
            } else {
                IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[nStream]);
                /* GetMemory binds the VBO */
                data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[nStream], 0, &streamVBO);
                if(fixup) {
                    if(streamVBO != 0 ) *fixup = TRUE;
                }
            }
        } else {
#if 0 /* TODO: Vertex shader support */
            thisFVF = This->stateBlock->vertexShaderDecl->fvf[nStream];
            data    = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[nStream], 0);
#endif
        }
        VTRACE(("FVF for stream %d is %lx\n", nStream, thisFVF));
        if (thisFVF == 0) continue;

        /* Now convert the stream into pointers */

        /* Shuffle to the beginning of the vertexes to render and index from there */
        data = data + (BaseVertexIndex * stride);

        primitiveConvertFVFtoOffset(thisFVF, stride, data, strided, streamVBO);
    }
}

#if 0 /* TODO: Software Shaders */
/* Draw a single vertex using this information */
static void draw_vertex(IWineD3DDevice *iface,                         /* interface    */
                 BOOL isXYZ,    float x, float y, float z, float rhw,  /* xyzn position*/
                 BOOL isNormal, float nx, float ny, float nz,          /* normal       */
                 BOOL isDiffuse, float *dRGBA,                         /* 1st   colors */
                 BOOL isSpecular, float *sRGB,                         /* 2ndry colors */
                 BOOL isPtSize, float ptSize,                       /* pointSize    */
                 WINED3DVECTOR_4 *texcoords, int *numcoords)        /* texture info */
{
    unsigned int textureNo;
    float s, t, r, q;
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    /* Diffuse -------------------------------- */
    if (isDiffuse) {
        glColor4fv(dRGBA);
        VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n", dRGBA[0], dRGBA[1], dRGBA[2], dRGBA[3]));
    }

    /* Specular Colour ------------------------------------------*/
    if (isSpecular) {
        if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
          GL_EXTCALL(glSecondaryColor3fvEXT(sRGB));
          VTRACE(("glSecondaryColor4f: r,g,b=%f,%f,%f\n", sRGB[0], sRGB[1], sRGB[2]));
        } else {
	  VTRACE(("Specular color extensions not supplied\n"));
	}
    }

    /* Normal -------------------------------- */
    if (isNormal) {
        VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
        glNormal3f(nx, ny, nz);
    }

    /* Point Size ----------------------------------------------*/
    if (isPtSize) {

        /* no such functionality in the fixed function GL pipeline */
        FIXME("Cannot change ptSize here in openGl\n");
    }

    /* Texture coords --------------------------- */
    for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {

        if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
            FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
            continue ;
        }

        /* Query tex coords */
        if (This->stateBlock->textures[textureNo] != NULL) {

            int    coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
            if (coordIdx >= MAX_TEXTURES) {
                VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
                continue;
            } else if (numcoords[coordIdx] == 0) {
                TRACE("tex: %d - Skipping tex coords, as no data supplied or no coords supplied\n", textureNo);
                continue;
            } else {

                /* Initialize vars */
                s = 0.0f;
                t = 0.0f;
                r = 0.0f;
                q = 0.0f;

                switch (numcoords[coordIdx]) {
                case 4: q = texcoords[coordIdx].w; /* drop through */
                case 3: r = texcoords[coordIdx].z; /* drop through */
                case 2: t = texcoords[coordIdx].y; /* drop through */
                case 1: s = texcoords[coordIdx].x;
                }

                switch (numcoords[coordIdx]) {   /* Supply the provided texture coords */
                case WINED3DTTFF_COUNT1:
                    VTRACE(("tex:%d, s=%f\n", textureNo, s));
                    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                        GLMULTITEXCOORD1F(textureNo, s);
                    } else {
                        glTexCoord1f(s);
                    }
                    break;
                case WINED3DTTFF_COUNT2:
                    VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
                    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                        GLMULTITEXCOORD2F(textureNo, s, t);
                    } else {
                        glTexCoord2f(s, t);
                    }
                    break;
                case WINED3DTTFF_COUNT3:
                    VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
                    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                        GLMULTITEXCOORD3F(textureNo, s, t, r);
                    } else {
                        glTexCoord3f(s, t, r);
                    }
                    break;
                case WINED3DTTFF_COUNT4:
                    VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
                    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                        GLMULTITEXCOORD4F(textureNo, s, t, r, q);
                    } else {
                        glTexCoord4f(s, t, r, q);
                    }
                    break;
                default:
                    FIXME("Should not get here as numCoords should be 0->4 (%x)!\n", numcoords[coordIdx]);
                }
            }
        }
    } /* End of textures */

    /* Position -------------------------------- */
    if (isXYZ) {
        if (1.0f == rhw || rhw < 0.00001f) {
            VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
            glVertex3f(x, y, z);
        } else {
            /* Cannot optimize by dividing through by rhw as rhw is required
               later for perspective in the GL pipeline for vertex shaders   */
            VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
            glVertex4f(x,y,z,rhw);
        }
    }
}
#endif /* TODO: Software shaders */

/* This should match any arrays loaded in loadNumberedArrays. */
/* TODO: Only load / unload arrays if we have to. */
static void unloadNumberedArrays(IWineD3DDevice *iface) {
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    /* disable any attribs (this is the same for both GLSL and ARB modes) */
    GLint maxAttribs;
    int i;

    /* Leave all the attribs disabled */
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
    /* MESA does not support it right not */
    if (glGetError() != GL_NO_ERROR)
        maxAttribs = 16;
    for (i = 0; i < maxAttribs; ++i) {
        GL_EXTCALL(glDisableVertexAttribArrayARB(i));
        checkGLcall("glDisableVertexAttribArrayARB(reg);");
    }
}

/* TODO: Only load / unload arrays if we have to. */
static void loadNumberedArrays(
    IWineD3DDevice *iface,
    IWineD3DVertexShader *shader,
    WineDirect3DVertexStridedData *strided) {

    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
    int i;

    for (i = 0; i < MAX_ATTRIBS; i++) {

        if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
            continue;

        TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);

        if(curVBO != strided->u.input[i].VBO) {
            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
            checkGLcall("glBindBufferARB");
            curVBO = strided->u.input[i].VBO;
        }
        GL_EXTCALL(glVertexAttribPointerARB(i,
                        WINED3D_ATR_SIZE(strided->u.input[i].dwType),
                        WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
                        WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
                        strided->u.input[i].dwStride,
                        strided->u.input[i].lpData));
        GL_EXTCALL(glEnableVertexAttribArrayARB(i));
   }
}

/* This should match any arrays loaded in loadVertexData. */
/* TODO: Only load / unload arrays if we have to. */
static void unloadVertexData(IWineD3DDevice *iface) {
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    int texture_idx;

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
        glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
    }
    for (texture_idx = 0; texture_idx < GL_LIMITS(textures); ++texture_idx) {
        GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
}

/* TODO: Only load / unload arrays if we have to. */
static void loadVertexData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd) {
    unsigned int textureNo   = 0;
    unsigned int texture_idx = 0;
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;

    TRACE("Using fast vertex array code\n");
    /* Blend Data ---------------------------------------------- */
    if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
        (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {


        if (GL_SUPPORT(ARB_VERTEX_BLEND)) {

#if 1
            glEnableClientState(GL_WEIGHT_ARRAY_ARB);
            checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
#endif

            TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
                sd->u.s.blendWeights.lpData, sd->u.s.blendWeights.dwStride);
            /* FIXME("TODO\n");*/
            /* Note dwType == float3 or float4 == 2 or 3 */

#if 0
            /* with this on, the normals appear to be being modified,
               but the vertices aren't being translated as they should be
               Maybe the world matrix aren't being setup properly? */
            glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1);
#endif


            VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
                WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
                sd->u.s.blendWeights.dwStride,
                sd->u.s.blendWeights.lpData));

            if(curVBO != sd->u.s.blendWeights.VBO) {
                GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
                checkGLcall("glBindBufferARB");
                curVBO = sd->u.s.blendWeights.VBO;
            }

            GL_EXTCALL(glWeightPointerARB)(
                WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
                WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
                sd->u.s.blendWeights.dwStride,
                sd->u.s.blendWeights.lpData);

            checkGLcall("glWeightPointerARB");

            if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
                static BOOL showfixme = TRUE;
                if(showfixme){
                    FIXME("blendMatrixIndices support\n");
                    showfixme = FALSE;
                }
            }

        } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
            /* FIXME("TODO\n");*/
#if 0

            GL_EXTCALL(glVertexWeightPointerEXT)(
                WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
                WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
                sd->u.s.blendWeights.dwStride,
                sd->u.s.blendWeights.lpData);
            checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
            glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
            checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
#endif

        } else {
            /* TODO: support blends in fixupVertices */
            FIXME("unsupported blending in openGl\n");
        }
    } else {
        if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
#if 0    /* TODO: Vertex blending */
            glDisable(GL_VERTEX_BLEND_ARB);
#endif
            TRACE("ARB_VERTEX_BLEND\n");
        } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
            TRACE(" EXT_VERTEX_WEIGHTING\n");
            glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
            checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");

        }
    }

#if 0 /* FOG  ----------------------------------------------*/
    if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
        /* TODO: fog*/
    if (GL_SUPPORT(EXT_FOG_COORD) {
             glEnableClientState(GL_FOG_COORDINATE_EXT);
            (GL_EXTCALL)(FogCoordPointerEXT)(
                WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
                sd->u.s.fog.dwStride,
                sd->u.s.fog.lpData);
        } else {
            /* don't bother falling back to 'slow' as we don't support software FOG yet. */
            /* FIXME: fixme once */
            TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
        }
    } else {
        if (GL_SUPPRT(EXT_FOR_COORD) {
             /* make sure fog is disabled */
             glDisableClientState(GL_FOG_COORDINATE_EXT);
        }
    }
#endif

#if 0 /* tangents  ----------------------------------------------*/
    if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
        sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
        /* TODO: tangents*/
        if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
            if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
                glEnable(GL_TANGENT_ARRAY_EXT);
                (GL_EXTCALL)(TangentPointerEXT)(
                    WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
                    sd->u.s.tangent.dwStride,
                    sd->u.s.tangent.lpData);
            } else {
                    glDisable(GL_TANGENT_ARRAY_EXT);
            }
            if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
                    glEnable(GL_BINORMAL_ARRAY_EXT);
                    (GL_EXTCALL)(BinormalPointerEXT)(
                        WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
                        sd->u.s.binormal.dwStride,
                        sd->u.s.binormal.lpData);
            } else{
                    glDisable(GL_BINORMAL_ARRAY_EXT);
            }

        } else {
            /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
            /* FIXME: fixme once */
            TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
        }
    } else {
        if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
             /* make sure fog is disabled */
             glDisable(GL_TANGENT_ARRAY_EXT);
             glDisable(GL_BINORMAL_ARRAY_EXT);
        }
    }
#endif

    /* Point Size ----------------------------------------------*/
    if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {

        /* no such functionality in the fixed function GL pipeline */
        TRACE("Cannot change ptSize here in openGl\n");
        /* TODO: Implement this function in using shaders if they are available */

    }

    /* Vertex Pointers -----------------------------------------*/
    if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
        /* Note dwType == float3 or float4 == 2 or 3 */
        VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
                sd->u.s.position.dwStride,
                sd->u.s.position.dwType + 1,
                sd->u.s.position.lpData));

        if(curVBO != sd->u.s.position.VBO) {
            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
            checkGLcall("glBindBufferARB");
            curVBO = sd->u.s.position.VBO;
        }

        /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
           handling for rhw mode should not impact screen position whereas in GL it does.
           This may  result in very slightly distored textures in rhw mode, but
           a very minimal different. There's always the other option of
           fixing the view matrix to prevent w from having any effect

           This only applies to user pointer sources, in VBOs the vertices are fixed up
         */
        if(sd->u.s.position.VBO == 0) {
            glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
                WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
                sd->u.s.position.dwStride, sd->u.s.position.lpData);
        } else {
            glVertexPointer(
                WINED3D_ATR_SIZE(sd->u.s.position.dwType),
                WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
                sd->u.s.position.dwStride, sd->u.s.position.lpData);
        }
        checkGLcall("glVertexPointer(...)");
        glEnableClientState(GL_VERTEX_ARRAY);
        checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");

    } else {
        glDisableClientState(GL_VERTEX_ARRAY);
        checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
    }

    /* Normals -------------------------------------------------*/
    if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
        /* Note dwType == float3 or float4 == 2 or 3 */
        VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
                sd->u.s.normal.dwStride,
                sd->u.s.normal.lpData));
        if(curVBO != sd->u.s.normal.VBO) {
            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
            checkGLcall("glBindBufferARB");
            curVBO = sd->u.s.normal.VBO;
        }
        glNormalPointer(
            WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
            sd->u.s.normal.dwStride,
            sd->u.s.normal.lpData);
        checkGLcall("glNormalPointer(...)");
        glEnableClientState(GL_NORMAL_ARRAY);
        checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");

    } else {
        glDisableClientState(GL_NORMAL_ARRAY);
        checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
        glNormal3f(0, 0, 1);
        checkGLcall("glNormal3f(0, 0, 1)");
    }

    /* Diffuse Colour --------------------------------------------*/
    /*  WARNING: Data here MUST be in RGBA format, so cannot      */
    /*     go directly into fast mode from app pgm, because       */
    /*     directx requires data in BGRA format.                  */
    /* currently fixupVertices swizels the format, but this isn't */
    /* very practical when using VBOS                             */
    /* NOTE: Unless we write a vertex shader to swizel the colour */
    /* , or the user doesn't care and wants the speed advantage   */

    if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
        /* Note dwType == float3 or float4 == 2 or 3 */
        VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
                sd->u.s.diffuse.dwStride,
                sd->u.s.diffuse.lpData));

        if(curVBO != sd->u.s.diffuse.VBO) {
            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
            checkGLcall("glBindBufferARB");
            curVBO = sd->u.s.diffuse.VBO;
        }
        glColorPointer(4, GL_UNSIGNED_BYTE,
                       sd->u.s.diffuse.dwStride,
                       sd->u.s.diffuse.lpData);
        checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
        glEnableClientState(GL_COLOR_ARRAY);
        checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");

    } else {
        glDisableClientState(GL_COLOR_ARRAY);
        checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        checkGLcall("glColor4f(1, 1, 1, 1)");
    }

    /* Specular Colour ------------------------------------------*/
    if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
        TRACE("setting specular colour\n");
        /* Note dwType == float3 or float4 == 2 or 3 */
        VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
                sd->u.s.specular.dwStride,
                sd->u.s.specular.lpData));
        if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
            if(curVBO != sd->u.s.specular.VBO) {
                GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
                checkGLcall("glBindBufferARB");
                curVBO = sd->u.s.specular.VBO;
            }
            GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
                                                   sd->u.s.specular.dwStride,
                                                   sd->u.s.specular.lpData);
            vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
            glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
            vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
        } else {

        /* Missing specular color is not critical, no warnings */
        VTRACE(("Specular colour is not supported in this GL implementation\n"));
        }

    } else {
        if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {

            glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
            checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
            GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
            checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
        } else {

            /* Missing specular color is not critical, no warnings */
            VTRACE(("Specular colour is not supported in this GL implementation\n"));
        }
    }

    /* Texture coords -------------------------------------------*/

    for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
        /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
        /* Abort if we don't support the extension. */
        if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
            FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
            continue;
        }

        if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]*/ TRUE) {
            /* Select the correct texture stage */
            GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
        }

        if (This->stateBlock->textures[textureNo] != NULL) {
            int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];

            if (coordIdx >= MAX_TEXTURES) {
                VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));

            } else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
                VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));

            } else {
                TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
                      textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
                if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
                    GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
                    checkGLcall("glBindBufferARB");
                    curVBO = sd->u.s.texCoords[coordIdx].VBO;
                }
                /* The coords to supply depend completely on the fvf / vertex shader */
                glTexCoordPointer(
                    WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
                    WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
                    sd->u.s.texCoords[coordIdx].dwStride,
                    sd->u.s.texCoords[coordIdx].lpData);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            }
        } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
        }
        if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]*/ TRUE) ++texture_idx;
    }
    if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
        for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
            GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
        }
    }
}

static void drawStridedFast(IWineD3DDevice *iface,UINT numberOfVertices, GLenum glPrimitiveType,
                     const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    if (idxData != NULL /* This crashes sometimes!*/) {
        TRACE("(%p) : glElements(%x, %d, %d, ...)\n", This, glPrimitiveType, numberOfVertices, minIndex);
        idxData = idxData == (void *)-1 ? NULL : idxData;
#if 1
#if 0
        glIndexPointer(idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idxSize, startIdx);
        glEnableClientState(GL_INDEX_ARRAY);
#endif
        glDrawElements(glPrimitiveType, numberOfVertices, idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
                     (const char *)idxData+(idxSize * startIdx));
#else /* using drawRangeElements may be faster */

        glDrawRangeElements(glPrimitiveType, minIndex, minIndex + numberOfVertices - 1, numberOfVertices,
                      idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
                      (const char *)idxData+(idxSize * startIdx));
#endif
        checkGLcall("glDrawRangeElements");

    } else {

        /* Note first is now zero as we shuffled along earlier */
        TRACE("(%p) : glDrawArrays(%x, 0, %d)\n", This, glPrimitiveType, numberOfVertices);
        glDrawArrays(glPrimitiveType, 0, numberOfVertices);
        checkGLcall("glDrawArrays");

    }

    return;
}

/*
 * Actually draw using the supplied information.
 * Slower GL version which extracts info about each vertex in turn
 */
	
static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd,
                     UINT NumVertexes, GLenum glPrimType,
                     const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {

    unsigned int               textureNo    = 0;
    unsigned int               texture_idx  = 0;
    const short               *pIdxBufS     = NULL;
    const long                *pIdxBufL     = NULL;
    LONG                       SkipnStrides = 0;
    LONG                       vx_index;
    float x  = 0.0f, y  = 0.0f, z = 0.0f;  /* x,y,z coordinates          */
    float nx = 0.0f, ny = 0.0, nz = 0.0f;  /* normal x,y,z coordinates   */
    float rhw = 0.0f;                      /* rhw                        */
    float ptSize = 0.0f;                   /* Point size                 */
    DWORD diffuseColor = 0xFFFFFFFF;       /* Diffuse Color              */
    DWORD specularColor = 0;               /* Specular Color             */
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    TRACE("Using slow vertex array code\n");

    /* Variable Initialization */
    if (idxData != NULL) {
        if (idxSize == 2) pIdxBufS = (const short *) idxData;
        else pIdxBufL = (const long *) idxData;
    }

    /* Start drawing in GL */
    VTRACE(("glBegin(%x)\n", glPrimType));
    glBegin(glPrimType);

    /* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
     * Guess it's not necessary(we crash then anyway) and would only eat CPU time
     */

    /* For each primitive */
    for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {

        /* Initialize diffuse color */
        diffuseColor = 0xFFFFFFFF;

        /* For indexed data, we need to go a few more strides in */
        if (idxData != NULL) {

            /* Indexed so work out the number of strides to skip */
            if (idxSize == 2) {
                VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
                SkipnStrides = pIdxBufS[startIdx + vx_index];
            } else {
                VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
                SkipnStrides = pIdxBufL[startIdx + vx_index];
            }
        }

        /* Position Information ------------------ */
        if (sd->u.s.position.lpData != NULL) {

            float *ptrToCoords = (float *)(sd->u.s.position.lpData + (SkipnStrides * sd->u.s.position.dwStride));
            x = ptrToCoords[0];
            y = ptrToCoords[1];
            z = ptrToCoords[2];
            rhw = 1.0;
            VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));

            /* RHW follows, only if transformed, ie 4 floats were provided */
            if (sd->u.s.position_transformed) {
                rhw = ptrToCoords[3];
                VTRACE(("rhw=%f\n", rhw));
            }
        }

        /* Blending data -------------------------- */
        if (sd->u.s.blendWeights.lpData != NULL) {
            /* float *ptrToCoords = (float *)(sd->u.s.blendWeights.lpData + (SkipnStrides * sd->u.s.blendWeights.dwStride)); */
            FIXME("Blending not supported yet\n");

            if (sd->u.s.blendMatrixIndices.lpData != NULL) {
                /*DWORD *ptrToCoords = (DWORD *)(sd->u.s.blendMatrixIndices.lpData + (SkipnStrides * sd->u.s.blendMatrixIndices.dwStride));*/
            }
        }

        /* Vertex Normal Data (untransformed only)- */
        if (sd->u.s.normal.lpData != NULL) {

            float *ptrToCoords = (float *)(sd->u.s.normal.lpData + (SkipnStrides * sd->u.s.normal.dwStride));
            nx = ptrToCoords[0];
            ny = ptrToCoords[1];
            nz = ptrToCoords[2];
            VTRACE(("nx,ny,nz=%f,%f,%f\n", nx, ny, nz));
        }

        /* Point Size ----------------------------- */
        if (sd->u.s.pSize.lpData != NULL) {

            float *ptrToCoords = (float *)(sd->u.s.pSize.lpData + (SkipnStrides * sd->u.s.pSize.dwStride));
            ptSize = ptrToCoords[0];
            VTRACE(("ptSize=%f\n", ptSize));
            FIXME("No support for ptSize yet\n");
        }

        /* Diffuse -------------------------------- */
        if (sd->u.s.diffuse.lpData != NULL) {

            DWORD *ptrToCoords = (DWORD *)(sd->u.s.diffuse.lpData + (SkipnStrides * sd->u.s.diffuse.dwStride));
            diffuseColor = ptrToCoords[0];
            VTRACE(("diffuseColor=%lx\n", diffuseColor));
        }

        /* Specular  -------------------------------- */
        if (sd->u.s.specular.lpData != NULL) {

            DWORD *ptrToCoords = (DWORD *)(sd->u.s.specular.lpData + (SkipnStrides * sd->u.s.specular.dwStride));
            specularColor = ptrToCoords[0];
            VTRACE(("specularColor=%lx\n", specularColor));
        }

        /* Texture coords --------------------------- */
        for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {

            if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
                FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
                continue ;
            }

            /* Query tex coords */
            if (This->stateBlock->textures[textureNo] != NULL) {

                int    coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
                float *ptrToCoords = NULL;
                float  s = 0.0, t = 0.0, r = 0.0, q = 0.0;

                if (coordIdx > 7) {
                    VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
                    ++texture_idx;
                    continue;
                } else if (coordIdx < 0) {
                    FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
                    ++texture_idx;
                    continue;
                }

                ptrToCoords = (float *)(sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
                if (sd->u.s.texCoords[coordIdx].lpData == NULL) {
                    TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
                    ++texture_idx;
                    continue;
                } else {

                    int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == WINED3DDECLTYPE_FLOAT1 etc */

                    /* The coords to supply depend completely on the fvf / vertex shader */
                    switch (coordsToUse) {
                    case 4: q = ptrToCoords[3]; /* drop through */
                    case 3: r = ptrToCoords[2]; /* drop through */
                    case 2: t = ptrToCoords[1]; /* drop through */
                    case 1: s = ptrToCoords[0];
                    }

                    /* Projected is more 'fun' - Move the last coord to the 'q'
                          parameter (see comments under WINED3DTSS_TEXTURETRANSFORMFLAGS */
                    if ((This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] != WINED3DTTFF_DISABLE) &&
                        (This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {

                        if (This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED) {
                            switch (coordsToUse) {
                            case 0:  /* Drop Through */
                            case 1:
                                FIXME("WINED3DTTFF_PROJECTED but only zero or one coordinate?\n");
                                break;
                            case 2:
                                q = t;
                                t = 0.0;
                                coordsToUse = 4;
                                break;
                            case 3:
                                q = r;
                                r = 0.0;
                                coordsToUse = 4;
                                break;
                            case 4:  /* Nop here */
                                break;
                            default:
                                FIXME("Unexpected WINED3DTSS_TEXTURETRANSFORMFLAGS value of %d\n",
                                      This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED);
                            }
                        }
                    }

                    switch (coordsToUse) {   /* Supply the provided texture coords */
                    case WINED3DTTFF_COUNT1:
                        VTRACE(("tex:%d, s=%f\n", textureNo, s));
                        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                            GL_EXTCALL(glMultiTexCoord1fARB(texture_idx, s));
                        } else {
                            glTexCoord1f(s);
                        }
                        break;
                    case WINED3DTTFF_COUNT2:
                        VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
                        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                            GL_EXTCALL(glMultiTexCoord2fARB(texture_idx, s, t));
                        } else {
                            glTexCoord2f(s, t);
                        }
                        break;
                    case WINED3DTTFF_COUNT3:
                        VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
                        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                            GL_EXTCALL(glMultiTexCoord3fARB(texture_idx, s, t, r));
                        } else {
                            glTexCoord3f(s, t, r);
                        }
                        break;
                    case WINED3DTTFF_COUNT4:
                        VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
                        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
                            GL_EXTCALL(glMultiTexCoord4fARB(texture_idx, s, t, r, q));
                        } else {
                            glTexCoord4f(s, t, r, q);
                        }
                        break;
                    default:
                        FIXME("Should not get here as coordsToUse is two bits only (%x)!\n", coordsToUse);
                    }
                }
            }
            if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]*/TRUE) ++texture_idx;
        } /* End of textures */

        /* Diffuse -------------------------------- */
        if (sd->u.s.diffuse.lpData != NULL) {
	  glColor4ub(D3DCOLOR_B_R(diffuseColor),
		     D3DCOLOR_B_G(diffuseColor),
		     D3DCOLOR_B_B(diffuseColor),
		     D3DCOLOR_B_A(diffuseColor));
            VTRACE(("glColor4ub: r,g,b,a=%lu,%lu,%lu,%lu\n", 
                    D3DCOLOR_B_R(diffuseColor),
		    D3DCOLOR_B_G(diffuseColor),
		    D3DCOLOR_B_B(diffuseColor),
		    D3DCOLOR_B_A(diffuseColor)));
        } else {
            if (vx_index == 0) glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        }

        /* Specular ------------------------------- */
        if (sd->u.s.specular.lpData != NULL) {
            /* special case where the fog density is stored in the diffuse alpha channel */
            if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
              (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 )&&
              This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
                if(GL_SUPPORT(EXT_FOG_COORD)) {
                    GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
                } else {
                    static BOOL warned = FALSE;
                    if(!warned) {
                        /* TODO: Use the fog table code from old ddraw */
                        FIXME("Implement fog for transformed vertices in software\n");
                        warned = TRUE;
                    }
                }
            }

            VTRACE(("glSecondaryColor4ub: r,g,b=%lu,%lu,%lu\n", 
                    D3DCOLOR_B_R(specularColor), 
                    D3DCOLOR_B_G(specularColor), 
                    D3DCOLOR_B_B(specularColor)));
            if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
                GL_EXTCALL(glSecondaryColor3ubEXT)(
                           D3DCOLOR_B_R(specularColor),
                           D3DCOLOR_B_G(specularColor),
                           D3DCOLOR_B_B(specularColor));
            } else {
                /* Do not worry if specular colour missing and disable request */
                VTRACE(("Specular color extensions not supplied\n"));
            }
        } else {
            if (vx_index == 0) {
                if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
                    GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
                } else {
                    /* Do not worry if specular colour missing and disable request */
                    VTRACE(("Specular color extensions not supplied\n"));
                }
            }
        }

        /* Normal -------------------------------- */
        if (sd->u.s.normal.lpData != NULL) {
            VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
            glNormal3f(nx, ny, nz);
        } else {
            if (vx_index == 0) glNormal3f(0, 0, 1);
        }

        /* Position -------------------------------- */
        if (sd->u.s.position.lpData != NULL) {
            if (1.0f == rhw || ((rhw < eps) && (rhw > -eps))) {
                VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
                glVertex3f(x, y, z);
            } else {
                GLfloat w = 1.0 / rhw;
                VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
                glVertex4f(x*w, y*w, z*w, w);
            }
        }

        /* For non indexed mode, step onto next parts */
        if (idxData == NULL) {
            ++SkipnStrides;
        }
    }

    glEnd();
    checkGLcall("glEnd and previous calls");
}

#if 0 /* TODO: Software/Hardware vertex blending support */
/*
 * Draw with emulated vertex shaders
 * Note: strided data is uninitialized, as we need to pass the vertex
 *     shader directly as ordering irs yet
 */
void drawStridedSoftwareVS(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd,
                     int PrimitiveType, ULONG NumPrimitives,
                     const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {

    unsigned int               textureNo    = 0;
    GLenum                     glPrimType   = GL_POINTS;
    int                        NumVertexes  = NumPrimitives;
    const short               *pIdxBufS     = NULL;
    const long                *pIdxBufL     = NULL;
    LONG                       SkipnStrides = 0;
    LONG                       vx_index;
    float x  = 0.0f, y  = 0.0f, z = 0.0f;  /* x,y,z coordinates          */
    float rhw = 0.0f;                      /* rhw                        */
    float ptSize = 0.0f;                   /* Point size                 */
    D3DVECTOR_4 texcoords[8];              /* Texture Coords             */
    int   numcoords[8];                    /* Number of coords           */
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    IDirect3DVertexShaderImpl* vertexShader = NULL;

    TRACE("Using slow software vertex shader code\n");

    /* Variable Initialization */
    if (idxData != NULL) {
        if (idxSize == 2) pIdxBufS = (const short *) idxData;
        else pIdxBufL = (const long *) idxData;
    }

    /* Ok, Work out which primitive is requested and how many vertexes that will be */
    NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);

    /* Retrieve the VS information */
    vertexShader = (IWineD3DVertexShaderImp *)This->stateBlock->VertexShader;

    /* Start drawing in GL */
    VTRACE(("glBegin(%x)\n", glPrimType));
    glBegin(glPrimType);

    /* For each primitive */
    for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {

        /* For indexed data, we need to go a few more strides in */
        if (idxData != NULL) {

            /* Indexed so work out the number of strides to skip */
            if (idxSize == 2) {
                VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
                SkipnStrides = pIdxBufS[startIdx+vx_index];
            } else {
                VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
                SkipnStrides = pIdxBufL[startIdx+vx_index];
            }
        }

        /* Fill the vertex shader input */
        IDirect3DDeviceImpl_FillVertexShaderInputSW(This, vertexShader, SkipnStrides);

        /* Initialize the output fields to the same defaults as it would normally have */
        memset(&vertexShader->output, 0, sizeof(VSHADEROUTPUTDATA8));
        vertexShader->output.oD[0].x = 1.0;
        vertexShader->output.oD[0].y = 1.0;
        vertexShader->output.oD[0].z = 1.0;
        vertexShader->output.oD[0].w = 1.0;

        /* Now execute the vertex shader */
        IDirect3DVertexShaderImpl_ExecuteSW(vertexShader, &vertexShader->input, &vertexShader->output);

        /*
        TRACE_VECTOR(vertexShader->output.oPos);
        TRACE_VECTOR(vertexShader->output.oD[0]);
        TRACE_VECTOR(vertexShader->output.oD[1]);
        TRACE_VECTOR(vertexShader->output.oT[0]);
        TRACE_VECTOR(vertexShader->output.oT[1]);
        TRACE_VECTOR(vertexShader->input.V[0]);
        TRACE_VECTOR(vertexShader->data->C[0]);
        TRACE_VECTOR(vertexShader->data->C[1]);
        TRACE_VECTOR(vertexShader->data->C[2]);
        TRACE_VECTOR(vertexShader->data->C[3]);
        TRACE_VECTOR(vertexShader->data->C[4]);
        TRACE_VECTOR(vertexShader->data->C[5]);
        TRACE_VECTOR(vertexShader->data->C[6]);
        TRACE_VECTOR(vertexShader->data->C[7]);
        */

        /* Extract out the output */
        /* FIXME: Fog coords? */
        x = vertexShader->output.oPos.x;
        y = vertexShader->output.oPos.y;
        z = vertexShader->output.oPos.z;
        rhw = vertexShader->output.oPos.w;
        ptSize = vertexShader->output.oPts.x; /* Fixme - Is this right? */

        /** Update textures coords using vertexShader->output.oT[0->7] */
        memset(texcoords, 0x00, sizeof(texcoords));
        memset(numcoords, 0x00, sizeof(numcoords));
        for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
            if (This->stateBlock->textures[textureNo] != NULL) {
               texcoords[textureNo].x = vertexShader->output.oT[textureNo].x;
               texcoords[textureNo].y = vertexShader->output.oT[textureNo].y;
               texcoords[textureNo].z = vertexShader->output.oT[textureNo].z;
               texcoords[textureNo].w = vertexShader->output.oT[textureNo].w;
               if (This->stateBlock->texture_state[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] != WINED3DTTFF_DISABLE) {
                   numcoords[textureNo]    = This->stateBlock->texture_state[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & ~WINED3DTTFF_PROJECTED;
               } else {
                   switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->stateBlock->textures[textureNo])) {
                   case WINED3DRTYPE_TEXTURE:       numcoords[textureNo] = 2; break;
                   case WINED3DRTYPE_VOLUMETEXTURE: numcoords[textureNo] = 3; break;
                   default:                         numcoords[textureNo] = 4;
                   }
               }
            } else {
                numcoords[textureNo] = 0;
            }
        }

        /* Draw using this information */
        draw_vertex(iface,
                    TRUE, x, y, z, rhw,
                    TRUE, 0.0f, 0.0f, 1.0f,
                    TRUE, (float*) &vertexShader->output.oD[0],
                    TRUE, (float*) &vertexShader->output.oD[1],
                    FALSE, ptSize,         /* FIXME: Change back when supported */
                    texcoords, numcoords);

        /* For non indexed mode, step onto next parts */
        if (idxData == NULL) {
           ++SkipnStrides;
        }

    } /* for each vertex */

    glEnd();
    checkGLcall("glEnd and previous calls");
}

#endif

inline static void drawPrimitiveDrawStrided(
    IWineD3DDevice *iface,
    BOOL useVertexShaderFunction,
    BOOL usePixelShaderFunction,
    WineDirect3DVertexStridedData *dataLocations,
    UINT numberOfvertices,
    UINT numberOfIndicies,
    GLenum glPrimType,
    const void *idxData,
    short idxSize,
    int minIndex,
    long StartIdx,
    BOOL fixup) {

    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    BOOL useDrawStridedSlow;

    int startStride = idxData == NULL ? 0 : 
                      idxData == (void *) -1 ? 0 :
                      (idxSize == 2 ? *(((const short *) idxData) + StartIdx) : *((const int *) idxData) + StartIdx);
    int endStride = startStride;
    TRACE("begin Start stride %d, end stride %d, number of indices%d, number of vertices%d\n",
        startStride, endStride, numberOfIndicies, numberOfvertices);

/* Generate some fixme's if unsupported functionality is being used */
#define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
    /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
    if (!useVertexShaderFunction && (BUFFER_OR_DATA(blendMatrixIndices) || BUFFER_OR_DATA(blendWeights))) {
        FIXME("Blending data is only valid with vertex shaders %p %p\n",dataLocations->u.s.blendWeights.lpData,dataLocations->u.s.blendWeights.lpData);
    }
    if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
        FIXME("Tweening is only valid with vertex shaders\n");
    }
    if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
        FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
    }
    if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
        FIXME("Extended attributes are only valid with vertex shaders\n");
    }
#undef BUFFER_OR_DATA

    /* Fixed pipeline, no fixups required - load arrays */
    if (!useVertexShaderFunction &&
       ((dataLocations->u.s.pSize.lpData == NULL &&
         dataLocations->u.s.diffuse.lpData == NULL &&
         dataLocations->u.s.specular.lpData == NULL) ||
         fixup) ) {

        /* Load the vertex data using named arrays */
        TRACE("(%p) Loading vertex data\n", This);
        loadVertexData(iface, dataLocations);
        useDrawStridedSlow = FALSE;

    /* Shader pipeline - load attribute arrays */
    } else if(useVertexShaderFunction) {

        loadNumberedArrays(iface, This->stateBlock->vertexShader, dataLocations);
        useDrawStridedSlow = FALSE;

        /* We compile the shader here because we need the vertex declaration
         * in order to determine if we need to do any swizzling for D3DCOLOR
         * registers. If the shader is already compiled this call will do nothing. */
        IWineD3DVertexShader_CompileShader(This->stateBlock->vertexShader);
    /* Draw vertex by vertex */
    } else { 
        TRACE("Not loading vertex data\n");
        useDrawStridedSlow = TRUE;
    }

    /* Make any shaders active */
    This->shader_backend->shader_select(iface, usePixelShaderFunction, useVertexShaderFunction);

    /* Load any global constants/uniforms that may have been set by the application */
    This->shader_backend->shader_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction);

    /* Draw vertex-by-vertex */
    if (useDrawStridedSlow)
        drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType, idxData, idxSize, minIndex,  StartIdx);
    else
        drawStridedFast(iface, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx);

    /* Cleanup any shaders */
    This->shader_backend->shader_cleanup(usePixelShaderFunction, useVertexShaderFunction);

    /* Unload vertex data */
    if (useVertexShaderFunction) {
        unloadNumberedArrays(iface);
    } else {
        unloadVertexData(iface);
    }
}

inline void drawPrimitiveTraceDataLocations(
    WineDirect3DVertexStridedData *dataLocations) {

    /* Dump out what parts we have supplied */
    TRACE("Strided Data:\n");
    TRACE_STRIDED((dataLocations), position);
    TRACE_STRIDED((dataLocations), blendWeights);
    TRACE_STRIDED((dataLocations), blendMatrixIndices);
    TRACE_STRIDED((dataLocations), normal);
    TRACE_STRIDED((dataLocations), pSize);
    TRACE_STRIDED((dataLocations), diffuse);
    TRACE_STRIDED((dataLocations), specular);
    TRACE_STRIDED((dataLocations), texCoords[0]);
    TRACE_STRIDED((dataLocations), texCoords[1]);
    TRACE_STRIDED((dataLocations), texCoords[2]);
    TRACE_STRIDED((dataLocations), texCoords[3]);
    TRACE_STRIDED((dataLocations), texCoords[4]);
    TRACE_STRIDED((dataLocations), texCoords[5]);
    TRACE_STRIDED((dataLocations), texCoords[6]);
    TRACE_STRIDED((dataLocations), texCoords[7]);
    TRACE_STRIDED((dataLocations), position2);
    TRACE_STRIDED((dataLocations), normal2);
    TRACE_STRIDED((dataLocations), tangent);
    TRACE_STRIDED((dataLocations), binormal);
    TRACE_STRIDED((dataLocations), tessFactor);
    TRACE_STRIDED((dataLocations), fog);
    TRACE_STRIDED((dataLocations), depth);
    TRACE_STRIDED((dataLocations), sample);

    return;

}

static void check_fbo_status(IWineD3DDevice *iface) {
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    GLenum status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
    switch(status) {
        case GL_FRAMEBUFFER_COMPLETE_EXT: TRACE("FBO complete.\n"); break;
        default: TRACE("FBO status %#x.\n", status); break;
    }
}

static void depth_blt(IWineD3DDevice *iface, GLuint texture) {
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    GLint old_binding = 0;

    glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);

    glDisable(GL_CULL_FACE);
    glDisable(GL_BLEND);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_STENCIL_TEST);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);

    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
    glBindTexture(GL_TEXTURE_2D, texture);
    glEnable(GL_TEXTURE_2D);

    This->shader_backend->shader_select_depth_blt(iface);

    glBegin(GL_TRIANGLE_STRIP);
    glVertex2f(-1.0f, -1.0f);
    glVertex2f(1.0f, -1.0f);
    glVertex2f(-1.0f, 1.0f);
    glVertex2f(1.0f, 1.0f);
    glEnd();

    glBindTexture(GL_TEXTURE_2D, old_binding);

    glPopAttrib();
}

static void depth_copy(IWineD3DDevice *iface) {
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
    IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *)This->depthStencilBuffer;

    /* Only copy the depth buffer if there is one. */
    if (!depth_stencil) return;

    /* TODO: Make this work for modes other than FBO */
    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return;

    if (This->render_offscreen) {
        static GLuint tmp_texture = 0;
        GLint old_binding = 0;

        TRACE("Copying onscreen depth buffer to offscreen surface\n");

        if (!tmp_texture) {
            glGenTextures(1, &tmp_texture);
        }

        /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
         * directly on the FBO texture. That's because we need to flip. */
        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
        glBindTexture(GL_TEXTURE_2D, tmp_texture);
        glCopyTexImage2D(depth_stencil->glDescription.target,
                depth_stencil->glDescription.level,
                depth_stencil->glDescription.glFormatInternal,
                0,
                0,
                depth_stencil->currentDesc.Width,
                depth_stencil->currentDesc.Height,
                0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
        glBindTexture(GL_TEXTURE_2D, old_binding);

        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, This->fbo));
        checkGLcall("glBindFramebuffer()");
        depth_blt(iface, tmp_texture);
        checkGLcall("depth_blt");
    } else {
        TRACE("Copying offscreen surface to onscreen depth buffer\n");

        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
        checkGLcall("glBindFramebuffer()");
        depth_blt(iface, depth_stencil->glDescription.textureName);
        checkGLcall("depth_blt");
    }
}

/* Routine common to the draw primitive and draw indexed primitive routines */
void drawPrimitive(IWineD3DDevice *iface,
                   int PrimitiveType,
                   long NumPrimitives,
                   /* for Indexed: */
                   long  StartVertexIndex,
                   UINT  numberOfVertices,
                   long  StartIdx,
                   short idxSize,
                   const void *idxData,
                   int   minIndex,
                   WineDirect3DVertexStridedData *DrawPrimStrideData) {

    IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
    BOOL                          useVertexShaderFunction = FALSE;
    BOOL                          usePixelShaderFunction = FALSE;
    WineDirect3DVertexStridedData *dataLocations;
    IWineD3DSwapChainImpl         *swapchain;
    int                           i;
    BOOL                          fixup = FALSE;
    DWORD                         dirtyState, idx;
    BYTE                          shift;

    BOOL lighting_changed, lighting_original = FALSE;

    /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software - 
     * here simply check whether a shader was set, or the user disabled shaders */
    if (This->vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader && 
        ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL) 
        useVertexShaderFunction = TRUE;

    if (This->ps_selected_mode != SHADER_NONE && This->stateBlock->pixelShader &&
        ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function) 
        usePixelShaderFunction = TRUE;

    /* Invalidate the back buffer memory so LockRect will read it the next time */
    for(i = 0; i < IWineD3DDevice_GetNumberOfSwapChains(iface); i++) {
        IWineD3DDevice_GetSwapChain(iface, i, (IWineD3DSwapChain **) &swapchain);
        if(swapchain) {
            if(swapchain->backBuffer) ((IWineD3DSurfaceImpl *) swapchain->backBuffer[0])->Flags |= SFLAG_GLDIRTY;
            IWineD3DSwapChain_Release( (IWineD3DSwapChain *) swapchain);
        }
    }

    /* Ok, we will be updating the screen from here onwards so grab the lock */
    ENTER_GL();

    /* Apply dirty states */
    for(i=0; i < This->numDirtyEntries; i++) {
        dirtyState = This->dirtyArray[i];
        idx = dirtyState >> 5;
        shift = dirtyState & 0x1f;
        This->isStateDirty[idx] &= ~(1 << shift);
        StateTable[dirtyState].apply(dirtyState, This->stateBlock);
    }
    This->numDirtyEntries = 0; /* This makes the whole list clean */

    if (TRACE_ON(d3d_draw) && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
        check_fbo_status(iface);
    }

    if (This->depth_copy_state == WINED3D_DCS_COPY) {
        depth_copy(iface);
    }
    This->depth_copy_state = WINED3D_DCS_INITIAL;

    if(DrawPrimStrideData) {

        /* Note: this is a ddraw fixed-function code path */

        TRACE("================ Strided Input ===================\n");
        dataLocations = DrawPrimStrideData;
        drawPrimitiveTraceDataLocations(dataLocations);
        fixup = FALSE;
    }

    else if (This->stateBlock->vertexDecl || This->stateBlock->vertexShader) {

        /* Note: This is a fixed function or shader codepath.
         * This means it must handle both types of strided data.
         * Shaders must go through here to zero the strided data, even if they
         * don't set any declaration at all */

        TRACE("================ Vertex Declaration  ===================\n");
        dataLocations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dataLocations));
        if(!dataLocations) {
            ERR("Out of memory!\n");
            return;
        }

        if (This->stateBlock->vertexDecl != NULL ||
            ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration != NULL)            

            primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, 
                dataLocations, StartVertexIndex, &fixup);

    } else {

        /* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
         * It is reachable through d3d8, but only for fixed-function.
         * It will not work properly for shaders. */

        TRACE("================ FVF ===================\n");
        dataLocations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dataLocations));
        if(!dataLocations) {
            ERR("Out of memory!\n");
            return;
        }
        primitiveConvertToStridedData(iface, dataLocations, StartVertexIndex, &fixup);
        drawPrimitiveTraceDataLocations(dataLocations);
    }

    /* Setup transform matrices and sort out */
    primitiveInitState(iface, dataLocations, useVertexShaderFunction, &lighting_changed, &lighting_original);

    /* Now initialize the materials state */
    init_materials(iface, (dataLocations->u.s.diffuse.lpData != NULL || dataLocations->u.s.diffuse.VBO != 0));

    {
        GLenum glPrimType;
        /* Ok, Work out which primitive is requested and how many vertexes that
           will be                                                              */
        UINT calculatedNumberOfindices = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
        if (numberOfVertices == 0 )
            numberOfVertices = calculatedNumberOfindices;

        drawPrimitiveDrawStrided(iface, useVertexShaderFunction, usePixelShaderFunction,
            dataLocations, numberOfVertices, calculatedNumberOfindices, glPrimType,
            idxData, idxSize, minIndex, StartIdx, fixup);
    }

    if(!DrawPrimStrideData) HeapFree(GetProcessHeap(), 0, dataLocations);

    /* If vertex shaders or no normals, restore previous lighting state */
    if (lighting_changed) {
        if (lighting_original) glEnable(GL_LIGHTING);
        else glDisable(GL_LIGHTING);
        TRACE("Restored lighting to original state\n");
    }

    /* Finshed updating the screen, restore lock */
    LEAVE_GL();
    TRACE("Done all gl drawing\n");

    /* Diagnostics */
#ifdef SHOW_FRAME_MAKEUP
    {
        static long int primCounter = 0;
        /* NOTE: set primCounter to the value reported by drawprim 
           before you want to to write frame makeup to /tmp */
        if (primCounter >= 0) {
            WINED3DLOCKED_RECT r;
            char buffer[80];
            IWineD3DSurface_LockRect(This->renderTarget, &r, NULL, WINED3DLOCK_READONLY);
            sprintf(buffer, "/tmp/backbuffer_%d.tga", primCounter);
            TRACE("Saving screenshot %s\n", buffer);
            IWineD3DSurface_SaveSnapshot(This->renderTarget, buffer);
            IWineD3DSurface_UnlockRect(This->renderTarget);

#ifdef SHOW_TEXTURE_MAKEUP
           {
            IWineD3DSurface *pSur;
            int textureNo;
            for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
                if (This->stateBlock->textures[textureNo] != NULL) {
                    sprintf(buffer, "/tmp/texture_%p_%d_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo);
                    TRACE("Saving texture %s\n", buffer);
                    if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) {
                            IWineD3DTexture_GetSurfaceLevel((IWineD3DTexture *)This->stateBlock->textures[textureNo], 0, &pSur);
                            IWineD3DSurface_SaveSnapshot(pSur, buffer);
                            IWineD3DSurface_Release(pSur);
                    } else  {
                        FIXME("base Texture isn't of type texture %d\n", IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]));
                    }
                }
            }
           }
#endif
        }
        TRACE("drawprim #%d\n", primCounter);
        ++primCounter;
    }
#endif
}
