📄 drawprim.c
字号:
* idxData will be != NULL
*/
if(idxData == NULL) {
idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory;
}
if (idxSize == 2) pIdxBufS = (const WORD *) idxData;
else pIdxBufL = (const DWORD *) idxData;
}
/* Adding the stream offset once is cheaper than doing it every iteration. Do not modify the strided data, it is a pointer
* to the strided Data in the device and might be needed intact on the next draw
*/
for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
if(sd->u.s.texCoords[textureNo].lpData) {
texCoords[textureNo] = sd->u.s.texCoords[textureNo].lpData + streamOffset[sd->u.s.texCoords[textureNo].streamNo];
} else {
texCoords[textureNo] = NULL;
}
}
if(sd->u.s.diffuse.lpData) {
diffuse = sd->u.s.diffuse.lpData + streamOffset[sd->u.s.diffuse.streamNo];
}
if(sd->u.s.specular.lpData) {
specular = sd->u.s.specular.lpData + streamOffset[sd->u.s.specular.streamNo];
}
if(sd->u.s.normal.lpData) {
normal = sd->u.s.normal.lpData + streamOffset[sd->u.s.normal.streamNo];
}
if(sd->u.s.position.lpData) {
position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo];
}
/* Start drawing in GL */
VTRACE(("glBegin(%x)\n", glPrimType));
glBegin(glPrimType);
/* Default settings for data that is not passed */
if (sd->u.s.normal.lpData == NULL) {
glNormal3f(0, 0, 1);
}
if(sd->u.s.diffuse.lpData == NULL) {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
if(sd->u.s.specular.lpData == NULL) {
if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
}
}
/* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
* Guess it's not necessary(we crash then anyway) and would only eat CPU time
*/
/* For each primitive */
for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
/* Initialize diffuse color */
diffuseColor = 0xFFFFFFFF;
/* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
* function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
*/
/* For indexed data, we need to go a few more strides in */
if (idxData != NULL) {
/* Indexed so work out the number of strides to skip */
if (idxSize == 2) {
VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
} else {
VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
}
}
/* Texture coords --------------------------- */
for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
continue ;
}
/* Query tex coords */
if (This->stateBlock->textures[textureNo] != NULL) {
int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
float *ptrToCoords = NULL;
float s = 0.0, t = 0.0, r = 0.0, q = 0.0;
if (coordIdx > 7) {
VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
continue;
} else if (coordIdx < 0) {
FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
continue;
}
ptrToCoords = (float *)(texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
if (texCoords[coordIdx] == NULL) {
TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
continue;
} else {
int texture_idx = This->texUnitMap[textureNo];
int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == WINED3DDECLTYPE_FLOAT1 etc */
if (texture_idx == -1) continue;
/* The coords to supply depend completely on the fvf / vertex shader */
switch (coordsToUse) {
case 4: q = ptrToCoords[3]; /* drop through */
case 3: r = ptrToCoords[2]; /* drop through */
case 2: t = ptrToCoords[1]; /* drop through */
case 1: s = ptrToCoords[0];
}
/* Projected is more 'fun' - Move the last coord to the 'q'
parameter (see comments under WINED3DTSS_TEXTURETRANSFORMFLAGS */
if ((This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] != WINED3DTTFF_DISABLE) &&
(This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {
if (This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED) {
switch (coordsToUse) {
case 0: /* Drop Through */
case 1:
FIXME("WINED3DTTFF_PROJECTED but only zero or one coordinate?\n");
break;
case 2:
q = t;
t = 0.0;
coordsToUse = 4;
break;
case 3:
q = r;
r = 0.0;
coordsToUse = 4;
break;
case 4: /* Nop here */
break;
default:
FIXME("Unexpected WINED3DTSS_TEXTURETRANSFORMFLAGS value of %d\n",
This->stateBlock->textureState[textureNo][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED);
}
}
}
switch (coordsToUse) { /* Supply the provided texture coords */
case WINED3DTTFF_COUNT1:
VTRACE(("tex:%d, s=%f\n", textureNo, s));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord1fARB(GL_TEXTURE0_ARB + texture_idx, s));
} else {
glTexCoord1f(s);
}
break;
case WINED3DTTFF_COUNT2:
VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord2fARB(GL_TEXTURE0_ARB + texture_idx, s, t));
} else {
glTexCoord2f(s, t);
}
break;
case WINED3DTTFF_COUNT3:
VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord3fARB(GL_TEXTURE0_ARB + texture_idx, s, t, r));
} else {
glTexCoord3f(s, t, r);
}
break;
case WINED3DTTFF_COUNT4:
VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, s, t, r, q));
} else {
glTexCoord4f(s, t, r, q);
}
break;
default:
FIXME("Should not get here as coordsToUse is two bits only (%x)!\n", coordsToUse);
}
}
}
} /* End of textures */
/* Diffuse -------------------------------- */
if (diffuse) {
DWORD *ptrToCoords = (DWORD *)(diffuse + (SkipnStrides * sd->u.s.diffuse.dwStride));
diffuseColor = ptrToCoords[0];
VTRACE(("diffuseColor=%lx\n", diffuseColor));
glColor4ub(D3DCOLOR_B_R(diffuseColor),
D3DCOLOR_B_G(diffuseColor),
D3DCOLOR_B_B(diffuseColor),
D3DCOLOR_B_A(diffuseColor));
VTRACE(("glColor4ub: r,g,b,a=%lu,%lu,%lu,%lu\n",
D3DCOLOR_B_R(diffuseColor),
D3DCOLOR_B_G(diffuseColor),
D3DCOLOR_B_B(diffuseColor),
D3DCOLOR_B_A(diffuseColor)));
if(This->activeContext->num_untracked_materials) {
unsigned char i;
float color[4];
color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0;
color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0;
color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0;
color[3] = D3DCOLOR_B_A(diffuseColor) / 255.0;
for(i = 0; i < This->activeContext->num_untracked_materials; i++) {
glMaterialfv(GL_FRONT_AND_BACK, This->activeContext->untracked_materials[i], color);
}
}
}
/* Specular ------------------------------- */
if (specular) {
DWORD *ptrToCoords = (DWORD *)(specular + (SkipnStrides * sd->u.s.specular.dwStride));
specularColor = ptrToCoords[0];
VTRACE(("specularColor=%lx\n", specularColor));
/* special case where the fog density is stored in the specular alpha channel */
if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
(This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 )&&
This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
if(GL_SUPPORT(EXT_FOG_COORD)) {
GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
} else {
static BOOL warned = FALSE;
if(!warned) {
/* TODO: Use the fog table code from old ddraw */
FIXME("Implement fog for transformed vertices in software\n");
warned = TRUE;
}
}
}
VTRACE(("glSecondaryColor4ub: r,g,b=%lu,%lu,%lu\n",
D3DCOLOR_B_R(specularColor),
D3DCOLOR_B_G(specularColor),
D3DCOLOR_B_B(specularColor)));
if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
GL_EXTCALL(glSecondaryColor3ubEXT)(
D3DCOLOR_B_R(specularColor),
D3DCOLOR_B_G(specularColor),
D3DCOLOR_B_B(specularColor));
} else {
/* Do not worry if specular colour missing and disable request */
VTRACE(("Specular color extensions not supplied\n"));
}
}
/* Normal -------------------------------- */
if (normal != NULL) {
float *ptrToCoords = (float *)(normal + (SkipnStrides * sd->u.s.normal.dwStride));
VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", ptrToCoords[0], ptrToCoords[1], ptrToCoords[2]));
glNormal3f(ptrToCoords[0], ptrToCoords[1], ptrToCoords[2]);
}
/* Position -------------------------------- */
if (position) {
float *ptrToCoords = (float *)(position + (SkipnStrides * sd->u.s.position.dwStride));
x = ptrToCoords[0];
y = ptrToCoords[1];
z = ptrToCoords[2];
rhw = 1.0;
VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
/* RHW follows, only if transformed, ie 4 floats were provided */
if (sd->u.s.position_transformed) {
rhw = ptrToCoords[3];
VTRACE(("rhw=%f\n", rhw));
}
if (1.0f == rhw || ((rhw < eps) && (rhw > -eps))) {
VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
glVertex3f(x, y, z);
} else {
GLfloat w = 1.0 / rhw;
VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
glVertex4f(x*w, y*w, z*w, w);
}
}
/* For non indexed mode, step onto next parts */
if (idxData == NULL) {
++SkipnStrides;
}
}
glEnd();
checkGLcall("glEnd and previous calls");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -