📄 state.c
字号:
}
break;
}
}
case WINED3DFOG_NONE: {
/* Both are none? According to msdn the alpha channel of the specular
* color contains a fog factor. Set it in drawStridedSlow.
* Same happens with Vertexfog on transformed vertices
*/
if(GL_SUPPORT(EXT_FOG_COORD)) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
fogstart = 0xff;
fogend = 0x0;
} else {
/* Disable GL fog, handle this in software in drawStridedSlow */
fogenable = FALSE;
}
break;
}
default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
}
} else {
glHint(GL_FOG_HINT, GL_NICEST);
checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
context->last_was_foggy_shader = FALSE;
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
case WINED3DFOG_EXP:
glFogi(GL_FOG_MODE, GL_EXP);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
if(GL_SUPPORT(EXT_FOG_COORD)) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
}
break;
case WINED3DFOG_EXP2:
glFogi(GL_FOG_MODE, GL_EXP2);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
if(GL_SUPPORT(EXT_FOG_COORD)) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
}
break;
case WINED3DFOG_LINEAR:
glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
if(GL_SUPPORT(EXT_FOG_COORD)) {
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
}
break;
case WINED3DFOG_NONE: /* Won't happen */
default:
FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
}
}
if(fogenable) {
glEnable(GL_FOG);
checkGLcall("glEnable GL_FOG");
glFogfv(GL_FOG_START, &fogstart);
checkGLcall("glFogf(GL_FOG_START, fogstart");
TRACE("Fog Start == %f\n", fogstart);
glFogfv(GL_FOG_END, &fogend);
checkGLcall("glFogf(GL_FOG_END, fogend");
TRACE("Fog End == %f\n", fogend);
} else {
glDisable(GL_FOG);
checkGLcall("glDisable GL_FOG");
if( use_ps(stateblock->wineD3DDevice) ) {
/* disable fog in the pixel shader
* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
* -1/(e-s) and e/(e-s) respectively.
*/
glFogf(GL_FOG_START, 0.0f);
checkGLcall("glFogf(GL_FOG_START, fogstart");
glFogf(GL_FOG_END, 1.0f);
checkGLcall("glFogf(GL_FOG_END, fogend");
}
}
if (GL_SUPPORT(NV_FOG_DISTANCE)) {
glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
}
}
static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
glFogfv(GL_FOG_COLOR, &col[0]);
checkGLcall("glFog GL_FOG_COLOR");
}
static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
union {
DWORD d;
float f;
} tmpvalue;
tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
}
/* TODO: Merge with primitive type + init_materials()!! */
static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
GLenum Parm = 0;
WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
BOOL isDiffuseSupplied;
/* Depends on the decoded vertex declaration to read the existence of diffuse data.
* The vertex declaration will call this function if the fixed function pipeline is used.
*/
if(isStateDirty(context, STATE_VDECL)) {
return;
}
isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
context->num_untracked_materials = 0;
if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
TRACE("diff %d, amb %d, emis %d, spec %d\n",
stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
Parm = GL_AMBIENT_AND_DIFFUSE;
} else {
Parm = GL_DIFFUSE;
}
if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
context->num_untracked_materials++;
}
if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
context->num_untracked_materials++;
}
} else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
Parm = GL_AMBIENT;
if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
context->num_untracked_materials++;
}
if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
context->num_untracked_materials++;
}
} else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
Parm = GL_EMISSION;
if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
context->num_untracked_materials++;
}
} else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
Parm = GL_SPECULAR;
}
}
/* Nothing changed, return. */
if (Parm == context->tracking_parm) return;
if(!Parm) {
glDisable(GL_COLOR_MATERIAL);
checkGLcall("glDisable GL_COLOR_MATERIAL");
} else {
glColorMaterial(GL_FRONT_AND_BACK, Parm);
checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
glEnable(GL_COLOR_MATERIAL);
checkGLcall("glEnable(GL_COLOR_MATERIAL)");
}
/* Apparently calls to glMaterialfv are ignored for properties we're
* tracking with glColorMaterial, so apply those here. */
switch (context->tracking_parm) {
case GL_AMBIENT_AND_DIFFUSE:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
checkGLcall("glMaterialfv");
break;
case GL_DIFFUSE:
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
checkGLcall("glMaterialfv");
break;
case GL_AMBIENT:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
checkGLcall("glMaterialfv");
break;
case GL_EMISSION:
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
checkGLcall("glMaterialfv");
break;
case GL_SPECULAR:
/* Only change material color if specular is enabled, otherwise it is set to black */
if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
checkGLcall("glMaterialfv");
} else {
float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
checkGLcall("glMaterialfv");
}
break;
}
context->tracking_parm = Parm;
}
static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
union {
DWORD d;
WINED3DLINEPATTERN lp;
} tmppattern;
tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
if (tmppattern.lp.wRepeatFactor) {
glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
checkGLcall("glLineStipple(repeat, linepattern)");
glEnable(GL_LINE_STIPPLE);
checkGLcall("glEnable(GL_LINE_STIPPLE);");
} else {
glDisable(GL_LINE_STIPPLE);
checkGLcall("glDisable(GL_LINE_STIPPLE);");
}
}
static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
union {
DWORD d;
float f;
} tmpvalue;
if (stateblock->renderState[WINED3DRS_ZBIAS]) {
tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
TRACE("ZBias value %f\n", tmpvalue.f);
glPolygonOffset(0, -tmpvalue.f);
checkGLcall("glPolygonOffset(0, -Value)");
glEnable(GL_POLYGON_OFFSET_FILL);
checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
glEnable(GL_POLYGON_OFFSET_LINE);
checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
glEnable(GL_POLYGON_OFFSET_POINT);
checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
} else {
glDisable(GL_POLYGON_OFFSET_FILL);
checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
glDisable(GL_POLYGON_OFFSET_LINE);
checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
glDisable(GL_POLYGON_OFFSET_POINT);
checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
}
}
static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
glEnable(GL_NORMALIZE);
checkGLcall("glEnable(GL_NORMALIZE);");
} else {
glDisable(GL_NORMALIZE);
checkGLcall("glDisable(GL_NORMALIZE);");
}
}
static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
union {
DWORD d;
float f;
} tmpvalue;
/* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
TRACE("Set point size to %f\n", tmpvalue.f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -