Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
d5f18e6a
Commit
d5f18e6a
authored
Jan 06, 2007
by
Stefan Dösinger
Committed by
Alexandre Julliard
Jan 08, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Move applying the gl stream sources to the state table.
parent
d3d030eb
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
485 additions
and
491 deletions
+485
-491
drawprim.c
dlls/wined3d/drawprim.c
+4
-480
state.c
dlls/wined3d/state.c
+479
-10
wined3d_private.h
dlls/wined3d/wined3d_private.h
+2
-1
No files found.
dlls/wined3d/drawprim.c
View file @
d5f18e6a
...
...
@@ -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
.
0
f
,
1
.
0
f
,
1
.
0
f
,
1
.
0
f
);
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 */
...
...
dlls/wined3d/state.c
View file @
d5f18e6a
...
...
@@ -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
.
0
f
,
1
.
0
f
,
1
.
0
f
,
1
.
0
f
);
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_stream
s
));
memcpy
(
dataLocations
,
device
->
up_strided
,
sizeof
(
*
dataLocation
s
));
}
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_stream
s
));
memset
(
dataLocations
,
0
,
sizeof
(
*
dataLocation
s
));
if
(
stateblock
->
vertexDecl
!=
NULL
||
((
IWineD3DVertexShaderImpl
*
)
stateblock
->
vertexShader
)
->
vertexDeclaration
!=
NULL
)
{
primitiveDeclarationConvertToStridedData
((
IWineD3DDevice
*
)
device
,
useVertexShaderFunction
,
&
device
->
strided_streams
,
&
device
->
streamFixedU
p
);
dataLocations
,
&
fixu
p
);
}
}
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_stream
s
));
primitiveConvertToStridedData
((
IWineD3DDevice
*
)
device
,
&
device
->
strided_stream
s
,
&
device
->
streamFixedU
p
);
memset
(
dataLocations
,
0
,
sizeof
(
*
dataLocation
s
));
primitiveConvertToStridedData
((
IWineD3DDevice
*
)
device
,
dataLocation
s
,
&
fixu
p
);
}
/* 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
);
}
}
...
...
dlls/wined3d/wined3d_private.h
View file @
d5f18e6a
...
...
@@ -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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment