1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "Context.hpp"
17 #include "PixelShader.hpp"
18 #include "VertexShader.hpp"
19 #include "Primitive.hpp"
20 #include "Surface.hpp"
28 extern bool perspectiveCorrection;
30 bool halfIntegerCoordinates = false; // Pixel centers are not at integer coordinates
31 bool symmetricNormalizedDepth = false; // [-1, 1] instead of [0, 1]
32 bool booleanFaceRegister = false;
33 bool fullPixelPositionRegister = false;
34 bool leadingVertexFirst = false; // Flat shading uses first vertex, else last
35 bool secondaryColor = false; // Specular lighting is applied after texturing
37 bool forceWindowed = false;
38 bool quadLayoutEnabled = false;
39 bool veryEarlyDepthTest = true;
40 bool complementaryDepthBuffer = false;
41 bool postBlendSRGB = false;
42 bool exactColorRounding = false;
43 TransparencyAntialiasing transparencyAntialiasing = TRANSPARENCY_NONE;
44 bool forceClearRegisters = false;
55 void *Context::operator new(size_t bytes)
57 return allocate((unsigned int)bytes);
60 void Context::operator delete(void *pointer, size_t bytes)
65 bool Context::isDrawPoint(bool fillModeAware) const
70 case DRAW_INDEXEDPOINTLIST8:
71 case DRAW_INDEXEDPOINTLIST16:
72 case DRAW_INDEXEDPOINTLIST32:
77 case DRAW_INDEXEDLINELIST8:
78 case DRAW_INDEXEDLINESTRIP8:
79 case DRAW_INDEXEDLINELOOP8:
80 case DRAW_INDEXEDLINELIST16:
81 case DRAW_INDEXEDLINESTRIP16:
82 case DRAW_INDEXEDLINELOOP16:
83 case DRAW_INDEXEDLINELIST32:
84 case DRAW_INDEXEDLINESTRIP32:
85 case DRAW_INDEXEDLINELOOP32:
87 case DRAW_TRIANGLELIST:
88 case DRAW_TRIANGLESTRIP:
89 case DRAW_TRIANGLEFAN:
90 case DRAW_INDEXEDTRIANGLELIST8:
91 case DRAW_INDEXEDTRIANGLESTRIP8:
92 case DRAW_INDEXEDTRIANGLEFAN8:
93 case DRAW_INDEXEDTRIANGLELIST16:
94 case DRAW_INDEXEDTRIANGLESTRIP16:
95 case DRAW_INDEXEDTRIANGLEFAN16:
96 case DRAW_INDEXEDTRIANGLELIST32:
97 case DRAW_INDEXEDTRIANGLESTRIP32:
98 case DRAW_INDEXEDTRIANGLEFAN32:
99 return fillModeAware ? fillMode == FILL_VERTEX : false;
109 bool Context::isDrawLine(bool fillModeAware) const
114 case DRAW_INDEXEDPOINTLIST8:
115 case DRAW_INDEXEDPOINTLIST16:
116 case DRAW_INDEXEDPOINTLIST32:
121 case DRAW_INDEXEDLINELIST8:
122 case DRAW_INDEXEDLINESTRIP8:
123 case DRAW_INDEXEDLINELOOP8:
124 case DRAW_INDEXEDLINELIST16:
125 case DRAW_INDEXEDLINESTRIP16:
126 case DRAW_INDEXEDLINELOOP16:
127 case DRAW_INDEXEDLINELIST32:
128 case DRAW_INDEXEDLINESTRIP32:
129 case DRAW_INDEXEDLINELOOP32:
131 case DRAW_TRIANGLELIST:
132 case DRAW_TRIANGLESTRIP:
133 case DRAW_TRIANGLEFAN:
134 case DRAW_INDEXEDTRIANGLELIST8:
135 case DRAW_INDEXEDTRIANGLESTRIP8:
136 case DRAW_INDEXEDTRIANGLEFAN8:
137 case DRAW_INDEXEDTRIANGLELIST16:
138 case DRAW_INDEXEDTRIANGLESTRIP16:
139 case DRAW_INDEXEDTRIANGLEFAN16:
140 case DRAW_INDEXEDTRIANGLELIST32:
141 case DRAW_INDEXEDTRIANGLESTRIP32:
142 case DRAW_INDEXEDTRIANGLEFAN32:
143 return fillModeAware ? fillMode == FILL_WIREFRAME : false;
153 bool Context::isDrawTriangle(bool fillModeAware) const
158 case DRAW_INDEXEDPOINTLIST8:
159 case DRAW_INDEXEDPOINTLIST16:
160 case DRAW_INDEXEDPOINTLIST32:
165 case DRAW_INDEXEDLINELIST8:
166 case DRAW_INDEXEDLINESTRIP8:
167 case DRAW_INDEXEDLINELOOP8:
168 case DRAW_INDEXEDLINELIST16:
169 case DRAW_INDEXEDLINESTRIP16:
170 case DRAW_INDEXEDLINELOOP16:
171 case DRAW_INDEXEDLINELIST32:
172 case DRAW_INDEXEDLINESTRIP32:
173 case DRAW_INDEXEDLINELOOP32:
175 case DRAW_TRIANGLELIST:
176 case DRAW_TRIANGLESTRIP:
177 case DRAW_TRIANGLEFAN:
178 case DRAW_INDEXEDTRIANGLELIST8:
179 case DRAW_INDEXEDTRIANGLESTRIP8:
180 case DRAW_INDEXEDTRIANGLEFAN8:
181 case DRAW_INDEXEDTRIANGLELIST16:
182 case DRAW_INDEXEDTRIANGLESTRIP16:
183 case DRAW_INDEXEDTRIANGLEFAN16:
184 case DRAW_INDEXEDTRIANGLELIST32:
185 case DRAW_INDEXEDTRIANGLESTRIP32:
186 case DRAW_INDEXEDTRIANGLEFAN32:
187 return fillModeAware ? fillMode == FILL_SOLID : true;
189 // Quads are broken up into triangles
190 return fillModeAware ? fillMode == FILL_SOLID : true;
200 for(int i = 0; i < 8; i++)
202 textureStage[i].init(i, &sampler[i], (i >= 1) ? &textureStage[i - 1] : 0);
205 // Set vertex streams to null stream
206 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
214 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++) textureWrap[i] = 0;
215 for(int i = 0; i < 8; i++) texGen[i] = TEXGEN_PASSTHRU;
216 for(int i = 0; i < 8; i++) textureTransformCount[i] = 0;
217 for(int i = 0; i < 8; i++) textureTransformProject[i] = false;
218 textureWrapActive = false;
220 normalizeNormals = false;
222 for(int i = 0; i < RENDERTARGETS; ++i)
224 renderTarget[i] = nullptr;
226 depthBuffer = nullptr;
227 stencilBuffer = nullptr;
229 stencilEnable = false;
230 stencilCompareMode = STENCIL_ALWAYS;
231 stencilReference = 0;
232 stencilMask = 0xFFFFFFFF;
233 stencilFailOperation = OPERATION_KEEP;
234 stencilPassOperation = OPERATION_KEEP;
235 stencilZFailOperation = OPERATION_KEEP;
236 stencilWriteMask = 0xFFFFFFFF;
238 twoSidedStencil = false;
239 stencilCompareModeCCW = STENCIL_ALWAYS;
240 stencilReferenceCCW = 0;
241 stencilMaskCCW = 0xFFFFFFFF;
242 stencilFailOperationCCW = OPERATION_KEEP;
243 stencilPassOperationCCW = OPERATION_KEEP;
244 stencilZFailOperationCCW = OPERATION_KEEP;
245 stencilWriteMaskCCW = 0xFFFFFFFF;
247 setGlobalMipmapBias(0);
249 lightingEnable = true;
250 specularEnable = false;
251 for(int i = 0; i < 8; i++) lightEnable[i] = false;
252 for(int i = 0; i < 8; i++) worldLightPosition[i] = 0;
254 alphaCompareMode = ALPHA_ALWAYS;
255 alphaTestEnable = false;
256 fillMode = FILL_SOLID;
257 shadingMode = SHADING_GOURAUD;
259 rasterizerDiscard = false;
261 depthCompareMode = DEPTH_LESS;
262 depthBufferEnable = true;
263 depthWriteEnable = true;
265 alphaBlendEnable = false;
266 sourceBlendFactorState = BLEND_ONE;
267 destBlendFactorState = BLEND_ZERO;
268 blendOperationState = BLENDOP_ADD;
270 separateAlphaBlendEnable = false;
271 sourceBlendFactorStateAlpha = BLEND_ONE;
272 destBlendFactorStateAlpha = BLEND_ZERO;
273 blendOperationStateAlpha = BLENDOP_ADD;
275 cullMode = CULL_CLOCKWISE;
276 alphaReference = 0.0f;
278 for(int i = 0; i < RENDERTARGETS; i++)
280 colorWriteMask[i] = 0x0000000F;
283 ambientMaterialSource = MATERIAL_MATERIAL;
284 diffuseMaterialSource = MATERIAL_COLOR1;
285 specularMaterialSource = MATERIAL_COLOR2;
286 emissiveMaterialSource = MATERIAL_MATERIAL;
287 colorVertexEnable = true;
290 pixelFogMode = FOG_NONE;
291 vertexFogMode = FOG_NONE;
293 rangeFogEnable = false;
295 indexedVertexBlendEnable = false;
296 vertexBlendMatrixCount = 0;
303 occlusionEnabled = false;
304 transformFeedbackQueryEnabled = false;
305 transformFeedbackEnabled = 0;
307 pointSpriteEnable = false;
308 pointScaleEnable = false;
312 sampleMask = 0xFFFFFFFF;
314 colorLogicOpEnabled = false;
315 logicalOperation = LOGICALOP_COPY;
318 const float &Context::exp2Bias()
323 const Point &Context::getLightPosition(int light)
325 return worldLightPosition[light];
328 void Context::setGlobalMipmapBias(float bias)
330 this->bias = exp2(bias + 0.5f);
333 void Context::setLightingEnable(bool lightingEnable)
335 this->lightingEnable = lightingEnable;
338 void Context::setSpecularEnable(bool specularEnable)
340 Context::specularEnable = specularEnable;
343 void Context::setLightEnable(int light, bool lightEnable)
345 Context::lightEnable[light] = lightEnable;
348 void Context::setLightPosition(int light, Point worldLightPosition)
350 Context::worldLightPosition[light] = worldLightPosition;
353 void Context::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
355 Context::ambientMaterialSource = ambientMaterialSource;
358 void Context::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
360 Context::diffuseMaterialSource = diffuseMaterialSource;
363 void Context::setSpecularMaterialSource(MaterialSource specularMaterialSource)
365 Context::specularMaterialSource = specularMaterialSource;
368 void Context::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
370 Context::emissiveMaterialSource = emissiveMaterialSource;
373 void Context::setPointSpriteEnable(bool pointSpriteEnable)
375 Context::pointSpriteEnable = pointSpriteEnable;
378 void Context::setPointScaleEnable(bool pointScaleEnable)
380 Context::pointScaleEnable = pointScaleEnable;
383 bool Context::setDepthBufferEnable(bool depthBufferEnable)
385 bool modified = (Context::depthBufferEnable != depthBufferEnable);
386 Context::depthBufferEnable = depthBufferEnable;
390 bool Context::setAlphaBlendEnable(bool alphaBlendEnable)
392 bool modified = (Context::alphaBlendEnable != alphaBlendEnable);
393 Context::alphaBlendEnable = alphaBlendEnable;
397 bool Context::setSourceBlendFactor(BlendFactor sourceBlendFactor)
399 bool modified = (Context::sourceBlendFactorState != sourceBlendFactor);
400 Context::sourceBlendFactorState = sourceBlendFactor;
404 bool Context::setDestBlendFactor(BlendFactor destBlendFactor)
406 bool modified = (Context::destBlendFactorState != destBlendFactor);
407 Context::destBlendFactorState = destBlendFactor;
411 bool Context::setBlendOperation(BlendOperation blendOperation)
413 bool modified = (Context::blendOperationState != blendOperation);
414 Context::blendOperationState = blendOperation;
418 bool Context::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
420 bool modified = (Context::separateAlphaBlendEnable != separateAlphaBlendEnable);
421 Context::separateAlphaBlendEnable = separateAlphaBlendEnable;
425 bool Context::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)
427 bool modified = (Context::sourceBlendFactorStateAlpha != sourceBlendFactorAlpha);
428 Context::sourceBlendFactorStateAlpha = sourceBlendFactorAlpha;
432 bool Context::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)
434 bool modified = (Context::destBlendFactorStateAlpha != destBlendFactorAlpha);
435 Context::destBlendFactorStateAlpha = destBlendFactorAlpha;
439 bool Context::setBlendOperationAlpha(BlendOperation blendOperationAlpha)
441 bool modified = (Context::blendOperationStateAlpha != blendOperationAlpha);
442 Context::blendOperationStateAlpha = blendOperationAlpha;
446 bool Context::setColorWriteMask(int index, int colorWriteMask)
448 bool modified = (Context::colorWriteMask[index] != colorWriteMask);
449 Context::colorWriteMask[index] = colorWriteMask;
453 bool Context::setWriteSRGB(bool sRGB)
455 bool modified = (Context::writeSRGB != sRGB);
456 Context::writeSRGB = sRGB;
460 bool Context::setColorLogicOpEnabled(bool enabled)
462 bool modified = (Context::colorLogicOpEnabled != enabled);
463 Context::colorLogicOpEnabled = enabled;
467 bool Context::setLogicalOperation(LogicalOperation logicalOperation)
469 bool modified = (Context::logicalOperation != logicalOperation);
470 Context::logicalOperation = logicalOperation;
474 void Context::setColorVertexEnable(bool colorVertexEnable)
476 Context::colorVertexEnable = colorVertexEnable;
479 bool Context::fogActive()
481 if(!colorUsed()) return false;
483 if(pixelShaderVersion() >= 0x0300) return false;
488 bool Context::pointSizeActive()
495 return isDrawPoint(true) && (input[PointSize] || (!preTransformed && pointScaleActive()));
498 FogMode Context::pixelFogActive()
508 bool Context::depthWriteActive()
510 if(!depthBufferActive()) return false;
512 return depthWriteEnable;
515 bool Context::alphaTestActive()
517 if(transparencyAntialiasing != TRANSPARENCY_NONE) return true;
518 if(!alphaTestEnable) return false;
519 if(alphaCompareMode == ALPHA_ALWAYS) return false;
520 if(alphaReference == 0.0f && alphaCompareMode == ALPHA_GREATEREQUAL) return false;
525 bool Context::depthBufferActive()
527 return depthBuffer && depthBufferEnable;
530 bool Context::stencilActive()
532 return stencilBuffer && stencilEnable;
535 bool Context::vertexLightingActive()
542 return lightingEnable && !preTransformed;
545 bool Context::texCoordActive(int coordinate, int component)
547 bool hasTexture = pointSpriteActive();
553 if(vertexShader->getOutput(T0 + coordinate, component).usage == Shader::USAGE_TEXCOORD)
560 hasTexture = true; // FIXME: Check vertex buffer streams
565 switch(texGen[coordinate])
570 case TEXGEN_PASSTHRU:
571 hasTexture = hasTexture || (component < input[TexCoord0 + textureStage[coordinate].texCoordIndex].count);
574 hasTexture = hasTexture || (component <= 2);
576 case TEXGEN_POSITION:
577 hasTexture = hasTexture || (component <= 2);
579 case TEXGEN_REFLECTION:
580 hasTexture = hasTexture || (component <= 2);
582 case TEXGEN_SPHEREMAP:
583 hasTexture = hasTexture || (component <= 1);
590 bool project = isProjectionComponent(coordinate, component);
591 bool usesTexture = false;
595 usesTexture = pixelShader->usesTexture(coordinate, component) || project;
599 usesTexture = textureStage[coordinate].usesTexture() || project;
602 return hasTexture && usesTexture;
605 bool Context::texCoordActive(int coordinate)
607 return texCoordActive(coordinate, 0) ||
608 texCoordActive(coordinate, 1) ||
609 texCoordActive(coordinate, 2) ||
610 texCoordActive(coordinate, 3);
613 bool Context::isProjectionComponent(unsigned int coordinate, int component)
615 if(pixelShaderVersion() <= 0x0103 && coordinate < 8 && textureTransformProject[coordinate])
617 if(textureTransformCount[coordinate] == 2)
619 if(component == 1) return true;
621 else if(textureTransformCount[coordinate] == 3)
623 if(component == 2) return true;
625 else if(textureTransformCount[coordinate] == 4 || textureTransformCount[coordinate] == 0)
627 if(component == 3) return true;
634 bool Context::vertexSpecularActive()
636 return vertexLightingActive() && specularEnable && vertexNormalActive();
639 bool Context::vertexNormalActive()
646 return input[Normal];
649 bool Context::vertexLightActive(int i)
656 return lightingEnable && lightEnable[i];
659 MaterialSource Context::vertexDiffuseMaterialSourceActive()
663 return MATERIAL_MATERIAL;
666 if(diffuseMaterialSource == MATERIAL_MATERIAL || !colorVertexEnable ||
667 (diffuseMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
668 (diffuseMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
670 return MATERIAL_MATERIAL;
673 return diffuseMaterialSource;
676 MaterialSource Context::vertexSpecularMaterialSourceActive()
680 return MATERIAL_MATERIAL;
683 if(!colorVertexEnable ||
684 (specularMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
685 (specularMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
687 return MATERIAL_MATERIAL;
690 return specularMaterialSource;
693 MaterialSource Context::vertexAmbientMaterialSourceActive()
697 return MATERIAL_MATERIAL;
700 if(!colorVertexEnable ||
701 (ambientMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
702 (ambientMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
704 return MATERIAL_MATERIAL;
707 return ambientMaterialSource;
710 MaterialSource Context::vertexEmissiveMaterialSourceActive()
714 return MATERIAL_MATERIAL;
717 if(!colorVertexEnable ||
718 (emissiveMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
719 (emissiveMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
721 return MATERIAL_MATERIAL;
724 return emissiveMaterialSource;
727 bool Context::pointSpriteActive()
729 return isDrawPoint(true) && pointSpriteEnable;
732 bool Context::pointScaleActive()
739 return isDrawPoint(true) && pointScaleEnable;
742 bool Context::alphaBlendActive()
744 if(!alphaBlendEnable)
754 bool colorBlend = !(blendOperation() == BLENDOP_SOURCE && sourceBlendFactor() == BLEND_ONE);
755 bool alphaBlend = separateAlphaBlendEnable ? !(blendOperationAlpha() == BLENDOP_SOURCE && sourceBlendFactorAlpha() == BLEND_ONE) : colorBlend;
757 return colorBlend || alphaBlend;
760 LogicalOperation Context::colorLogicOp()
762 return colorLogicOpEnabled ? logicalOperation : LOGICALOP_COPY;
765 BlendFactor Context::sourceBlendFactor()
767 if(!alphaBlendEnable) return BLEND_ONE;
769 switch(blendOperationState)
774 return sourceBlendFactorState;
783 return sourceBlendFactorState;
786 BlendFactor Context::destBlendFactor()
788 if(!alphaBlendEnable) return BLEND_ZERO;
790 switch(blendOperationState)
795 return destBlendFactorState;
804 return destBlendFactorState;
807 BlendOperation Context::blendOperation()
809 if(!alphaBlendEnable) return BLENDOP_SOURCE;
811 switch(blendOperationState)
814 if(sourceBlendFactor() == BLEND_ZERO)
816 if(destBlendFactor() == BLEND_ZERO)
825 else if(sourceBlendFactor() == BLEND_ONE)
827 if(destBlendFactor() == BLEND_ZERO)
829 return BLENDOP_SOURCE;
838 if(destBlendFactor() == BLEND_ZERO)
840 return BLENDOP_SOURCE;
848 if(sourceBlendFactor() == BLEND_ZERO)
850 return BLENDOP_NULL; // Negative, clamped to zero
852 else if(sourceBlendFactor() == BLEND_ONE)
854 if(destBlendFactor() == BLEND_ZERO)
856 return BLENDOP_SOURCE;
865 if(destBlendFactor() == BLEND_ZERO)
867 return BLENDOP_SOURCE;
875 if(sourceBlendFactor() == BLEND_ZERO)
877 if(destBlendFactor() == BLEND_ZERO)
886 else if(sourceBlendFactor() == BLEND_ONE)
888 if(destBlendFactor() == BLEND_ZERO)
890 return BLENDOP_NULL; // Negative, clamped to zero
894 return BLENDOP_INVSUB;
899 if(destBlendFactor() == BLEND_ZERO)
901 return BLENDOP_NULL; // Negative, clamped to zero
905 return BLENDOP_INVSUB;
916 return blendOperationState;
919 BlendFactor Context::sourceBlendFactorAlpha()
921 if(!separateAlphaBlendEnable)
923 return sourceBlendFactor();
927 switch(blendOperationStateAlpha)
932 return sourceBlendFactorStateAlpha;
941 return sourceBlendFactorStateAlpha;
945 BlendFactor Context::destBlendFactorAlpha()
947 if(!separateAlphaBlendEnable)
949 return destBlendFactor();
953 switch(blendOperationStateAlpha)
958 return destBlendFactorStateAlpha;
967 return destBlendFactorStateAlpha;
971 BlendOperation Context::blendOperationAlpha()
973 if(!separateAlphaBlendEnable)
975 return blendOperation();
979 switch(blendOperationStateAlpha)
982 if(sourceBlendFactorAlpha() == BLEND_ZERO)
984 if(destBlendFactorAlpha() == BLEND_ZERO)
993 else if(sourceBlendFactorAlpha() == BLEND_ONE)
995 if(destBlendFactorAlpha() == BLEND_ZERO)
997 return BLENDOP_SOURCE;
1006 if(destBlendFactorAlpha() == BLEND_ZERO)
1008 return BLENDOP_SOURCE;
1016 if(sourceBlendFactorAlpha() == BLEND_ZERO)
1018 return BLENDOP_NULL; // Negative, clamped to zero
1020 else if(sourceBlendFactorAlpha() == BLEND_ONE)
1022 if(destBlendFactorAlpha() == BLEND_ZERO)
1024 return BLENDOP_SOURCE;
1033 if(destBlendFactorAlpha() == BLEND_ZERO)
1035 return BLENDOP_SOURCE;
1042 case BLENDOP_INVSUB:
1043 if(sourceBlendFactorAlpha() == BLEND_ZERO)
1045 if(destBlendFactorAlpha() == BLEND_ZERO)
1047 return BLENDOP_NULL;
1051 return BLENDOP_DEST;
1054 else if(sourceBlendFactorAlpha() == BLEND_ONE)
1056 if(destBlendFactorAlpha() == BLEND_ZERO)
1058 return BLENDOP_NULL; // Negative, clamped to zero
1062 return BLENDOP_INVSUB;
1067 if(destBlendFactorAlpha() == BLEND_ZERO)
1069 return BLENDOP_NULL; // Negative, clamped to zero
1073 return BLENDOP_INVSUB;
1084 return blendOperationStateAlpha;
1088 bool Context::indexedVertexBlendActive()
1095 return indexedVertexBlendEnable;
1098 int Context::vertexBlendMatrixCountActive()
1105 return vertexBlendMatrixCount;
1108 bool Context::localViewerActive()
1118 bool Context::normalizeNormalsActive()
1125 return normalizeNormals;
1128 FogMode Context::vertexFogModeActive()
1130 if(vertexShader || !fogActive())
1135 return vertexFogMode;
1138 bool Context::rangeFogActive()
1140 if(vertexShader || !fogActive())
1145 return rangeFogEnable;
1148 TexGen Context::texGenActive(int stage)
1150 if(vertexShader || !texCoordActive(stage))
1152 return TEXGEN_PASSTHRU;
1155 return texGen[stage];
1158 int Context::textureTransformCountActive(int stage)
1160 if(vertexShader || !texCoordActive(stage))
1165 return textureTransformCount[stage];
1168 int Context::texCoordIndexActive(int stage)
1170 if(vertexShader || !texCoordActive(stage))
1175 return textureStage[stage].texCoordIndex;
1178 bool Context::perspectiveActive()
1185 if(!perspectiveCorrection)
1190 if(isDrawPoint(true))
1198 bool Context::diffuseUsed()
1200 return diffuseUsed(0) || diffuseUsed(1) || diffuseUsed(2) || diffuseUsed(3);
1203 bool Context::diffuseUsed(int component)
1212 return pixelShader->usesDiffuse(component);
1215 // Directly using the diffuse input color
1216 for(int i = 0; i < 8; i++)
1218 if(textureStage[i].isStageDisabled())
1223 if(textureStage[i].usesDiffuse())
1229 // Using the current color (initialized to diffuse) before it's overwritten
1230 for(int i = 0; i < 8; i++)
1232 if(textureStage[i].usesCurrent() || textureStage[i].isStageDisabled()) // Current color contains diffuse before being overwritten
1237 if(textureStage[i].writesCurrent())
1246 bool Context::diffuseActive()
1248 return diffuseActive(0) || diffuseActive(1) || diffuseActive(2) || diffuseActive(3);
1251 bool Context::diffuseActive(int component)
1258 // Vertex processor provides diffuse component
1263 vertexDiffuse = vertexShader->getOutput(C0, component).active();
1265 else if(!preTransformed)
1267 vertexDiffuse = input[Color0] || lightingEnable;
1271 vertexDiffuse = input[Color0];
1274 // Pixel processor requires diffuse component
1275 bool pixelDiffuse = diffuseUsed(component);
1277 return vertexDiffuse && pixelDiffuse;
1280 bool Context::specularUsed()
1282 return Context::specularUsed(0) || Context::specularUsed(1) || Context::specularUsed(2) || Context::specularUsed(3);
1285 bool Context::specularUsed(int component)
1294 return pixelShader->usesSpecular(component);
1297 bool pixelSpecular = specularEnable;
1299 for(int i = 0; i < 8; i++)
1301 if(textureStage[i].isStageDisabled()) break;
1303 pixelSpecular = pixelSpecular || textureStage[i].usesSpecular();
1306 return pixelSpecular;
1309 bool Context::specularActive()
1311 return specularActive(0) || specularActive(1) || specularActive(2) || specularActive(3);
1314 bool Context::specularActive(int component)
1321 // Vertex processor provides specular component
1322 bool vertexSpecular;
1326 vertexSpecular = input[Color1] || (lightingEnable && specularEnable);
1330 vertexSpecular = vertexShader->getOutput(C1, component).active();
1333 // Pixel processor requires specular component
1334 bool pixelSpecular = specularUsed(component);
1336 return vertexSpecular && pixelSpecular;
1339 bool Context::colorActive(int color, int component)
1343 return diffuseActive(component);
1347 return specularActive(component);
1351 bool Context::textureActive()
1353 for(int i = 0; i < 8; i++)
1355 if(textureActive(i))
1364 bool Context::textureActive(int coordinate)
1366 return textureActive(coordinate, 0) || textureActive(coordinate, 1) || textureActive(coordinate, 2) || textureActive(coordinate, 3);
1369 bool Context::textureActive(int coordinate, int component)
1376 if(!texCoordActive(coordinate, component))
1381 if(textureTransformProject[coordinate] && pixelShaderVersion() <= 0x0103)
1383 if(textureTransformCount[coordinate] == 2)
1385 if(component == 1) return true;
1387 else if(textureTransformCount[coordinate] == 3)
1389 if(component == 2) return true;
1391 else if(textureTransformCount[coordinate] == 4 || textureTransformCount[coordinate] == 0)
1393 if(component == 3) return true;
1399 bool texture = textureStage[coordinate].usesTexture();
1400 bool cube = sampler[coordinate].hasCubeTexture();
1401 bool volume = sampler[coordinate].hasVolumeTexture();
1405 for(int i = coordinate; i >= 0; i--)
1407 if(textureStage[i].stageOperation == TextureStage::STAGE_DISABLE)
1421 return (texture && (cube || volume));
1428 return pixelShader->usesTexture(coordinate, component);
1434 unsigned short Context::pixelShaderVersion() const
1436 return pixelShader ? pixelShader->getVersion() : 0x0000;
1439 unsigned short Context::vertexShaderVersion() const
1441 return vertexShader ? vertexShader->getVersion() : 0x0000;
1444 int Context::getMultiSampleCount() const
1446 return renderTarget[0] ? renderTarget[0]->getMultiSampleCount() : 1;
1449 int Context::getSuperSampleCount() const
1451 return renderTarget[0] ? renderTarget[0]->getSuperSampleCount() : 1;
1454 Format Context::renderTargetInternalFormat(int index)
1456 if(renderTarget[index])
1458 return renderTarget[index]->getInternalFormat();
1466 int Context::colorWriteActive()
1468 return colorWriteActive(0) | colorWriteActive(1) | colorWriteActive(2) | colorWriteActive(3);
1471 int Context::colorWriteActive(int index)
1473 if(!renderTarget[index] || renderTarget[index]->getInternalFormat() == FORMAT_NULL)
1478 if(blendOperation() == BLENDOP_DEST && destBlendFactor() == BLEND_ONE &&
1479 (!separateAlphaBlendEnable || (blendOperationAlpha() == BLENDOP_DEST && destBlendFactorAlpha() == BLEND_ONE)))
1484 return colorWriteMask[index];
1487 bool Context::colorUsed()
1489 return colorWriteActive() || alphaTestActive() || (pixelShader && pixelShader->containsKill());