void SkyBox::_initMaterial() { if ( mMatInstance ) SAFE_DELETE( mMatInstance ); if ( mMaterial ) mMatInstance = mMaterial->createMatInstance(); else mMatInstance = MATMGR->createMatInstance( "WarningMaterial" ); // We want to disable culling and z write. GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setBlend( true ); desc.setZReadWrite( true, false ); mMatInstance->addStateBlockDesc( desc ); // Also disable lighting on the skybox material by default. FeatureSet features = MATMGR->getDefaultFeatures(); features.removeFeature( MFT_RTLighting ); features.removeFeature( MFT_Visibility ); features.addFeature(MFT_SkyBox); // Now initialize the material. mMatInstance->init(features, getGFXVertexFormat<GFXVertexPNT>()); }
void SceneSpace::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat ) { if( overrideMat ) return; if( !mEditorRenderMaterial ) { // We have no material for rendering so just render // a plain box. GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( getScale() ); GFX->multWorld( mat ); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); desc.setCullMode( GFXCullNone ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawCube( desc, mObjBox, _getDefaultEditorSolidColor() ); // Render black wireframe. desc.setFillModeWireframe(); drawer->drawCube( desc, mObjBox, _getDefaultEditorWireframeColor() ); } else { //RDTODO } }
void Trigger::renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if(overrideMat) return; GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); // Trigger polyhedrons are set up with outward facing normals and CCW ordering // so can't enable backface culling. desc.setCullMode( GFXCullNone ); GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( getScale() ); GFX->multWorld( mat ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawPolyhedron( desc, mTriggerPolyhedron, ColorI( 255, 192, 0, 45 ) ); // Render wireframe. desc.setFillModeWireframe(); drawer->drawPolyhedron( desc, mTriggerPolyhedron, ColorI::BLACK ); }
void GuiGradientCtrl::onRender(Point2I offset, const RectI& updateRect) { if (mStateBlock.isNull()) { GFXStateBlockDesc desc; desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); desc.setZReadWrite(false); desc.zWriteEnable = false; desc.setCullMode(GFXCullNone); mStateBlock = GFX->createStateBlock( desc ); } RectI boundsRect(offset, getExtent()); renderColorBox(boundsRect); if (mPositionChanged) { mPositionChanged = false; // Now do onAction() if we are allowed if (mActionOnMove) onAction(); } //render the children renderChildControls( offset, updateRect); }
void Sun::_initCorona() { if ( isServerObject() ) return; // Load texture... if ( mCoronaTextureName.isNotEmpty() ) mCoronaTexture.set( mCoronaTextureName, &GFXDefaultStaticDiffuseProfile, "CoronaTexture" ); // Make stateblock... if ( mCoronaSB.isNull() ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setAlphaTest( true, GFXCmpGreaterEqual, 1 ); desc.setZReadWrite( false, false ); desc.setBlend( true, GFXBlendSrcColor, GFXBlendOne ); desc.samplersDefined = true; desc.samplers[0].textureColorOp = GFXTOPModulate; desc.samplers[0].colorArg1 = GFXTATexture; desc.samplers[0].colorArg2 = GFXTADiffuse; desc.samplers[0].alphaOp = GFXTOPModulate; desc.samplers[0].alphaArg1 = GFXTATexture; desc.samplers[0].alphaArg2 = GFXTADiffuse; mCoronaSB = GFX->createStateBlock(desc); desc.setFillModeWireframe(); mCoronaWireframeSB = GFX->createStateBlock(desc); } }
bool CloudLayer::onAdd() { if ( !Parent::onAdd() ) return false; setGlobalBounds(); resetWorldBox(); addToScene(); if ( isClientObject() ) { _initTexture(); _initBuffers(); // Find ShaderData ShaderData *shaderData; mShader = Sim::findObject( "CloudLayerShader", shaderData ) ? shaderData->getShader() : NULL; if ( !mShader ) { Con::errorf( "CloudLayer::onAdd - could not find CloudLayerShader" ); return false; } // Create ShaderConstBuffer and Handles mShaderConsts = mShader->allocConstBuffer(); mModelViewProjSC = mShader->getShaderConstHandle( "$modelView" ); mEyePosWorldSC = mShader->getShaderConstHandle( "$eyePosWorld" ); mSunVecSC = mShader->getShaderConstHandle( "$sunVec" ); mTexOffsetSC[0] = mShader->getShaderConstHandle( "$texOffset0" ); mTexOffsetSC[1] = mShader->getShaderConstHandle( "$texOffset1" ); mTexOffsetSC[2] = mShader->getShaderConstHandle( "$texOffset2" ); mTexScaleSC = mShader->getShaderConstHandle( "$texScale" ); mAmbientColorSC = mShader->getShaderConstHandle( "$ambientColor" ); mSunColorSC = mShader->getShaderConstHandle( "$sunColor" ); mCoverageSC = mShader->getShaderConstHandle( "$cloudCoverage" ); mExposureSC = mShader->getShaderConstHandle( "$cloudExposure" ); mBaseColorSC = mShader->getShaderConstHandle( "$cloudBaseColor" ); mNormalHeightMapSC = mShader->getShaderConstHandle( "$normalHeightMap" ); // Create StateBlocks GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setBlend( true ); desc.setZReadWrite( false, false ); desc.samplersDefined = true; desc.samplers[0].addressModeU = GFXAddressWrap; desc.samplers[0].addressModeV = GFXAddressWrap; desc.samplers[0].addressModeW = GFXAddressWrap; desc.samplers[0].magFilter = GFXTextureFilterLinear; desc.samplers[0].minFilter = GFXTextureFilterLinear; desc.samplers[0].mipFilter = GFXTextureFilterLinear; desc.samplers[0].textureColorOp = GFXTOPModulate; mStateblock = GFX->createStateBlock( desc ); } return true; }
BaseMatInstance * MaterialManager::createMeshDebugMatInstance(const ColorF &meshColor) { String meshDebugStr = String::ToString( "Torque_MeshDebug_%d", meshColor.getRGBAPack() ); Material *debugMat; if (!Sim::findObject(meshDebugStr,debugMat)) { debugMat = allocateAndRegister( meshDebugStr ); debugMat->mDiffuse[0] = meshColor; debugMat->mEmissive[0] = true; } BaseMatInstance *debugMatInstance = NULL; if( debugMat != NULL ) { debugMatInstance = debugMat->createMatInstance(); GFXStateBlockDesc desc; desc.setCullMode(GFXCullNone); desc.fillMode = GFXFillWireframe; debugMatInstance->addStateBlockDesc(desc); // Disable fog and other stuff. FeatureSet debugFeatures; debugFeatures.addFeature( MFT_DiffuseColor ); debugMatInstance->init( debugFeatures, getGFXVertexFormat<GFXVertexPCN>() ); } return debugMatInstance; }
void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) { if (mStateBlock.isNull()) { GFXStateBlockDesc desc; desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); desc.setZReadWrite(false); desc.zWriteEnable = false; desc.setCullMode(GFXCullNone); mStateBlock = GFX->createStateBlock( desc ); } RectI boundsRect(offset, getExtent()); renderColorBox(boundsRect); if (mPositionChanged) { mPositionChanged = false; Point2I extent = getRoot()->getExtent(); // If we are anything but a pallete, change the pick color if (mDisplayMode != pPallet) { Point2I resolution = getRoot()->getExtent(); U32 buf_x = offset.x + mSelectorPos.x + 1; U32 buf_y = ( extent.y - ( offset.y + mSelectorPos.y + 1 ) ); if(GFX->getAdapterType() != OpenGL) buf_y = resolution.y - buf_y; GFXTexHandle bb( resolution.x, resolution.y, GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) ); Point2I tmpPt( buf_x, buf_y ); GFXTarget *targ = GFX->getActiveRenderTarget(); targ->resolveTo( bb ); GBitmap bmp( bb.getWidth(), bb.getHeight() ); bb.copyToBmp( &bmp ); //bmp.writePNGDebug( "foo.png" ); ColorI tmp; bmp.getColor( buf_x, buf_y, tmp ); mPickColor = (ColorF)tmp; // Now do onAction() if we are allowed if (mActionOnMove) onAction(); } } //render the children renderChildControls( offset, updateRect); }
void DebugDrawer::setupStateBlocks() { GFXStateBlockDesc d; d.setCullMode(GFXCullNone); mRenderZOnSB = GFX->createStateBlock(d); d.setZReadWrite(false); mRenderZOffSB = GFX->createStateBlock(d); }
void NavPath::renderSimple(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) { if(overrideMat) return; if(state->isReflectPass() || !(isSelected() || mAlwaysRender)) return; GFXDrawUtil *drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setZReadWrite(true, false); desc.setBlend(true); desc.setCullMode(GFXCullNone); if(isSelected()) { drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 5)); desc.setFillModeWireframe(); drawer->drawCube(desc, getWorldBox(), ColorI::BLACK); } desc.setZReadWrite(!mXray, false); ColorI pathColour(255, 0, 255); if(!mIsLooping) { desc.setFillModeSolid(); if(mFromSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mFrom, pathColour); if(mToSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mTo, pathColour); } GFXStateBlockRef sb = GFX->createStateBlock(desc); GFX->setStateBlock(sb); PrimBuild::color3i(pathColour.red, pathColour.green, pathColour.blue); PrimBuild::begin(GFXLineStrip, mPoints.size()); for (U32 i = 0; i < mPoints.size(); i++) PrimBuild::vertex3fv(mPoints[i]); PrimBuild::end(); if(mRenderSearch && getServerObject()) { NavPath *np = static_cast<NavPath*>(getServerObject()); if(np->mQuery && !dtStatusSucceed(np->mStatus)) { duDebugDrawTorque dd; dd.overrideColor(duRGBA(250, 20, 20, 255)); duDebugDrawNavMeshNodes(&dd, *np->mQuery); dd.render(); } } }
bool BasicClouds::onAdd() { if ( !Parent::onAdd() ) return false; setGlobalBounds(); resetWorldBox(); addToScene(); if ( isClientObject() ) { _initTexture(); _initBuffers(); // Find ShaderData ShaderData *shaderData; mShader = Sim::findObject( "BasicCloudsShader", shaderData ) ? shaderData->getShader() : NULL; if ( !mShader ) { Con::errorf( "BasicClouds::onAdd - could not find BasicCloudsShader" ); return false; } // Create ShaderConstBuffer and Handles mShaderConsts = mShader->allocConstBuffer(); mModelViewProjSC = mShader->getShaderConstHandle( "$modelView" ); mTimeSC = mShader->getShaderConstHandle( "$accumTime" ); mTexScaleSC = mShader->getShaderConstHandle( "$texScale" ); mTexDirectionSC = mShader->getShaderConstHandle( "$texDirection" ); mTexOffsetSC = mShader->getShaderConstHandle( "$texOffset" ); mDiffuseMapSC = mShader->getShaderConstHandle( "$diffuseMap" ); // Create StateBlocks GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setBlend( true ); desc.setZReadWrite( false, false ); desc.samplersDefined = true; desc.samplers[0].addressModeU = GFXAddressWrap; desc.samplers[0].addressModeV = GFXAddressWrap; desc.samplers[0].addressModeW = GFXAddressWrap; desc.samplers[0].magFilter = GFXTextureFilterLinear; desc.samplers[0].minFilter = GFXTextureFilterLinear; desc.samplers[0].mipFilter = GFXTextureFilterLinear; desc.samplers[0].textureColorOp = GFXTOPModulate; mStateblock = GFX->createStateBlock( desc ); } return true; }
void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* overrideMat) { if (overrideMat) return; if (mLightningSB.isNull()) { GFXStateBlockDesc desc; desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendOne); desc.setCullMode(GFXCullNone); desc.zWriteEnable = false; desc.samplersDefined = true; desc.samplers[0].magFilter = GFXTextureFilterLinear; desc.samplers[0].minFilter = GFXTextureFilterLinear; desc.samplers[0].addressModeU = GFXAddressWrap; desc.samplers[0].addressModeV = GFXAddressWrap; mLightningSB = GFX->createStateBlock(desc); } GFX->setStateBlock(mLightningSB); Strike* walk = mStrikeListHead; while (walk != NULL) { GFX->setTexture(0, mDataBlock->strikeTextures[0]); for( U32 i=0; i<3; i++ ) { if( walk->bolt[i].isFading ) { F32 alpha = 1.0f - walk->bolt[i].percentFade; if( alpha < 0.0f ) alpha = 0.0f; PrimBuild::color4f( fadeColor.red, fadeColor.green, fadeColor.blue, alpha ); } else { PrimBuild::color4f( color.red, color.green, color.blue, color.alpha ); } walk->bolt[i].render( state->getCameraPosition() ); } walk = walk->next; } //GFX->setZWriteEnable(true); //GFX->setAlphaTestEnable(false); //GFX->setAlphaBlendEnable(false); }
void GFXDrawUtil::_setupStateBlocks() { // DrawBitmapStretchSR GFXStateBlockDesc bitmapStretchSR; bitmapStretchSR.setCullMode(GFXCullNone); bitmapStretchSR.setZReadWrite(false); bitmapStretchSR.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); bitmapStretchSR.samplersDefined = true; // Linear: Create wrap SB bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getWrapLinear(); mBitmapStretchWrapLinearSB = mDevice->createStateBlock(bitmapStretchSR); // Linear: Create clamp SB bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear(); mBitmapStretchLinearSB = mDevice->createStateBlock(bitmapStretchSR); // Point: bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint; bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint; bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint; // Point: Create clamp SB, last created clamped so no work required here mBitmapStretchSB = mDevice->createStateBlock(bitmapStretchSR); // Point: Create wrap SB, have to do this manually because getWrapLinear doesn't bitmapStretchSR.samplers[0].addressModeU = GFXAddressWrap; bitmapStretchSR.samplers[0].addressModeV = GFXAddressWrap; bitmapStretchSR.samplers[0].addressModeW = GFXAddressWrap; mBitmapStretchWrapSB = mDevice->createStateBlock(bitmapStretchSR); GFXStateBlockDesc rectFill; rectFill.setCullMode(GFXCullNone); rectFill.setZReadWrite(false); rectFill.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); mRectFillSB = mDevice->createStateBlock(rectFill); }
void NavMesh::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) { if(overrideMat) return; if(state->isReflectPass()) return; PROFILE_SCOPE(NavMesh_Render); GFXDrawUtil *drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setZReadWrite(true, false); desc.setBlend(true); desc.setCullMode(GFXCullNone); drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 45)); desc.setFillModeWireframe(); drawer->drawCube(desc, getWorldBox(), ColorI::BLACK); // Recast debug draw duDebugDrawTorque dd; NetObject *no = getServerObject(); if(no && isSelected()) { NavMesh *n = static_cast<NavMesh*>(no); RenderMode mode = mRenderMode; bool build = n->mBuilding; if(build) { mode = RENDER_NAVMESH; dd.overrideColour(duRGBA(255, 0, 0, 80)); } n->mNavMeshLock.lock(); switch(mode) { case RENDER_NAVMESH: if(n->nm) duDebugDrawNavMesh (&dd, *n->nm, 0); break; case RENDER_CONTOURS: if(n->cs) duDebugDrawContours (&dd, *n->cs); break; case RENDER_POLYMESH: if(n->pm) duDebugDrawPolyMesh (&dd, *n->pm); break; case RENDER_DETAILMESH: if(n->pmd) duDebugDrawPolyMeshDetail (&dd, *n->pmd); break; case RENDER_PORTALS: if(n->nm) duDebugDrawNavMeshPortals (&dd, *n->nm); break; } if(n->cs && mRenderConnections && !build) duDebugDrawRegionConnections(&dd, *n->cs); if(n->mInPolys && mRenderInput && !build) n->mInPolys->render(); n->mNavMeshLock.unlock(); } }
bool GuiRoadEditorCtrl::onAdd() { if( !Parent::onAdd() ) return false; mRoadSet = DecalRoad::getServerSet(); GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setBlend(false); desc.setZReadWrite( false, false ); mZDisableSB = GFX->createStateBlock(desc); return true; }
void EditTSCtrl::renderMissionArea() { MissionArea* obj = MissionArea::getServerObject(); if ( !obj ) return; if ( !mRenderMissionArea && !obj->isSelected() ) return; GFXDEBUGEVENT_SCOPE( Editor_renderMissionArea, ColorI::WHITE ); F32 minHeight = 0.0f; F32 maxHeight = 0.0f; TerrainBlock* terrain = getActiveTerrain(); if ( terrain ) { terrain->getMinMaxHeight( &minHeight, &maxHeight ); Point3F pos = terrain->getPosition(); maxHeight += pos.z + mMissionAreaHeightAdjust; minHeight += pos.z - mMissionAreaHeightAdjust; } const RectI& area = obj->getArea(); Box3F areaBox( area.point.x, area.point.y, minHeight, area.point.x + area.extent.x, area.point.y + area.extent.y, maxHeight ); GFXDrawUtil* drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setBlend( true ); desc.setZReadWrite( false, false ); desc.setFillModeSolid(); drawer->drawCube( desc, areaBox, mMissionAreaFillColor ); desc.setFillModeWireframe(); drawer->drawCube( desc, areaBox, mMissionAreaFrameColor ); }
void PxCloth::_initMaterial() { SAFE_DELETE( mMatInst ); Material *material = NULL; if (mMaterialName.isNotEmpty() ) Sim::findObject( mMaterialName, material ); if ( material ) mMatInst = material->createMatInstance(); else mMatInst = MATMGR->createMatInstance( "WarningMaterial" ); GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); mMatInst->addStateBlockDesc( desc ); mMatInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTT>() ); }
BaseMatInstance * MaterialManager::createWarningMatInstance() { Material *warnMat = static_cast<Material*>(Sim::findObject("WarningMaterial")); BaseMatInstance *warnMatInstance = NULL; if( warnMat != NULL ) { warnMatInstance = warnMat->createMatInstance(); GFXStateBlockDesc desc; desc.setCullMode(GFXCullNone); warnMatInstance->addStateBlockDesc(desc); warnMatInstance->init( getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTTB>() ); } return warnMatInstance; }
bool GuiNavEditorCtrl::onAdd() { if(!Parent::onAdd()) return false; GFXStateBlockDesc desc; desc.fillMode = GFXFillSolid; desc.setBlend(false); desc.setZReadWrite(false, false); desc.setCullMode(GFXCullNone); mZDisableSB = GFX->createStateBlock(desc); desc.setZReadWrite(true, true); mZEnableSB = GFX->createStateBlock(desc); SceneManager::getPreRenderSignal().notify(this, &GuiNavEditorCtrl::_prepRenderImage); return true; }
void Portal::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* overrideMat ) { if( overrideMat ) return; // Update geometry if necessary. if( mIsGeometryDirty ) _updateGeometry(); // Render portal polygon. GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); desc.setCullMode( GFXCullNone ); PlaneF::Side viewSide = mPortalPlane.whichSide( state->getCameraPosition() ); ColorI color; switch( mClassification ) { case InvalidPortal: color = ColorI( 255, 255, 255, 45 ); break; case ExteriorPortal: color = viewSide == PlaneF::Front ? ColorI( 0, 128, 128, 45 ) : ColorI( 0, 255, 255, 45 ); break; case InteriorPortal: color = viewSide == PlaneF::Front ? ColorI( 128, 128, 0, 45 ) : ColorI( 255, 255, 0, 45 ); break; } GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), color ); desc.setFillModeWireframe(); GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), ColorF::RED ); // Render rest. Parent::_renderObject( ri, state, overrideMat ); }
void SFXEmitter::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat ) { // Check to see if the emitter is in range and playing // and assign a proper color depending on this. ColorI color; if( _getPlaybackStatus() == SFXStatusPlaying ) { if( isInRange() ) color = smRenderColorPlayingInRange; else color = smRenderColorPlayingOutOfRange; } else { if( isInRange() ) color = smRenderColorStoppedInRange; else color = smRenderColorStoppedOutOfRange; } // Draw the cube. GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); desc.setCullMode( GFXCullNone ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawCube( desc, Point3F( 0.5f, 0.5f, 0.5f ), getBoxCenter(), color ); // Render visual feedback for 3D sounds. if( ( smRenderEmitters || isSelected() ) && is3D() ) _render3DVisualFeedback(); }
bool GuiTerrPreviewCtrl::onAdd() { if(Parent::onAdd() == false) { return false; } SimObject* inTerrEditor = Sim::findObject("ETerrainEditor"); if(!inTerrEditor) { Con::errorf(ConsoleLogEntry::General, "TerrainEditor::onAdd: failed to load Terrain Editor"); return false; } mTerrainEditor = dynamic_cast<TerrainEditor*>(inTerrEditor); GFXStateBlockDesc desc; desc.setBlend(false, GFXBlendOne, GFXBlendZero); desc.samplersDefined = true; desc.samplers[0].addressModeU = GFXAddressWrap; desc.samplers[0].addressModeV = GFXAddressWrap; desc.samplers[0].textureColorOp = GFXTOPSelectARG1; desc.samplers[0].colorArg1 = GFXTATexture; desc.setCullMode(GFXCullNone); desc.setZReadWrite(false); mTerrainBitmapStateBlock = GFX->createStateBlock(desc); desc.samplers[0].textureColorOp = GFXTOPDisable; mControlsStateBlock = GFX->createStateBlock(desc); return true; }
void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) { if (mStateBlock.isNull()) { GFXStateBlockDesc desc; desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); desc.setZReadWrite(false); desc.zWriteEnable = false; desc.setCullMode(GFXCullNone); mStateBlock = GFX->createStateBlock(desc); } RectI boundsRect(offset, getExtent()); renderColorBox(boundsRect); if (mPositionChanged || mBitmap == NULL) { bool nullBitmap = false; if (mPositionChanged == false && mBitmap == NULL) nullBitmap = true; mPositionChanged = false; Point2I extent = getRoot()->getExtent(); // If we are anything but a pallete, change the pick color if (mDisplayMode != pPallet) { Point2I resolution = getRoot()->getExtent(); U32 buf_x = offset.x + mSelectorPos.x + 1; U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1)); GFXTexHandle bb( resolution.x, resolution.y, GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) ); Point2I tmpPt(buf_x, buf_y); GFXTarget *targ = GFX->getActiveRenderTarget(); targ->resolveTo(bb); if (mBitmap) { delete mBitmap; mBitmap = NULL; } mBitmap = new GBitmap(bb.getWidth(), bb.getHeight()); bb.copyToBmp(mBitmap); if (!nullBitmap) { if (mSelectColor) { Point2I pos = findColor(mSetColor, offset, resolution, *mBitmap); mSetColor = mSetColor.BLACK; mSelectColor = false; setSelectorPos(pos); } else { ColorI tmp; mBitmap->getColor(buf_x, buf_y, tmp); mPickColor = (ColorF)tmp; // Now do onAction() if we are allowed if (mActionOnMove) onAction(); } } } } //render the children renderChildControls(offset, updateRect); }
void drawActor( NxActor *inActor ) { GFXDrawUtil *drawer = GFX->getDrawUtil(); //drawer->setZRead( false ); // Determine alpha we render shapes with. const U8 enabledAlpha = 255; const U8 disabledAlpha = 100; U8 renderAlpha = inActor->readActorFlag( NX_AF_DISABLE_COLLISION ) ? disabledAlpha : enabledAlpha; // Determine color we render actors and shapes with. ColorI actorColor( 0, 0, 255, 200 ); ColorI shapeColor = ( inActor->isSleeping() ? ColorI( 0, 0, 255, renderAlpha ) : ColorI( 255, 0, 255, renderAlpha ) ); MatrixF actorMat(true); inActor->getGlobalPose().getRowMajor44( actorMat ); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); desc.setCullMode( GFXCullNone ); // Draw an xfm gizmo for the actor's globalPose... //drawer->drawTransform( desc, actorMat, Point3F::One, actorColor ); // Loop through and render all the actor's shapes.... NxShape *const*pShapeArray = inActor->getShapes(); U32 numShapes = inActor->getNbShapes(); for ( U32 i = 0; i < numShapes; i++ ) { const NxShape *shape = pShapeArray[i]; Point3F shapePos = pxCast<Point3F>( shape->getGlobalPosition() ); MatrixF shapeMat(true); shape->getGlobalPose().getRowMajor44(shapeMat); shapeMat.setPosition( Point3F::Zero ); switch ( shape->getType() ) { case NX_SHAPE_SPHERE: { NxSphereShape *sphere = (NxSphereShape*)shape; drawer->drawSphere( desc, sphere->getRadius(), shapePos, shapeColor ); break; } case NX_SHAPE_BOX: { NxBoxShape *box = (NxBoxShape*)shape; Point3F size = pxCast<Point3F>( box->getDimensions() ); drawer->drawCube( desc, size*2, shapePos, shapeColor, &shapeMat ); break; } case NX_SHAPE_CAPSULE: { shapeMat.mul( MatrixF( EulerF( mDegToRad(90.0f), mDegToRad(90.0f), 0 ) ) ); NxCapsuleShape *capsule = (NxCapsuleShape*)shape; drawer->drawCapsule( desc, shapePos, capsule->getRadius(), capsule->getHeight(), shapeColor, &shapeMat ); break; } default: { break; } } } //drawer->clearZDefined(); }
void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect) { // Save the current transforms so we can restore // it for child control rendering below. GFXTransformSaver saver; bool renderingToTarget = false; if(!processCameraQuery(&mLastCameraQuery)) { // We have no camera, but render the GUI children // anyway. This makes editing GuiTSCtrl derived // controls easier in the GuiEditor. renderChildControls( offset, updateRect ); return; } GFXTargetRef origTarget = GFX->getActiveRenderTarget(); // Set up the appropriate render style U32 prevRenderStyle = GFX->getCurrentRenderStyle(); Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset(); Point2I renderSize = getExtent(); if(mRenderStyle == RenderStyleStereoSideBySide) { GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide); GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset); GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset); if (!mLastCameraQuery.hasStereoTargets) { // Need to calculate our current viewport here mLastCameraQuery.stereoViewports[0] = updateRect; mLastCameraQuery.stereoViewports[0].extent.x /= 2; mLastCameraQuery.stereoViewports[1] = mLastCameraQuery.stereoViewports[0]; mLastCameraQuery.stereoViewports[1].point.x += mLastCameraQuery.stereoViewports[1].extent.x; } if (!mLastCameraQuery.hasFovPort) { // Need to make our own fovPort mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery); mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery); } GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes GFX->setSteroViewports(mLastCameraQuery.stereoViewports); GFX->setStereoTargets(mLastCameraQuery.stereoTargets); MatrixF myTransforms[2]; if (smUseLatestDisplayTransform) { // Use the view matrix determined from the display device myTransforms[0] = mLastCameraQuery.eyeTransforms[0]; myTransforms[1] = mLastCameraQuery.eyeTransforms[1]; } else { // Use the view matrix determined from the control object myTransforms[0] = mLastCameraQuery.cameraMatrix; myTransforms[1] = mLastCameraQuery.cameraMatrix; QuatF qrot = mLastCameraQuery.cameraMatrix; Point3F pos = mLastCameraQuery.cameraMatrix.getPosition(); Point3F rotEyePos; myTransforms[0].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[0], &rotEyePos)); myTransforms[1].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[1], &rotEyePos)); } GFX->setStereoEyeTransforms(myTransforms); // Allow render size to originate from the render target if (mLastCameraQuery.stereoTargets[0]) { renderSize = mLastCameraQuery.stereoViewports[0].extent; renderingToTarget = true; } } else { GFX->setCurrentRenderStyle(GFXDevice::RS_Standard); } if ( mReflectPriority > 0 ) { // Get the total reflection priority. F32 totalPriority = 0; for ( U32 i=0; i < smAwakeTSCtrls.size(); i++ ) if ( smAwakeTSCtrls[i]->isVisible() ) totalPriority += smAwakeTSCtrls[i]->mReflectPriority; REFLECTMGR->update( mReflectPriority / totalPriority, getExtent(), mLastCameraQuery ); } if(mForceFOV != 0) mLastCameraQuery.fov = mDegToRad(mForceFOV); if(mCameraZRot) { MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot))); mLastCameraQuery.cameraMatrix.mul(rotMat); } Frustum frustum; if(mRenderStyle == RenderStyleStereoSideBySide) { // NOTE: these calculations are essentially overridden later by the fov port settings when rendering each eye. MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]); } else { // set up the camera and viewport stuff: F32 wwidth; F32 wheight; F32 renderWidth = F32(renderSize.x); F32 renderHeight = F32(renderSize.y); F32 aspectRatio = renderWidth / renderHeight; // Use the FOV to calculate the viewport height scale // then generate the width scale from the aspect ratio. if(!mLastCameraQuery.ortho) { wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f); wwidth = aspectRatio * wheight; } else { wheight = mLastCameraQuery.fov; wwidth = aspectRatio * wheight; } F32 hscale = wwidth * 2.0f / renderWidth; F32 vscale = wheight * 2.0f / renderHeight; F32 left = (updateRect.point.x - offset.x) * hscale - wwidth; F32 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth; F32 top = wheight - vscale * (updateRect.point.y - offset.y); F32 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y); frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane ); } // Manipulate the frustum for tiled screenshots const bool screenShotMode = gScreenShot && gScreenShot->isPending(); if ( screenShotMode ) { gScreenShot->tileFrustum( frustum ); GFX->setViewMatrix(MatrixF::Identity); } RectI tempRect = updateRect; if (!renderingToTarget) { #ifdef TORQUE_OS_MAC Point2I screensize = getRoot()->getWindowSize(); tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y); #endif GFX->setViewport( tempRect ); } else { // Activate stereo RT GFX->activateStereoTarget(-1); } // Clear the zBuffer so GUI doesn't hose object rendering accidentally GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 ); //GFX->clear( GFXClearTarget, ColorI(255,0,0), 1.0f, 0); GFX->setFrustum( frustum ); if(mLastCameraQuery.ortho) { mOrthoWidth = frustum.getWidth(); mOrthoHeight = frustum.getHeight(); } // We're going to be displaying this render at size of this control in // pixels - let the scene know so that it can calculate e.g. reflections // correctly for that final display result. gClientSceneGraph->setDisplayTargetResolution(renderSize); // Set the GFX world matrix to the world-to-camera transform, but don't // change the cameraMatrix in mLastCameraQuery. This is because // mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world // transform. In-place invert would save a copy but mess up any GUIs that // depend on that value. MatrixF worldToCamera = mLastCameraQuery.cameraMatrix; worldToCamera.inverse(); GFX->setWorldMatrix( worldToCamera ); mSaveProjection = GFX->getProjectionMatrix(); mSaveModelview = GFX->getWorldMatrix(); mSaveViewport = updateRect; mSaveWorldToScreenScale = GFX->getWorldToScreenScale(); mSaveFrustum = GFX->getFrustum(); mSaveFrustum.setTransform( mLastCameraQuery.cameraMatrix ); // Set the default non-clip projection as some // objects depend on this even in non-reflect cases. gClientSceneGraph->setNonClipProjection( mSaveProjection ); // Give the post effect manager the worldToCamera, and cameraToScreen matrices PFXMGR->setFrameMatrices( mSaveModelview, mSaveProjection ); renderWorld(updateRect); DebugDrawer::get()->render(); // Render the canvas overlay if its available if (mRenderStyle == RenderStyleStereoSideBySide && mStereoGuiTarget.getPointer()) { GFXDEBUGEVENT_SCOPE( StereoGui_Render, ColorI( 255, 0, 0 ) ); MatrixF proj(1); Frustum originalFrustum = GFX->getFrustum(); GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0); const FovPort *currentFovPort = GFX->getStereoFovPort(); const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms(); const Point3F *eyeOffset = GFX->getStereoEyeOffsets(); Frustum gfxFrustum = originalFrustum; for (U32 i=0; i<2; i++) { GFX->activateStereoTarget(i); MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]); GFX->setFrustum(gfxFrustum); MatrixF eyeWorldTrans(1); eyeWorldTrans.setPosition(Point3F(eyeOffset[i].x,eyeOffset[i].y,eyeOffset[i].z)); MatrixF eyeWorld(1); eyeWorld.mul(eyeWorldTrans); eyeWorld.inverse(); GFX->setWorldMatrix(eyeWorld); GFX->setViewMatrix(MatrixF::Identity); if (!mStereoOverlayVB.getPointer()) { mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic); GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4); F32 texLeft = 0.0f; F32 texRight = 1.0f; F32 texTop = 1.0f; F32 texBottom = 0.0f; F32 rectRatio = gfxFrustum.getWidth() / gfxFrustum.getHeight(); F32 rectWidth = gfxFrustum.getWidth() * TS_OVERLAY_SCREEN_WIDTH; F32 rectHeight = rectWidth * rectRatio; F32 screenLeft = -rectWidth * 0.5; F32 screenRight = rectWidth * 0.5; F32 screenTop = -rectHeight * 0.5; F32 screenBottom = rectHeight * 0.5; const F32 fillConv = 0.0f; const F32 frustumDepthAdjusted = gfxFrustum.getNearDist() + 0.012; verts[0].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenTop - fillConv ); verts[1].point.set( screenRight - fillConv, frustumDepthAdjusted, screenTop - fillConv ); verts[2].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenBottom - fillConv ); verts[3].point.set( screenRight - fillConv, frustumDepthAdjusted, screenBottom - fillConv ); verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255); verts[0].texCoord.set( texLeft, texTop ); verts[1].texCoord.set( texRight, texTop ); verts[2].texCoord.set( texLeft, texBottom ); verts[3].texCoord.set( texRight, texBottom ); mStereoOverlayVB.unlock(); } if (!mStereoGuiSB.getPointer()) { // DrawBitmapStretchSR GFXStateBlockDesc bitmapStretchSR; bitmapStretchSR.setCullMode(GFXCullNone); bitmapStretchSR.setZReadWrite(false, false); bitmapStretchSR.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); bitmapStretchSR.samplersDefined = true; bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear(); bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint; bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint; bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint; mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR); } GFX->setVertexBuffer(mStereoOverlayVB); GFX->setStateBlock(mStereoGuiSB); GFX->setTexture( 0, texObject ); GFX->setupGenericShaders( GFXDevice::GSModColorTexture ); GFX->drawPrimitive( GFXTriangleStrip, 0, 2 ); } } // Restore the previous matrix state before // we begin rendering the child controls. saver.restore(); // Restore the render style and any stereo parameters GFX->setActiveRenderTarget(origTarget); GFX->setCurrentRenderStyle(prevRenderStyle); GFX->setCurrentProjectionOffset(prevProjectionOffset); if(mRenderStyle == RenderStyleStereoSideBySide && gLastStereoTexture) { GFX->setClipRect(updateRect); GFX->getDrawUtil()->drawBitmapStretch(gLastStereoTexture, updateRect); } // Allow subclasses to render 2D elements. GFX->setClipRect(updateRect); renderGui( offset, updateRect ); if (shouldRenderChildControls()) { renderChildControls(offset, updateRect); } smFrameCount++; }
void TSShapeInstance::renderDebugNormals( F32 normalScalar, S32 dl ) { if ( dl < 0 ) return; AssertFatal( dl >= 0 && dl < mShape->details.size(), "TSShapeInstance::renderDebugNormals() - Bad detail level!" ); static GFXStateBlockRef sb; if ( sb.isNull() ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setZReadWrite( true ); desc.zWriteEnable = false; desc.vertexColorEnable = true; sb = GFX->createStateBlock( desc ); } GFX->setStateBlock( sb ); const TSDetail *detail = &mShape->details[dl]; const S32 ss = detail->subShapeNum; if ( ss < 0 ) return; const S32 start = mShape->subShapeFirstObject[ss]; const S32 end = start + mShape->subShapeNumObjects[ss]; for ( S32 i = start; i < end; i++ ) { MeshObjectInstance *meshObj = &mMeshObjects[i]; if ( !meshObj ) continue; const MatrixF &meshMat = meshObj->getTransform(); // Then go through each TSMesh... U32 m = 0; for( TSMesh *mesh = meshObj->getMesh(m); mesh != NULL; mesh = meshObj->getMesh(m++) ) { // and pull out the list of normals. const U32 numNrms = mesh->mNumVerts; PrimBuild::begin( GFXLineList, 2 * numNrms ); for ( U32 n = 0; n < numNrms; n++ ) { Point3F norm = mesh->mVertexData[n].normal(); Point3F vert = mesh->mVertexData[n].vert(); meshMat.mulP( vert ); meshMat.mulV( norm ); // Then render them. PrimBuild::color4f( mFabs( norm.x ), mFabs( norm.y ), mFabs( norm.z ), 1.0f ); PrimBuild::vertex3fv( vert ); PrimBuild::vertex3fv( vert + (norm * normalScalar) ); } PrimBuild::end(); } } }
bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials, Pass *pass, bool firstPass, bool prePassMat, bool reflectMat, bool baseOnly ) { if ( GFX->getPixelShaderVersion() < 3.0f ) baseOnly = true; // NOTE: At maximum we only try to combine sgMaxTerrainMaterialsPerPass materials // into a single pass. This is sub-optimal for the simplest // cases, but the most common case results in much fewer // shader generation failures and permutations leading to // faster load time and less hiccups during gameplay. U32 matCount = getMin( sgMaxTerrainMaterialsPerPass, materials->size() ); Vector<GFXTexHandle> normalMaps; // See if we're currently running under the // basic lighting manager. // // TODO: This seems ugly... we should trigger // features like this differently in the future. // bool useBLM = dStrcmp( LIGHTMGR->getId(), "BLM" ) == 0; // Do we need to disable normal mapping? const bool disableNormalMaps = MATMGR->getExclusionFeatures().hasFeature( MFT_NormalMap ) || useBLM; // How about parallax? const bool disableParallaxMaps = GFX->getPixelShaderVersion() < 3.0f || MATMGR->getExclusionFeatures().hasFeature( MFT_Parallax ); // Has advanced lightmap support been enabled for prepass. bool advancedLightmapSupport = false; if ( prePassMat ) { // This sucks... but it works. AdvancedLightBinManager *lightBin; if ( Sim::findObject( "AL_LightBinMgr", lightBin ) ) advancedLightmapSupport = lightBin->MRTLightmapsDuringPrePass(); } // Loop till we create a valid shader! while( true ) { FeatureSet features; features.addFeature( MFT_VertTransform ); if ( prePassMat ) { features.addFeature( MFT_EyeSpaceDepthOut ); features.addFeature( MFT_PrePassConditioner ); features.addFeature( MFT_DeferredTerrainBaseMap ); features.addFeature(MFT_isDeferred); if ( advancedLightmapSupport ) features.addFeature( MFT_RenderTarget3_Zero ); } else { features.addFeature( MFT_TerrainBaseMap ); features.addFeature( MFT_RTLighting ); // The HDR feature is always added... it will compile out // if HDR is not enabled in the engine. features.addFeature( MFT_HDROut ); } features.addFeature(MFT_DeferredTerrainBlankInfoMap); // Enable lightmaps and fogging if we're in BL. if ( reflectMat || useBLM ) { features.addFeature( MFT_Fog ); features.addFeature( MFT_ForwardShading ); } if ( useBLM ) features.addFeature( MFT_TerrainLightMap ); // The additional passes need to be lerp blended into the // target to maintain the results of the previous passes. if ( !firstPass ) features.addFeature( MFT_TerrainAdditive ); normalMaps.clear(); pass->materials.clear(); // Now add all the material layer features. for ( U32 i=0; i < matCount && !baseOnly; i++ ) { TerrainMaterial *mat = (*materials)[i]->mat; if ( mat == NULL ) continue; // We only include materials that // have more than a base texture. if ( mat->getDetailSize() <= 0 || mat->getDetailDistance() <= 0 || mat->getDetailMap().isEmpty() ) continue; S32 featureIndex = pass->materials.size(); // check for macro detail texture if ( !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) ) { if(prePassMat) features.addFeature( MFT_DeferredTerrainMacroMap, featureIndex ); else features.addFeature( MFT_TerrainMacroMap, featureIndex ); } if(prePassMat) features.addFeature( MFT_DeferredTerrainDetailMap, featureIndex ); else features.addFeature( MFT_TerrainDetailMap, featureIndex ); pass->materials.push_back( (*materials)[i] ); normalMaps.increment(); // Skip normal maps if we need to. if ( !disableNormalMaps && mat->getNormalMap().isNotEmpty() ) { features.addFeature( MFT_TerrainNormalMap, featureIndex ); normalMaps.last().set( mat->getNormalMap(), &GFXDefaultStaticNormalMapProfile, "TerrainCellMaterial::_createPass() - NormalMap" ); if ( normalMaps.last().getFormat() == GFXFormatDXT5 ) features.addFeature( MFT_IsDXTnm, featureIndex ); // Do we need and can we do parallax mapping? if ( !disableParallaxMaps && mat->getParallaxScale() > 0.0f && !mat->useSideProjection() ) features.addFeature( MFT_TerrainParallaxMap, featureIndex ); } // Is this layer got side projection? if ( mat->useSideProjection() ) features.addFeature( MFT_TerrainSideProject, featureIndex ); } MaterialFeatureData featureData; featureData.features = features; featureData.materialFeatures = features; // Check to see how many vertex shader output // registers we're gonna need. U32 numTex = 0; U32 numTexReg = 0; for ( U32 i=0; i < features.getCount(); i++ ) { S32 index; const FeatureType &type = features.getAt( i, &index ); ShaderFeature* sf = FEATUREMGR->getByType( type ); if ( !sf ) continue; sf->setProcessIndex( index ); ShaderFeature::Resources res = sf->getResources( featureData ); numTex += res.numTex; numTexReg += res.numTexReg; } // Can we build the shader? // // NOTE: The 10 is sort of an abitrary SM 3.0 // limit. Its really supposed to be 11, but that // always fails to compile so far. // if ( numTex < GFX->getNumSamplers() && numTexReg <= 10 ) { // NOTE: We really shouldn't be getting errors building the shaders, // but we can generate more instructions than the ps_2_x will allow. // // There is no way to deal with this case that i know of other than // letting the compile fail then recovering by trying to build it // with fewer materials. // // We normally disable the shader error logging so that the user // isn't fooled into thinking there is a real bug. That is until // we get down to a single material. If a single material case // fails it means it cannot generate any passes at all! const bool logErrors = matCount == 1; GFXShader::setLogging( logErrors, true ); pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL, mSamplerNames ); } // If we got a shader then we can continue. if ( pass->shader ) break; // If the material count is already 1 then this // is a real shader error... give up! if ( matCount <= 1 ) return false; // If we failed we next try half the input materials // so that we can more quickly arrive at a valid shader. matCount -= matCount / 2; } // Setup the constant buffer. pass->consts = pass->shader->allocConstBuffer(); // Prepare the basic constants. pass->modelViewProjConst = pass->shader->getShaderConstHandle( "$modelview" ); pass->worldViewOnly = pass->shader->getShaderConstHandle( "$worldViewOnly" ); pass->viewToObj = pass->shader->getShaderConstHandle( "$viewToObj" ); pass->eyePosWorldConst = pass->shader->getShaderConstHandle( "$eyePosWorld" ); pass->eyePosConst = pass->shader->getShaderConstHandle( "$eyePos" ); pass->vEyeConst = pass->shader->getShaderConstHandle( "$vEye" ); pass->layerSizeConst = pass->shader->getShaderConstHandle( "$layerSize" ); pass->objTransConst = pass->shader->getShaderConstHandle( "$objTrans" ); pass->worldToObjConst = pass->shader->getShaderConstHandle( "$worldToObj" ); pass->lightInfoBufferConst = pass->shader->getShaderConstHandle( "$lightInfoBuffer" ); pass->baseTexMapConst = pass->shader->getShaderConstHandle( "$baseTexMap" ); pass->layerTexConst = pass->shader->getShaderConstHandle( "$layerTex" ); pass->fogDataConst = pass->shader->getShaderConstHandle( "$fogData" ); pass->fogColorConst = pass->shader->getShaderConstHandle( "$fogColor" ); pass->lightMapTexConst = pass->shader->getShaderConstHandle( "$lightMapTex" ); pass->oneOverTerrainSize = pass->shader->getShaderConstHandle( "$oneOverTerrainSize" ); pass->squareSize = pass->shader->getShaderConstHandle( "$squareSize" ); pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParamslightInfoBuffer" ); // Now prepare the basic stateblock. GFXStateBlockDesc desc; if ( !firstPass ) { desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha ); // If this is the prepass then we don't want to // write to the last two color channels (where // depth is usually encoded). // // This trick works in combination with the // MFT_TerrainAdditive feature to lerp the // output normal with the previous pass. // if ( prePassMat ) desc.setColorWrites( true, true, true, false ); } // We write to the zbuffer if this is a prepass // material or if the prepass is disabled. desc.setZReadWrite( true, !MATMGR->getPrePassEnabled() || prePassMat || reflectMat ); desc.samplersDefined = true; if ( pass->baseTexMapConst->isValid() ) desc.samplers[pass->baseTexMapConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear(); if ( pass->layerTexConst->isValid() ) desc.samplers[pass->layerTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint(); if ( pass->lightInfoBufferConst->isValid() ) desc.samplers[pass->lightInfoBufferConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint(); if ( pass->lightMapTexConst->isValid() ) desc.samplers[pass->lightMapTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear(); const U32 maxAnisotropy = MATMGR->getDefaultAnisotropy(); // Finally setup the material specific shader // constants and stateblock state. // // NOTE: If this changes be sure to check TerrainCellMaterial::_updateDefaultAnisotropy // to see if it needs the same changes. // for ( U32 i=0; i < pass->materials.size(); i++ ) { MaterialInfo *matInfo = pass->materials[i]; matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) ); matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) ); matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) ); if ( matInfo->detailTexConst->isValid() ) { const S32 sampler = matInfo->detailTexConst->getSamplerRegister(); desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear(); desc.samplers[sampler].magFilter = GFXTextureFilterLinear; desc.samplers[sampler].mipFilter = GFXTextureFilterLinear; if ( maxAnisotropy > 1 ) { desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic; desc.samplers[sampler].maxAnisotropy = maxAnisotropy; } else desc.samplers[sampler].minFilter = GFXTextureFilterLinear; matInfo->detailTex.set( matInfo->mat->getDetailMap(), &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - DetailMap" ); } matInfo->macroInfoVConst = pass->shader->getShaderConstHandle( avar( "$macroScaleAndFade%d", i ) ); matInfo->macroInfoPConst = pass->shader->getShaderConstHandle( avar( "$macroIdStrengthParallax%d", i ) ); matInfo->macroTexConst = pass->shader->getShaderConstHandle( avar( "$macroMap%d", i ) ); if ( matInfo->macroTexConst->isValid() ) { const S32 sampler = matInfo->macroTexConst->getSamplerRegister(); desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear(); desc.samplers[sampler].magFilter = GFXTextureFilterLinear; desc.samplers[sampler].mipFilter = GFXTextureFilterLinear; if ( maxAnisotropy > 1 ) { desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic; desc.samplers[sampler].maxAnisotropy = maxAnisotropy; } else desc.samplers[sampler].minFilter = GFXTextureFilterLinear; matInfo->macroTex.set( matInfo->mat->getMacroMap(), &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - MacroMap" ); } //end macro texture matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) ); if ( matInfo->normalTexConst->isValid() ) { const S32 sampler = matInfo->normalTexConst->getSamplerRegister(); desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear(); desc.samplers[sampler].magFilter = GFXTextureFilterLinear; desc.samplers[sampler].mipFilter = GFXTextureFilterLinear; if ( maxAnisotropy > 1 ) { desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic; desc.samplers[sampler].maxAnisotropy = maxAnisotropy; } else desc.samplers[sampler].minFilter = GFXTextureFilterLinear; matInfo->normalTex = normalMaps[i]; } } // Remove the materials we processed and leave the // ones that remain for the next pass. for ( U32 i=0; i < matCount; i++ ) { MaterialInfo *matInfo = materials->first(); if ( baseOnly || pass->materials.find_next( matInfo ) == -1 ) delete matInfo; materials->pop_front(); } // If we're doing prepass it requires some // special stencil settings for it to work. if ( prePassMat ) desc.addDesc( RenderPrePassMgr::getOpaqueStenciWriteDesc( false ) ); desc.setCullMode( GFXCullCCW ); pass->stateBlock = GFX->createStateBlock(desc); //reflection stateblock desc.setCullMode( GFXCullCW ); pass->reflectionStateBlock = GFX->createStateBlock(desc); // Create the wireframe state blocks. GFXStateBlockDesc wireframe( desc ); wireframe.fillMode = GFXFillWireframe; wireframe.setCullMode( GFXCullCCW ); pass->wireframeStateBlock = GFX->createStateBlock( wireframe ); return true; }
void TerrainCellMaterial::_updateDefaultAnisotropy() { // TODO: We need to split the stateblock initialization // from the shader constant lookup and pass setup in a // future version of terrain materials. // // For now use some custom code in a horrible loop to // change the anisotropy directly and fast. // const U32 maxAnisotropy = MATMGR->getDefaultAnisotropy(); Vector<TerrainCellMaterial*>::iterator iter = smAllMaterials.begin(); for ( ; iter != smAllMaterials.end(); iter++ ) { for ( U32 p=0; p < (*iter)->mPasses.size(); p++ ) { Pass &pass = (*iter)->mPasses[p]; // Start from the existing state block. GFXStateBlockDesc desc = pass.stateBlock->getDesc(); for ( U32 m=0; m < pass.materials.size(); m++ ) { const MaterialInfo *matInfo = pass.materials[m]; if ( matInfo->detailTexConst->isValid() ) { const S32 sampler = matInfo->detailTexConst->getSamplerRegister(); if ( maxAnisotropy > 1 ) { desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic; desc.samplers[sampler].maxAnisotropy = maxAnisotropy; } else desc.samplers[sampler].minFilter = GFXTextureFilterLinear; } if ( matInfo->macroTexConst->isValid() ) { const S32 sampler = matInfo->macroTexConst->getSamplerRegister(); if ( maxAnisotropy > 1 ) { desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic; desc.samplers[sampler].maxAnisotropy = maxAnisotropy; } else desc.samplers[sampler].minFilter = GFXTextureFilterLinear; } if ( matInfo->normalTexConst->isValid() ) { const S32 sampler = matInfo->normalTexConst->getSamplerRegister(); if ( maxAnisotropy > 1 ) { desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic; desc.samplers[sampler].maxAnisotropy = maxAnisotropy; } else desc.samplers[sampler].minFilter = GFXTextureFilterLinear; } } // for ( U32 m=0; m < pass.materials.size(); m++ ) // Set the updated stateblock. desc.setCullMode( GFXCullCCW ); pass.stateBlock = GFX->createStateBlock( desc ); //reflection desc.setCullMode( GFXCullCW ); pass.reflectionStateBlock = GFX->createStateBlock(desc); // Create the wireframe state blocks. GFXStateBlockDesc wireframe( desc ); wireframe.fillMode = GFXFillWireframe; wireframe.setCullMode( GFXCullCCW ); pass.wireframeStateBlock = GFX->createStateBlock( wireframe ); } // for ( U32 p=0; i < (*iter)->mPasses.size(); p++ ) } }
void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mat ) { GFXDrawUtil *drawer = GFX->getDrawUtil(); GFX->setTexture( 0, NULL ); // Render world box. if ( false ) { Box3F wbox( mWorldBox ); //if ( getServerObject() ) // Box3F wbox = static_cast<ConvexShape*>( getServerObject() )->mWorldBox; GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setFillModeWireframe(); drawer->drawCube( desc, wbox, ColorI::RED ); } const Vector< Point3F > &pointList = mGeometry.points; const Vector< ConvexShape::Face > &faceList = mGeometry.faces; // Render Edges. if ( false ) { GFXTransformSaver saver; //GFXFrustumSaver fsaver; MatrixF xfm( getRenderTransform() ); xfm.scale( getScale() ); GFX->multWorld( xfm ); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); GFX->setStateBlockByDesc( desc ); //MathUtils::getZBiasProjectionMatrix( 0.01f, state->getFrustum(), ) const Point3F &camFvec = state->getCameraTransform().getForwardVector(); for ( S32 i = 0; i < faceList.size(); i++ ) { const ConvexShape::Face &face = faceList[i]; const Vector< ConvexShape::Edge > &edgeList = face.edges; const Vector< U32 > &facePntList = face.points; PrimBuild::begin( GFXLineList, edgeList.size() * 2 ); PrimBuild::color( ColorI::WHITE * 0.8f ); for ( S32 j = 0; j < edgeList.size(); j++ ) { PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] - camFvec * 0.001f ); PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] - camFvec * 0.001f ); } PrimBuild::end(); } } ColorI faceColorsx[4] = { ColorI( 255, 0, 0 ), ColorI( 0, 255, 0 ), ColorI( 0, 0, 255 ), ColorI( 255, 0, 255 ) }; MatrixF objToWorld( mObjToWorld ); objToWorld.scale( mObjScale ); // Render faces centers/colors. if ( false ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); Point3F size( 0.1f ); for ( S32 i = 0; i < faceList.size(); i++ ) { ColorI color = faceColorsx[ i % 4 ]; S32 div = ( i / 4 ) * 4; if ( div > 0 ) color /= div; color.alpha = 255; Point3F pnt; objToWorld.mulP( faceList[i].centroid, &pnt ); drawer->drawCube( desc, size, pnt, color, NULL ); } } // Render winding order. if ( false ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setZReadWrite( true, false ); GFX->setStateBlockByDesc( desc ); U32 pointCount = 0; for ( S32 i = 0; i < faceList.size(); i++ ) pointCount += faceList[i].winding.size(); PrimBuild::begin( GFXLineList, pointCount * 2 ); for ( S32 i = 0; i < faceList.size(); i++ ) { for ( S32 j = 0; j < faceList[i].winding.size(); j++ ) { Point3F p0 = pointList[ faceList[i].points[ faceList[i].winding[j] ] ]; Point3F p1 = p0 + mSurfaces[ faceList[i].id ].getUpVector() * 0.75f * ( Point3F::One / mObjScale ); objToWorld.mulP( p0 ); objToWorld.mulP( p1 ); ColorI color = faceColorsx[ j % 4 ]; S32 div = ( j / 4 ) * 4; if ( div > 0 ) color /= div; color.alpha = 255; PrimBuild::color( color ); PrimBuild::vertex3fv( p0 ); PrimBuild::color( color ); PrimBuild::vertex3fv( p1 ); } } PrimBuild::end(); } // Render Points. if ( false ) { /* GFXTransformSaver saver; MatrixF xfm( getRenderTransform() ); xfm.scale( getScale() ); GFX->multWorld( xfm ); GFXStateBlockDesc desc; Point3F size( 0.05f ); */ } // Render surface transforms. if ( false ) { GFXStateBlockDesc desc; desc.setBlend( false ); desc.setZReadWrite( true, true ); Point3F scale(mNormalLength); for ( S32 i = 0; i < mSurfaces.size(); i++ ) { MatrixF objToWorld( mObjToWorld ); objToWorld.scale( mObjScale ); MatrixF renderMat; renderMat.mul( objToWorld, mSurfaces[i] ); renderMat.setPosition( renderMat.getPosition() + renderMat.getUpVector() * 0.001f ); drawer->drawTransform( desc, renderMat, &scale, NULL ); } } }
void ClipMapBlenderCache::initialize( ClipMap *cm ) { mOwningClipMap = cm; mClipMapSize = cm->mClipMapSize; mLightmapScratchTextures.push_back(GFXTexHandle( mClipMapSize, mClipMapSize, GFXFormatR8G8B8X8, &ClipMapTextureProfile, avar("%s() - mLightmapScratchTextures (line %d)", __FUNCTION__, __LINE__), 1 )); if (GFX->getPixelShaderVersion() == 0.0f) { mFixedfunction = true; // Fixed function stateblock GFXStateBlockDesc sbFF; sbFF.samplersDefined = true; sbFF.samplers[0] = GFXSamplerStateDesc::getClampLinear(); sbFF.samplers[0].textureColorOp = GFXTOPSelectARG1; sbFF.samplers[0].colorArg1 = GFXTATexture; sbFF.samplers[1] = GFXSamplerStateDesc::getWrapLinear(); mFFBaseLayerSB = GFX->createStateBlock(sbFF); sbFF.setBlend(true, GFXBlendOne, GFXBlendOne); mFFAdditionalLayersSB = GFX->createStateBlock(sbFF); sbFF.setBlend(true, GFXBlendDestColor, GFXBlendSrcColor); sbFF.samplers[1].textureColorOp = GFXTOPDisable; mFFLightmapSB = GFX->createStateBlock(sbFF); } else { mFixedfunction = false; // Find and init shaders. ShaderData *sd = NULL; if(GFX->getPixelShaderVersion() >= 2.0f) { if(!Sim::findObject( ( mLM1 ? "AtlasBlender20ShaderLM1" : "AtlasBlender20Shader" ), sd) || (sd->mShader == NULL)) { Con::errorf("ClipMapBlenderCache::initialize - " "Couldn't find shader 'AtlasBlender20Shader'! Terrain will not blend properly on SM2.0 cards!"); } else { mOnePass = sd->mShader; if (mOnePass) mShaderConsts = mOnePass->allocConstBuffer(); if (mShaderConsts) sd->mapSamplerNames(mShaderConsts); } } else { if(!Sim::findObject( ( mLM1 ? "AtlasBlender11AShaderLM1" : "AtlasBlendeer11AShader" ), sd) || (sd->mShader == NULL)) { Con::errorf("ClipMapBlenderCache::initialize - " "Couldn't find shader 'AtlasBlender11AShader'! Terrain will not blend properly on SM1.0 cards!"); } else { mTwoPass[0] = sd->mShader; if (mTwoPass[0]) mShaderConsts = mTwoPass[0]->allocConstBuffer(); if (mShaderConsts) sd->mapSamplerNames(mShaderConsts); } if(!Sim::findObject( ( mLM1 ? "AtlasBlender11BShaderLM1" : "AtlasBlender11BShader" ), sd) || (sd->mShader == NULL)) { Con::errorf("ClipMapBlenderCache::initialize - " "Couldn't find shader 'AtlasBlender11BShader'! Terrain will not blend properly on SM1.0 cards!"); } else { mTwoPass[1] = sd->mShader; } } if (mShaderConsts) { mModelViewProjSC = mShaderConsts->getShader()->getShaderConstHandle(ShaderGenVars::modelview); mOpacityMapSC = mShaderConsts->getShader()->getShaderConstHandle("$opacity"); mLightMapSC = mShaderConsts->getShader()->getShaderConstHandle("$lightMap"); mTex1SC = mShaderConsts->getShader()->getShaderConstHandle("$tex1"); mTex2SC = mShaderConsts->getShader()->getShaderConstHandle("$tex2"); mTex3SC = mShaderConsts->getShader()->getShaderConstHandle("$tex3"); mTex4SC = mShaderConsts->getShader()->getShaderConstHandle("$tex4"); mSourceTexScalesSC = mShaderConsts->getShader()->getShaderConstHandle("$sourceTexScales"); } // Init state blocks GFXStateBlockDesc sbd; sbd.setCullMode(GFXCullNone); sbd.setZEnable(false); sbd.zWriteEnable = false; sbd.samplersDefined = true; sbd.samplers[0] = GFXSamplerStateDesc::getClampLinear(); sbd.samplers[1] = GFXSamplerStateDesc::getClampLinear(); sbd.samplers[2] = GFXSamplerStateDesc::getWrapLinear(); sbd.samplers[3] = GFXSamplerStateDesc::getWrapLinear(); sbd.samplers[4] = GFXSamplerStateDesc::getWrapLinear(); sbd.samplers[5] = GFXSamplerStateDesc::getWrapLinear(); mOnePassSB = GFX->createStateBlock(sbd); sbd.setBlend(true, GFXBlendOne, GFXBlendOne); mTwoPassSB = GFX->createStateBlock(sbd); } createOpacityScratchTextures(); }