wined3d: Move applying the gl stream sources to the state table.
This commit is contained in:
parent
d3d030eb88
commit
d5f18e6a63
|
@ -26,7 +26,6 @@
|
|||
#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>
|
||||
|
@ -596,436 +595,6 @@ static void draw_vertex(IWineD3DDevice *iface, /* interf
|
|||
}
|
||||
#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 + This->stateBlock->baseVertexIndex * strided->u.input[i].dwStride));
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride, 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 + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride));
|
||||
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
|
||||
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.fog.dwStride);
|
||||
} 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 + This->stateBlock->baseVertexIndex * sd->u.s.tangent.dwStride);
|
||||
} 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 + This->stateBlock->baseVertexIndex * sd->u.s.binormal.dwStride);
|
||||
} 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 + This->stateBlock->baseVertexIndex * sd->u.s.position.dwStride);
|
||||
} 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 + This->stateBlock->baseVertexIndex * sd->u.s.position.dwStride);
|
||||
}
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.normal.dwStride);
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.diffuse.dwStride);
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.specular.dwStride);
|
||||
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 + This->stateBlock->baseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride);
|
||||
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, ULONG startVertex) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
@ -1535,18 +1104,9 @@ inline static void drawPrimitiveDrawStrided(
|
|||
const void *idxData,
|
||||
short idxSize,
|
||||
int minIndex,
|
||||
long StartIdx,
|
||||
BOOL fixup) {
|
||||
long StartIdx) {
|
||||
|
||||
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
|
||||
|
@ -1565,34 +1125,6 @@ inline static void drawPrimitiveDrawStrided(
|
|||
}
|
||||
#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);
|
||||
|
||||
|
@ -1600,20 +1132,13 @@ inline static void drawPrimitiveDrawStrided(
|
|||
This->shader_backend->shader_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction);
|
||||
|
||||
/* Draw vertex-by-vertex */
|
||||
if (useDrawStridedSlow)
|
||||
if (This->useDrawStridedSlow)
|
||||
drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx, baseVIndex);
|
||||
else
|
||||
drawStridedFast(iface, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx, baseVIndex);
|
||||
|
||||
/* Cleanup any shaders */
|
||||
This->shader_backend->shader_cleanup(usePixelShaderFunction, useVertexShaderFunction);
|
||||
|
||||
/* Unload vertex data */
|
||||
if (useVertexShaderFunction) {
|
||||
unloadNumberedArrays(iface);
|
||||
} else {
|
||||
unloadVertexData(iface);
|
||||
}
|
||||
}
|
||||
|
||||
inline void drawPrimitiveTraceDataLocations(
|
||||
|
@ -1760,7 +1285,6 @@ void drawPrimitive(IWineD3DDevice *iface,
|
|||
BOOL usePixelShaderFunction = FALSE;
|
||||
IWineD3DSwapChainImpl *swapchain;
|
||||
int i;
|
||||
BOOL fixup;
|
||||
DWORD dirtyState, idx;
|
||||
BYTE shift;
|
||||
|
||||
|
@ -1795,7 +1319,7 @@ void drawPrimitive(IWineD3DDevice *iface,
|
|||
StateTable[dirtyState].apply(dirtyState, This->stateBlock);
|
||||
}
|
||||
This->numDirtyEntries = 0; /* This makes the whole list clean */
|
||||
fixup = This->streamFixedUp;
|
||||
|
||||
|
||||
if (TRACE_ON(d3d_draw) && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
|
||||
check_fbo_status(iface);
|
||||
|
@ -1819,7 +1343,7 @@ void drawPrimitive(IWineD3DDevice *iface,
|
|||
|
||||
drawPrimitiveDrawStrided(iface, useVertexShaderFunction, usePixelShaderFunction,
|
||||
&This->strided_streams, StartVertexIndex, numberOfVertices, calculatedNumberOfindices, glPrimType,
|
||||
idxData, idxSize, minIndex, StartIdx, fixup);
|
||||
idxData, idxSize, minIndex, StartIdx);
|
||||
}
|
||||
|
||||
/* Finshed updating the screen, restore lock */
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
|
||||
|
||||
#define GLINFO_LOCATION ((IWineD3DImpl *)(stateblock->wineD3DDevice->wineD3D))->gl_info
|
||||
|
||||
|
@ -1511,6 +1512,8 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
|
||||
}
|
||||
|
||||
static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd);
|
||||
|
||||
static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
||||
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
|
||||
DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
|
||||
|
@ -1678,6 +1681,15 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
|
||||
transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock);
|
||||
}
|
||||
|
||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_VDECL) && stateblock->wineD3DDevice->namedArraysLoaded) {
|
||||
/* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
|
||||
* source. Call loadVertexData directly because there is no need to reparse the vertex declaration
|
||||
* and do all the things linked to it
|
||||
* TODO: Tidy that up to reload only the arrays of the changed unit
|
||||
*/
|
||||
loadVertexData(stateblock, &stateblock->wineD3DDevice->strided_streams);
|
||||
}
|
||||
}
|
||||
|
||||
static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
||||
|
@ -2005,14 +2017,439 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
|
|||
}
|
||||
}
|
||||
|
||||
/* This should match any arrays loaded in loadVertexData.
|
||||
* stateblock impl is required for GL_SUPPORT
|
||||
* TODO: Only load / unload arrays if we have to.
|
||||
*/
|
||||
static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* This should match any arrays loaded in loadNumberedArrays
|
||||
* TODO: Only load / unload arrays if we have to.
|
||||
*/
|
||||
static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
|
||||
/* 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);");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
|
||||
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 + stateblock->baseVertexIndex * strided->u.input[i].dwStride));
|
||||
GL_EXTCALL(glEnableVertexAttribArrayARB(i));
|
||||
}
|
||||
}
|
||||
|
||||
/* Used from 2 different functions, and too big to justify making it inlined */
|
||||
static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
|
||||
unsigned int textureNo = 0;
|
||||
unsigned int texture_idx = 0;
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride, 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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride));
|
||||
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
|
||||
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.fog.dwStride);
|
||||
} 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 + stateblock->baseVertexIndex * sd->u.s.tangent.dwStride);
|
||||
} 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 + stateblock->baseVertexIndex * sd->u.s.binormal.dwStride);
|
||||
} 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 + stateblock->baseVertexIndex * sd->u.s.position.dwStride);
|
||||
} 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 + stateblock->baseVertexIndex * sd->u.s.position.dwStride);
|
||||
}
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.normal.dwStride);
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.diffuse.dwStride);
|
||||
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 + stateblock->baseVertexIndex * sd->u.s.specular.dwStride);
|
||||
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) || stateblock->textures[textureNo]*/ TRUE) {
|
||||
/* Select the correct texture stage */
|
||||
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
|
||||
}
|
||||
|
||||
if (stateblock->textures[textureNo] != NULL) {
|
||||
int coordIdx = 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 + stateblock->baseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride);
|
||||
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) || 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for vertexdeclaration() */
|
||||
static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction) {
|
||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
BOOL fixup = FALSE;
|
||||
WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
|
||||
|
||||
if(device->up_strided) {
|
||||
/* Note: this is a ddraw fixed-function code path */
|
||||
TRACE("================ Strided Input ===================\n");
|
||||
memcpy(&device->strided_streams, device->up_strided, sizeof(device->strided_streams));
|
||||
memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
|
||||
} else if (stateblock->vertexDecl || stateblock->vertexShader) {
|
||||
/* Note: This is a fixed function or shader codepath.
|
||||
* This means it must handle both types of strided data.
|
||||
|
@ -2020,13 +2457,13 @@ static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVer
|
|||
* don't set any declaration at all
|
||||
*/
|
||||
TRACE("================ Vertex Declaration ===================\n");
|
||||
memset(&device->strided_streams, 0, sizeof(device->strided_streams));
|
||||
memset(dataLocations, 0, sizeof(*dataLocations));
|
||||
|
||||
if (stateblock->vertexDecl != NULL ||
|
||||
((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->vertexDeclaration != NULL) {
|
||||
|
||||
primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
|
||||
&device->strided_streams, &device->streamFixedUp);
|
||||
dataLocations, &fixup);
|
||||
}
|
||||
} else {
|
||||
/* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
|
||||
|
@ -2034,10 +2471,39 @@ static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVer
|
|||
* It will not work properly for shaders.
|
||||
*/
|
||||
TRACE("================ FVF ===================\n");
|
||||
memset(&device->strided_streams, 0, sizeof(device->strided_streams));
|
||||
primitiveConvertToStridedData((IWineD3DDevice *) device, &device->strided_streams,
|
||||
&device->streamFixedUp);
|
||||
memset(dataLocations, 0, sizeof(*dataLocations));
|
||||
primitiveConvertToStridedData((IWineD3DDevice *) device, dataLocations,
|
||||
&fixup);
|
||||
}
|
||||
|
||||
/* Unload the old arrays before loading the new ones to get old junk out */
|
||||
if(device->numberedArraysLoaded) {
|
||||
unloadNumberedArrays(stateblock);
|
||||
device->numberedArraysLoaded = FALSE;
|
||||
}
|
||||
if(device->namedArraysLoaded) {
|
||||
unloadVertexData(stateblock);
|
||||
device->namedArraysLoaded = FALSE;
|
||||
}
|
||||
|
||||
if(useVertexShaderFunction) {
|
||||
TRACE("Loading numbered arrays\n");
|
||||
loadNumberedArrays(stateblock, dataLocations);
|
||||
device->useDrawStridedSlow = FALSE;
|
||||
device->numberedArraysLoaded = TRUE;
|
||||
} else if (fixup ||
|
||||
(dataLocations->u.s.pSize.lpData == NULL &&
|
||||
dataLocations->u.s.diffuse.lpData == NULL &&
|
||||
dataLocations->u.s.specular.lpData == NULL)) {
|
||||
/* Load the vertex data using named arrays */
|
||||
TRACE("Loading vertex data\n");
|
||||
loadVertexData(stateblock, dataLocations);
|
||||
device->useDrawStridedSlow = FALSE;
|
||||
device->namedArraysLoaded = TRUE;
|
||||
} else {
|
||||
TRACE("Not loading vertex data\n");
|
||||
device->useDrawStridedSlow = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
||||
|
@ -2047,8 +2513,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
BOOL wasrhw = device->last_was_rhw;
|
||||
|
||||
device->streamFixedUp = FALSE;
|
||||
|
||||
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
|
||||
* here simply check whether a shader was set, or the user disabled shaders
|
||||
*/
|
||||
|
@ -2128,10 +2592,15 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
|
|||
!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_VIEW))) {
|
||||
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* 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(stateblock->vertexShader);
|
||||
}
|
||||
|
||||
if(updateFog) {
|
||||
state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock);
|
||||
state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -579,6 +579,7 @@ typedef struct IWineD3DDeviceImpl
|
|||
BOOL untransformed;
|
||||
BOOL last_was_pshader;
|
||||
BOOL last_was_foggy_shader;
|
||||
BOOL namedArraysLoaded, numberedArraysLoaded;
|
||||
|
||||
/* State block related */
|
||||
BOOL isRecordingState;
|
||||
|
@ -670,7 +671,7 @@ typedef struct IWineD3DDeviceImpl
|
|||
/* Stream source management */
|
||||
WineDirect3DVertexStridedData strided_streams;
|
||||
WineDirect3DVertexStridedData *up_strided;
|
||||
BOOL streamFixedUp;
|
||||
BOOL useDrawStridedSlow;
|
||||
|
||||
} IWineD3DDeviceImpl;
|
||||
|
||||
|
|
Loading…
Reference in New Issue