GFXShaderConstBufferRef GFXGLShader::allocConstBuffer() { GFXGLShaderConstBuffer* buffer = new GFXGLShaderConstBuffer(this, mConstBufferSize, mConstBuffer); buffer->registerResourceWithDevice(getOwningDevice()); mActiveBuffers.push_back( buffer ); return buffer; }
GFXShaderConstBufferRef GFXD3D9Shader::allocConstBuffer() { if (mVertexConstBufferLayoutF && mPixelConstBufferLayoutF) { GFXD3D9ShaderConstBuffer* buffer = new GFXD3D9ShaderConstBuffer(this, mVertexConstBufferLayoutF, mVertexConstBufferLayoutI, mPixelConstBufferLayoutF, mPixelConstBufferLayoutI); mActiveBuffers.push_back( buffer ); buffer->registerResourceWithDevice(getOwningDevice()); return buffer; } else { return NULL; } }
void GFXGLCubemap::bind(U32 textureUnit) const { glActiveTexture(GL_TEXTURE0 + textureUnit); glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); static_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP, mCubemap); GFXGLStateBlockRef sb = static_cast<GFXGLDevice*>(GFX)->getCurrentStateBlock(); AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!"); if (!sb) return; const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit]; glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0)); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]); }
/// Called by D3D9 device to active this state block. /// @param oldState The current state, used to make sure we don't set redundant states on the device. Pass NULL to reset all states. void GFXD3D9StateBlock::activate(GFXD3D9StateBlock* oldState) { PROFILE_SCOPE( GFXD3D9StateBlock_Activate ); // Little macro to save some typing, SD = state diff, checks for null source state block, then // checks to see if the states differ #if defined(TORQUE_OS_XENON) #define SD(x, y) if (!oldState || oldState->mDesc.x != mDesc.x) \ mD3DDevice->SetRenderState_Inline(y, mDesc.x) // Same as above, but allows you to set the data #define SDD(x, y, z) if (!oldState || oldState->mDesc.x != mDesc.x) \ mD3DDevice->SetRenderState_Inline(y, z) #else #define SD(x, y) if (!oldState || oldState->mDesc.x != mDesc.x) \ mD3DDevice->SetRenderState(y, mDesc.x) // Same as above, but allows you to set the data #define SDD(x, y, z) if (!oldState || oldState->mDesc.x != mDesc.x) \ mD3DDevice->SetRenderState(y, z) #endif // Blending SD(blendEnable, D3DRS_ALPHABLENDENABLE); SDD(blendSrc, D3DRS_SRCBLEND, GFXD3D9Blend[mDesc.blendSrc]); SDD(blendDest, D3DRS_DESTBLEND, GFXD3D9Blend[mDesc.blendDest]); SDD(blendOp, D3DRS_BLENDOP, GFXD3D9BlendOp[mDesc.blendOp]); // Separate alpha blending SD(separateAlphaBlendEnable, D3DRS_SEPARATEALPHABLENDENABLE); SDD(separateAlphaBlendSrc, D3DRS_SRCBLENDALPHA, GFXD3D9Blend[mDesc.separateAlphaBlendSrc]); SDD(separateAlphaBlendDest, D3DRS_DESTBLENDALPHA, GFXD3D9Blend[mDesc.separateAlphaBlendDest]); SDD(separateAlphaBlendOp, D3DRS_BLENDOPALPHA, GFXD3D9BlendOp[mDesc.separateAlphaBlendOp]); // Alpha test SD(alphaTestEnable, D3DRS_ALPHATESTENABLE); SDD(alphaTestFunc, D3DRS_ALPHAFUNC, GFXD3D9CmpFunc[mDesc.alphaTestFunc]); SD(alphaTestRef, D3DRS_ALPHAREF); // Color writes if ((oldState == NULL) || (mColorMask != oldState->mColorMask)) mD3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, mColorMask); // Culling SDD(cullMode, D3DRS_CULLMODE, GFXD3D9CullMode[mDesc.cullMode]); // Depth SD(zEnable, D3DRS_ZENABLE); SD(zWriteEnable, D3DRS_ZWRITEENABLE); SDD(zFunc, D3DRS_ZFUNC, GFXD3D9CmpFunc[mDesc.zFunc]); if ((!oldState) || (mZBias != oldState->mZBias)) mD3DDevice->SetRenderState(D3DRS_DEPTHBIAS, mZBias); if ((!oldState) || (mZSlopeBias != oldState->mZSlopeBias)) mD3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, mZSlopeBias); // Stencil SD(stencilEnable, D3DRS_STENCILENABLE); SDD(stencilFailOp, D3DRS_STENCILFAIL, GFXD3D9StencilOp[mDesc.stencilFailOp]); SDD(stencilZFailOp, D3DRS_STENCILZFAIL, GFXD3D9StencilOp[mDesc.stencilZFailOp]); SDD(stencilPassOp, D3DRS_STENCILPASS, GFXD3D9StencilOp[mDesc.stencilPassOp]); SDD(stencilFunc, D3DRS_STENCILFUNC, GFXD3D9CmpFunc[mDesc.stencilFunc]); SD(stencilRef, D3DRS_STENCILREF); SD(stencilMask, D3DRS_STENCILMASK); SD(stencilWriteMask, D3DRS_STENCILWRITEMASK); SDD(fillMode, D3DRS_FILLMODE, GFXD3D9FillMode[mDesc.fillMode]); #if !defined(TORQUE_OS_XENON) SD(ffLighting, D3DRS_LIGHTING); SD(vertexColorEnable, D3DRS_COLORVERTEX); static DWORD swzTemp; getOwningDevice()->getDeviceSwizzle32()->ToBuffer( &swzTemp, &mDesc.textureFactor, sizeof(ColorI) ); SDD(textureFactor, D3DRS_TEXTUREFACTOR, swzTemp); #endif #undef SD #undef SDD // NOTE: Samplers and Stages are different things. // // The Stages were for fixed function blending. When using shaders // calling SetTextureStageState() is a complete waste of time. In // fact if this function rises to the top of profiles we should // refactor stateblocks to seperate the two. // // Samplers are used by both fixed function and shaders, but the // number of samplers is limited by shader model. #if !defined(TORQUE_OS_XENON) #define TSS(x, y, z) if (!oldState || oldState->mDesc.samplers[i].x != mDesc.samplers[i].x) \ mD3DDevice->SetTextureStageState(i, y, z) for ( U32 i = 0; i < 8; i++ ) { TSS(textureColorOp, D3DTSS_COLOROP, GFXD3D9TextureOp[mDesc.samplers[i].textureColorOp]); TSS(colorArg1, D3DTSS_COLORARG1, mDesc.samplers[i].colorArg1); TSS(colorArg2, D3DTSS_COLORARG2, mDesc.samplers[i].colorArg2); TSS(colorArg3, D3DTSS_COLORARG0, mDesc.samplers[i].colorArg3); TSS(alphaOp, D3DTSS_ALPHAOP, GFXD3D9TextureOp[mDesc.samplers[i].alphaOp]); TSS(alphaArg1, D3DTSS_ALPHAARG1, mDesc.samplers[i].alphaArg1); TSS(alphaArg2, D3DTSS_ALPHAARG2, mDesc.samplers[i].alphaArg2); TSS(alphaArg3, D3DTSS_ALPHAARG0, mDesc.samplers[i].alphaArg3); TSS(textureTransform, D3DTSS_TEXTURETRANSFORMFLAGS, mDesc.samplers[i].textureTransform); TSS(resultArg, D3DTSS_RESULTARG, mDesc.samplers[i].resultArg); } #undef TSS #endif #if defined(TORQUE_OS_XENON) #define SS(x, y, z) if (!oldState || oldState->mDesc.samplers[i].x != mDesc.samplers[i].x) \ mD3DDevice->SetSamplerState_Inline(i, y, z) #else #define SS(x, y, z) if (!oldState || oldState->mDesc.samplers[i].x != mDesc.samplers[i].x) \ mD3DDevice->SetSamplerState(i, y, z) #endif for ( U32 i = 0; i < getOwningDevice()->getNumSamplers(); i++ ) { SS(minFilter, D3DSAMP_MINFILTER, GFXD3D9TextureFilter[mDesc.samplers[i].minFilter]); SS(magFilter, D3DSAMP_MAGFILTER, GFXD3D9TextureFilter[mDesc.samplers[i].magFilter]); SS(mipFilter, D3DSAMP_MIPFILTER, GFXD3D9TextureFilter[mDesc.samplers[i].mipFilter]); F32 bias = mDesc.samplers[i].mipLODBias; DWORD dwBias = *( (LPDWORD)(&bias) ); SS(mipLODBias, D3DSAMP_MIPMAPLODBIAS, dwBias); SS(maxAnisotropy, D3DSAMP_MAXANISOTROPY, mDesc.samplers[i].maxAnisotropy); SS(addressModeU, D3DSAMP_ADDRESSU, GFXD3D9TextureAddress[mDesc.samplers[i].addressModeU]); SS(addressModeV, D3DSAMP_ADDRESSV, GFXD3D9TextureAddress[mDesc.samplers[i].addressModeV]); SS(addressModeW, D3DSAMP_ADDRESSW, GFXD3D9TextureAddress[mDesc.samplers[i].addressModeW]); } #undef SS }
void GFXGLCubemap::setToTexUnit(U32 tuNum) { static_cast<GFXGLDevice*>(getOwningDevice())->setCubemapInternal(tuNum, this); }
/// Called by OpenGL device to active this state block. /// @param oldState The current state, used to make sure we don't set redundant states on the device. Pass NULL to reset all states. void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState) { // Big scary warning copied from Apple docs // http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_performance/chapter_13_section_2.html#//apple_ref/doc/uid/TP40001987-CH213-SW12 // Don't set a state that's already set. Once a feature is enabled, it does not need to be enabled again. // Calling an enable function more than once does nothing except waste time because OpenGL does not check // the state of a feature when you call glEnable or glDisable. For instance, if you call glEnable(GL_LIGHTING) // more than once, OpenGL does not check to see if the lighting state is already enabled. It simply updates // the state value even if that value is identical to the current value. #define STATE_CHANGE(state) (!oldState || oldState->mDesc.state != mDesc.state) #define TOGGLE_STATE(state, enum) if(mDesc.state) glEnable(enum); else glDisable(enum) #define CHECK_TOGGLE_STATE(state, enum) if(!oldState || oldState->mDesc.state != mDesc.state) if(mDesc.state) glEnable(enum); else glDisable(enum) // Blending CHECK_TOGGLE_STATE(blendEnable, GL_BLEND); if(STATE_CHANGE(blendSrc) || STATE_CHANGE(blendDest)) glBlendFunc(GFXGLBlend[mDesc.blendSrc], GFXGLBlend[mDesc.blendDest]); if(STATE_CHANGE(blendOp)) glBlendEquation(GFXGLBlendOp[mDesc.blendOp]); // Color write masks if(STATE_CHANGE(colorWriteRed) || STATE_CHANGE(colorWriteBlue) || STATE_CHANGE(colorWriteGreen) || STATE_CHANGE(colorWriteAlpha)) glColorMask(mDesc.colorWriteRed, mDesc.colorWriteBlue, mDesc.colorWriteGreen, mDesc.colorWriteAlpha); // Culling if(STATE_CHANGE(cullMode)) { TOGGLE_STATE(cullMode, GL_CULL_FACE); glCullFace(GFXGLCullMode[mDesc.cullMode]); } // Depth CHECK_TOGGLE_STATE(zEnable, GL_DEPTH_TEST); if(STATE_CHANGE(zFunc)) glDepthFunc(GFXGLCmpFunc[mDesc.zFunc]); if(STATE_CHANGE(zBias)) { if (mDesc.zBias == 0) { glDisable(GL_POLYGON_OFFSET_FILL); } else { F32 bias = mDesc.zBias * 10000.0f; glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(bias, bias); } } if(STATE_CHANGE(zWriteEnable)) glDepthMask(mDesc.zWriteEnable); // Stencil CHECK_TOGGLE_STATE(stencilEnable, GL_STENCIL_TEST); if(STATE_CHANGE(stencilFunc) || STATE_CHANGE(stencilRef) || STATE_CHANGE(stencilMask)) glStencilFunc(GFXGLCmpFunc[mDesc.stencilFunc], mDesc.stencilRef, mDesc.stencilMask); if(STATE_CHANGE(stencilFailOp) || STATE_CHANGE(stencilZFailOp) || STATE_CHANGE(stencilPassOp)) glStencilOp(GFXGLStencilOp[mDesc.stencilFailOp], GFXGLStencilOp[mDesc.stencilZFailOp], GFXGLStencilOp[mDesc.stencilPassOp]); if(STATE_CHANGE(stencilWriteMask)) glStencilMask(mDesc.stencilWriteMask); if(STATE_CHANGE(fillMode)) glPolygonMode(GL_FRONT_AND_BACK, GFXGLFillMode[mDesc.fillMode]); #undef CHECK_STATE #undef TOGGLE_STATE #undef CHECK_TOGGLE_STATE //sampler objects if( gglHasExtension(ARB_sampler_objects) ) { for (U32 i = 0; i < getMin(getOwningDevice()->getNumSamplers(), (U32) TEXTURE_STAGE_COUNT); i++) { if(!oldState || oldState->mSamplerObjects[i] != mSamplerObjects[i]) glBindSampler(i, mSamplerObjects[i] ); } } // TODO: states added for detail blend }