VertexBuffer &VertexBuffer::operator=(const VertexBuffer &other) { if (this == &other) return *this; setVertexDecl(other._decl); setSize(other._count, other._size); memcpy(_data, other._data, other._count * other._size); // Fix up the data pointers std::vector<VertexAttrib>::const_iterator src = other._decl.begin(); std::vector<VertexAttrib>::iterator dest = _decl.begin(); while ((src != other._decl.end()) && (dest != _decl.end())) { dest->pointer = (byte *)_data + ((byte *)src->pointer - (byte *)other._data); ++src; ++dest; } return *this; }
void GFXDevice::updateStates(bool forceSetAll /*=false*/) { PROFILE_SCOPE(GFXDevice_updateStates); if(forceSetAll) { bool rememberToEndScene = false; if(!canCurrentlyRender()) { if (!beginScene()) { AssertFatal(false, "GFXDevice::updateStates: Unable to beginScene!"); } rememberToEndScene = true; } setMatrix( GFXMatrixProjection, mProjectionMatrix ); setMatrix( GFXMatrixWorld, mWorldMatrix[mWorldStackSize] ); setMatrix( GFXMatrixView, mViewMatrix ); setVertexDecl( mCurrVertexDecl ); for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ ) { setVertexStream( i, mCurrentVertexBuffer[i] ); setVertexStreamFrequency( i, mVertexBufferFrequency[i] ); } if( mCurrentPrimitiveBuffer.isValid() ) // This could be NULL when the device is initalizing mCurrentPrimitiveBuffer->prepare(); /// Stateblocks if ( mNewStateBlock ) setStateBlockInternal(mNewStateBlock, true); mCurrentStateBlock = mNewStateBlock; for(U32 i = 0; i < getNumSamplers(); i++) { switch (mTexType[i]) { case GFXTDT_Normal : { mCurrentTexture[i] = mNewTexture[i]; setTextureInternal(i, mCurrentTexture[i]); } break; case GFXTDT_Cube : { mCurrentCubemap[i] = mNewCubemap[i]; if (mCurrentCubemap[i]) mCurrentCubemap[i]->setToTexUnit(i); else setTextureInternal(i, NULL); } break; default: AssertFatal(false, "Unknown texture type!"); break; } } // Set our material setLightMaterialInternal(mCurrentLightMaterial); // Set our lights for(U32 i = 0; i < LIGHT_STAGE_COUNT; i++) { setLightInternal(i, mCurrentLight[i], mCurrentLightEnable[i]); } _updateRenderTargets(); if(rememberToEndScene) endScene(); return; } if (!mStateDirty) return; // Normal update logic begins here. mStateDirty = false; // Update Projection Matrix if( mProjectionMatrixDirty ) { setMatrix( GFXMatrixProjection, mProjectionMatrix ); mProjectionMatrixDirty = false; } // Update World Matrix if( mWorldMatrixDirty ) { setMatrix( GFXMatrixWorld, mWorldMatrix[mWorldStackSize] ); mWorldMatrixDirty = false; } // Update View Matrix if( mViewMatrixDirty ) { setMatrix( GFXMatrixView, mViewMatrix ); mViewMatrixDirty = false; } if( mTextureMatrixCheckDirty ) { for( S32 i = 0; i < getNumSamplers(); i++ ) { if( mTextureMatrixDirty[i] ) { mTextureMatrixDirty[i] = false; setMatrix( (GFXMatrixType)(GFXMatrixTexture + i), mTextureMatrix[i] ); } } mTextureMatrixCheckDirty = false; } // Update the vertex declaration. if ( mVertexDeclDirty ) { setVertexDecl( mCurrVertexDecl ); mVertexDeclDirty = false; } // Update the vertex buffers. for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ ) { if ( mVertexBufferDirty[i] ) { setVertexStream( i, mCurrentVertexBuffer[i] ); mVertexBufferDirty[i] = false; } if ( mVertexBufferFrequencyDirty[i] ) { setVertexStreamFrequency( i, mVertexBufferFrequency[i] ); mVertexBufferFrequencyDirty[i] = false; } } // Update primitive buffer // // NOTE: It is very important to set the primitive buffer AFTER the vertex buffer // because in order to draw indexed primitives in DX8, the call to SetIndicies // needs to include the base vertex offset, and the DX8 GFXDevice relies on // having mCurrentVB properly assigned before the call to setIndices -patw if( mPrimitiveBufferDirty ) { if( mCurrentPrimitiveBuffer.isValid() ) // This could be NULL when the device is initalizing mCurrentPrimitiveBuffer->prepare(); mPrimitiveBufferDirty = false; } // NOTE: With state blocks, it's now important to update state before setting textures // some devices (e.g. OpenGL) set states on the texture and we need that information before // the texture is activated. if (mStateBlockDirty) { setStateBlockInternal(mNewStateBlock, false); mCurrentStateBlock = mNewStateBlock; mStateBlockDirty = false; } if( mTexturesDirty ) { mTexturesDirty = false; for(U32 i = 0; i < getNumSamplers(); i++) { if(!mTextureDirty[i]) continue; mTextureDirty[i] = false; switch (mTexType[i]) { case GFXTDT_Normal : { mCurrentTexture[i] = mNewTexture[i]; setTextureInternal(i, mCurrentTexture[i]); } break; case GFXTDT_Cube : { mCurrentCubemap[i] = mNewCubemap[i]; if (mCurrentCubemap[i]) mCurrentCubemap[i]->setToTexUnit(i); else setTextureInternal(i, NULL); } break; default: AssertFatal(false, "Unknown texture type!"); break; } } } // Set light material if(mLightMaterialDirty) { setLightMaterialInternal(mCurrentLightMaterial); mLightMaterialDirty = false; } // Set our lights if(mLightsDirty) { mLightsDirty = false; for(U32 i = 0; i < LIGHT_STAGE_COUNT; i++) { if(!mLightDirty[i]) continue; mLightDirty[i] = false; setLightInternal(i, mCurrentLight[i], mCurrentLightEnable[i]); } } _updateRenderTargets(); #ifdef TORQUE_DEBUG_RENDER doParanoidStateCheck(); #endif }