void Patcher_HandleReceipt_NextPatchFile() { char* MessageContent = strstr( g_HTTPResultBuffer.GetData(), CRLF CRLF ); if( !MessageContent ) { // If we were updating, we're not anymore g_Patcher_IsUpdating = false; AddStatus( "Error receiving patch file.", g_StatusWarningColor ); ++g_NumWarnings; return; } MessageContent += 4; uint Offset = ( uint )( MessageContent - g_HTTPResultBuffer.GetData() ); uint ContentSize = g_HTTPSocket->AsyncGetBytesReceived() - Offset; // Compute the checksum for the payload and compare with the data in the manifest file uint32 ContentChecksum = Checksum::Adler32( ( uint8* )MessageContent, ContentSize ); SimpleString ContentLengthString = SimpleString::PrintF( "%d", ContentSize ); SimpleString ContentChecksumString = SimpleString::PrintF( "0x%08X", ContentChecksum ); SManifestFile& ManifestFile = g_FilesInManifest[ g_NextPatchFileIndex ]; SimpleString PatchFile = ManifestFile.m_Filename; if( ContentLengthString == ManifestFile.m_Length && ContentChecksumString == ManifestFile.m_Checksum ) { ManifestFile.m_Validated = true; FileStream TempFile( GetTempFileForPatchFile( PatchFile ).CStr(), FileStream::EFM_Write ); TempFile.Write( ContentSize, MessageContent ); AddStatus( SimpleString::PrintF( "%s received.", PatchFile.CStr() ), g_StatusColor ); } else { AddStatus( SimpleString::PrintF( "Checksum failure for %s.", PatchFile.CStr() ), g_StatusWarningColor ); ++g_NumWarnings; } g_NextPatchFileIndex++; // If there are remaining files, get them. if( g_NextPatchFileIndex < g_FilesInManifest.Size() ) { Patcher_GetNextPatchFile(); } else { FinishPatching(); } }
void StreamReader::ReadString(String *result, const String &delimiter) { Array<Char> retString; Array<Char> delString; String strDelimiter = delimiter; Char c; if (strDelimiter.IsEmpty()) { strDelimiter.Resize(1); strDelimiter.Append("\0"); } while (true) { c = ReadByte(); if (this->GetError()) break; if (c == strDelimiter.GetData()[0]) { delString.Clear(); delString.Append(c); for (Int i = 1; i < strDelimiter.GetSizeInBytes(); i++) { c = ReadByte(); if (this->GetError()) { for (Int j = 0; j < delString.GetElementCount(); j++) retString.Append(delString[j]); break; } delString.Append(c); if (c != strDelimiter.GetData()[i]) break; } if (strDelimiter.GetSizeInBytes() > delString.GetElementCount()) for (Int i = 0; i < delString.GetElementCount(); i++) retString.Append(delString[i]); else { if (memcmp(strDelimiter.GetData(), delString.GetData(), delString.GetElementCount())) { for (Int i = 0; i < delString.GetElementCount(); i++) retString.Append(delString[i]); } else break; } } else { retString.Append(c); } } result->Resize(retString.GetElementCount()); memcpy((Char*)result->GetData(), retString.GetData(), retString.GetElementCount()); }
void BlockVector::Update(const Array<int> &bOffsets) { blockOffsets = bOffsets.GetData(); if (OwnsData()) { // check if 'bOffsets' agree with the 'blocks' if (bOffsets.Size() == numBlocks+1) { if (numBlocks == 0) { return; } if (Size() == bOffsets.Last()) { for (int i = numBlocks - 1; true; i--) { if (i < 0) { return; } if (blocks[i].Size() != bOffsets[i+1] - bOffsets[i]) { break; } MFEM_ASSERT(blocks[i].GetData() == data + bOffsets[i], "invalid blocks[" << i << ']'); } } } } else { Destroy(); } SetSize(bOffsets.Last()); if (numBlocks != bOffsets.Size()-1) { delete [] blocks; numBlocks = bOffsets.Size()-1; blocks = new Vector[numBlocks]; } SetBlocks(); }
void SimpleString::FillArray( Array<char>& OutArray, bool WithNull /*= false*/ ) const { const uint Length = WithNull ? m_Length + 1 : m_Length; OutArray.Clear(); OutArray.Resize( Length ); memcpy_s( OutArray.GetData(), Length, m_String, Length ); }
/*virtual*/ void GL2ShaderProgram::Initialize( IVertexShader* const pVertexShader, IPixelShader* const pPixelShader, IVertexDeclaration* const pVertexDeclaration ) { XTRACE_FUNCTION; m_VertexShader = pVertexShader; m_PixelShader = pPixelShader; ASSERT( m_VertexShader ); ASSERT( m_PixelShader ); m_ShaderProgram = glCreateProgram(); ASSERT( m_ShaderProgram != 0 ); GLuint VertexShader = *static_cast<GLuint*>( m_VertexShader->GetHandle() ); ASSERT( VertexShader != 0 ); glAttachShader( m_ShaderProgram, VertexShader ); GLuint PixelShader = *static_cast<GLuint*>( m_PixelShader->GetHandle() ); ASSERT( PixelShader != 0 ); glAttachShader( m_ShaderProgram, PixelShader ); BindAttributes( pVertexDeclaration ); glLinkProgram( m_ShaderProgram ); GLERRORCHECK; GLint LinkStatus; glGetProgramiv( m_ShaderProgram, GL_LINK_STATUS, &LinkStatus ); if( LinkStatus != GL_TRUE ) { GLint LogLength; glGetProgramiv( m_ShaderProgram, GL_INFO_LOG_LENGTH, &LogLength ); Array<GLchar> Log; Log.Resize( LogLength ); glGetProgramInfoLog( m_ShaderProgram, LogLength, NULL, Log.GetData() ); if( LogLength > 0 ) { PRINTF( "GLSL shader program link failed:\n" ); PRINTF( Log.GetData() ); } WARNDESC( "GLSL shader program link failed" ); } BuildUniformTable(); SetSamplerUniforms(); }
//! View constructor BlockVector::BlockVector(double *data, const Array<int> & bOffsets): Vector(data, bOffsets.Last()), numBlocks(bOffsets.Size()-1), blockOffsets(bOffsets.GetData()) { blocks = new Vector[numBlocks]; SetBlocks(); }
static void TestDataAlignmentT() { Array<TYPE> v; v.PushBack( TYPE() ); UT_ASSERT(v.GetSize() == 1); UT_ASSERT(((long)v.GetData()) % AligmentSize == 0); }
// helper to set submatrix of A repeated vdim times static void SetVDofSubMatrixTranspose(SparseMatrix& A, Array<int>& rows, Array<int>& cols, const DenseMatrix& subm, int vdim) { if (vdim == 1) { A.SetSubMatrixTranspose(rows, cols, subm, 1); } else { int nr = subm.Width(), nc = subm.Height(); for (int d = 0; d < vdim; d++) { Array<int> rows_sub(rows.GetData() + d*nr, nr); // (not owner) Array<int> cols_sub(cols.GetData() + d*nc, nc); // (not owner) A.SetSubMatrixTranspose(rows_sub, cols_sub, subm, 1); } } }
void GL2PixelShader::Initialize( const IDataStream& Stream ) { XTRACE_FUNCTION; const int Length = Stream.Size(); byte* pBuffer = new byte[ Length ]; Stream.Read( Length, pBuffer ); m_PixelShader = glCreateShader( GL_FRAGMENT_SHADER ); ASSERT( m_PixelShader != 0 ); // Copy the GLSL source const GLsizei NumStrings = 1; const GLchar* Strings[] = { reinterpret_cast<GLchar*>( pBuffer ) }; const GLint StringLengths[] = { Length }; // I don't trust this file to be null-terminated, so explicitly declare the length. glShaderSource( m_PixelShader, NumStrings, Strings, StringLengths ); // Compile the shader glCompileShader( m_PixelShader ); GLERRORCHECK; GLint CompileStatus; glGetShaderiv( m_PixelShader, GL_COMPILE_STATUS, &CompileStatus ); if( CompileStatus != GL_TRUE ) { GLint LogLength; glGetShaderiv( m_PixelShader, GL_INFO_LOG_LENGTH, &LogLength ); Array<GLchar> Log; Log.Resize( LogLength ); glGetShaderInfoLog( m_PixelShader, LogLength, NULL, Log.GetData() ); if( LogLength > 0 ) { PRINTF( "GLSL fragment shader compile failed:\n" ); PRINTF( Log.GetData() ); } WARNDESC( "GLSL fragment shader compile failed" ); } SafeDeleteArray( pBuffer ); }
void BlockVector::Update(double *data, const Array<int> & bOffsets) { NewDataAndSize(data, bOffsets.Last()); blockOffsets = bOffsets.GetData(); if (numBlocks != bOffsets.Size()-1) { delete [] blocks; numBlocks = bOffsets.Size()-1; blocks = new Vector[numBlocks]; } SetBlocks(); }
void Patcher_HandleReceipt_ManifestFile() { g_FilesInManifest.Clear(); g_NextPatchFileIndex = 0; char* MessageContent = strstr( g_HTTPResultBuffer.GetData(), CRLF CRLF ); if( !MessageContent ) { AddStatus( "Error receiving manifest file.", g_StatusWarningColor ); ++g_NumWarnings; return; } MessageContent += 4; uint Offset = ( uint )( MessageContent - g_HTTPResultBuffer.GetData() ); uint ContentSize = g_HTTPSocket->AsyncGetBytesReceived() - Offset; Array<SimpleString> Lines; SplitIntoLines( MessageContent, ContentSize, Lines ); for( uint LinesIndex = 0; LinesIndex + 2 < Lines.Size(); LinesIndex += 3 ) { SManifestFile ManifestFile; ManifestFile.m_Filename = Lines[ LinesIndex ]; ManifestFile.m_Length = Lines[ LinesIndex + 1 ]; ManifestFile.m_Checksum = Lines[ LinesIndex + 2 ]; ManifestFile.m_Validated = false; g_FilesInManifest.PushBack( ManifestFile ); } AddStatus( "Manifest file received.", g_StatusColor ); if( g_NextPatchFileIndex < g_FilesInManifest.Size() ) { Patcher_GetNextPatchFile(); } }
SimpleString SimpleString::Replace( const char* const Find, const char* const Replace ) const { DEVASSERT( Find ); DEVASSERT( Replace ); Array<char> NewStringBuffer; NewStringBuffer.Resize( m_Length + 1 ); memcpy( NewStringBuffer.GetData(), m_String, m_Length + 1 ); const size_t FindLength = strlen( Find ); const size_t ReplaceLength = strlen( Replace ); const size_t Difference = ReplaceLength - FindLength; for( size_t Iterator = 0; Iterator < NewStringBuffer.Size(); ) { const char* const SubStr = strstr( NewStringBuffer.GetData() + Iterator, Find ); if( SubStr ) { const char* const Base = NewStringBuffer.GetData(); const size_t Offset = SubStr - Base; for( size_t DifferenceIndex = 0; DifferenceIndex < Difference; ++DifferenceIndex ) { NewStringBuffer.Insert( 0, static_cast<uint>( Offset ) ); } memcpy( NewStringBuffer.GetData() + Offset, Replace, ReplaceLength ); Iterator += ReplaceLength; } else { break; } } return SimpleString( NewStringBuffer ); }
void Patcher_HandleReceipt_VersionNumber() { char* MessageContent = strstr( g_HTTPResultBuffer.GetData(), CRLF CRLF ); if( !MessageContent ) { AddStatus( "Error receiving version number.", g_StatusWarningColor ); ++g_NumWarnings; return; } MessageContent += 4; // Skip the CRLF CRLF // If there's additional content, only get the first line char* LineBreak = strstr( MessageContent, LF ); if( LineBreak ) { *LineBreak = '\0'; } SimpleString LatestVersion = MessageContent; STATICHASH( Version ); STATICHASH( ContentSyncer ); SimpleString LocalVersion = ConfigManager::GetString( sVersion, "", sContentSyncer ); if( LocalVersion == LatestVersion ) { AddStatus( "Game is up to date.", g_StatusColor ); g_ShouldLaunchApp = true; } else { AddStatus( "New updates are available.", g_StatusColor ); BeginUpdating(); } }
MIDIEvent* MIDI::EventFactory( const uint8 EventCode, const IDataStream& Stream ) const { const uint8 MIDIEventType = ( EventCode & 0xF0 ) >> 4; if( MIDIEventType == 0x08 ) { // Note off return new MIDINoteOffEvent(); } else if( MIDIEventType == 0x09 ) { // Note on return new MIDINoteOnEvent(); } else if( MIDIEventType == 0x0A ) { // Note aftertouch } else if( MIDIEventType == 0x0B ) { // Controller return new MIDIControllerEvent(); } else if( MIDIEventType == 0x0C ) { // Program change return new MIDIProgramChangeEvent(); } else if( MIDIEventType == 0x0D ) { // Channel aftertouch } else if( MIDIEventType == 0x0E ) { // Pitch bend return new MIDIPitchBendEvent(); } else if( EventCode == 0xF0 || EventCode == 0xF7 ) { // SysEx event // For now, skip SysEx events because I don't care (TODO: I'll need to load them to resave them, though) const uint SysExLength = LoadVariableLengthValue( Stream ); Stream.Skip( SysExLength ); //PRINTF( "Skipped SysEx of length %d\n", SysExLength ); return NULL; } else if( EventCode == 0xFF ) { // Meta event const uint8 MetaType = Stream.ReadUInt8(); Unused( MetaType ); // For now, skip meta events because I don't care (TODO: I'll need to load them to resave them, though) const uint MetaLength = LoadVariableLengthValue( Stream ); //Stream.Skip( MetaLength ); Array<uint8> MetaString; MetaString.Resize( MetaLength ); Stream.Read( MetaLength, MetaString.GetData() ); MetaString.PushBack( '\0' ); //PRINTF( "Skipped meta (0x%02X) of length %d\n", MetaType, MetaLength ); //PRINTF( "%s\n", MetaString.GetData() ); return NULL; } else { // Unknown event WARN; return NULL; } // Not yet handled WARN; return NULL; }
// It might be useful to have some arithmetic parsing for more complex expressions, // but eventually that would just become writing a whole little language... // NOTE: This is very error-prone if the format isn't exactly "A OP B", so // don't use this for anything that the user can touch. bool ConfigParser::EvaluateConditional( const IDataStream& Stream ) { // Parse three tokens: a left side, an operator, and a right side // Valid expressions: // bool b-op bool // int n-op int // int n-op float // float n-op float // float n-op int // string s-op string // b-op: == != // n-op: < <= > >= == != // s-op: == != ~= ~!= (case-insensitive) // Use same rules as above to determine the type of each value // This would be a good place to refactor to reuse some code SToken::ETokenType LeftSideType = SToken::ET_None; SToken::ETokenType RightSideType = SToken::ET_None; Array< char > LeftSideString; Array< char > OperatorString; Array< char > RightSideString; char StrMark = '\"'; // Parse left side for(;;) { char c = Stream.ReadInt8(); if( c == ' ' || Stream.EOS() ) { LeftSideString.PushBack( '\0' ); break; } else { InnerParse( c, StrMark, LeftSideString, 0, LeftSideType ); } } // Parse operator for(;;) { char c = Stream.ReadInt8(); if( c == ' ' || Stream.EOS() ) { OperatorString.PushBack( '\0' ); break; } OperatorString.PushBack( c ); } // Parse right side for(;;) { char c = Stream.ReadInt8(); if( c == '\0' || c == ' ' || Stream.EOS() ) { RightSideString.PushBack( '\0' ); break; } else { InnerParse( c, StrMark, RightSideString, 0, RightSideType ); } } // Evaluate if( LeftSideType == RightSideType || ( LeftSideType == SToken::ET_Int && RightSideType == SToken::ET_Float ) || ( LeftSideType == SToken::ET_Float && RightSideType == SToken::ET_Int ) ) { SimpleString LeftSide = LeftSideString.GetData(); SimpleString RightSide = RightSideString.GetData(); SimpleString Operator = OperatorString.GetData(); if( LeftSideType == SToken::ET_Bool ) { bool LeftSideBool = LeftSide.AsBool(); bool RightSideBool = RightSide.AsBool(); if( Operator == "==" ) { return ( LeftSideBool == RightSideBool ); } else if( Operator == "!=" ) { return ( LeftSideBool != RightSideBool ); } else { DEBUGWARNDESC( "Unknown operator in conditional expression" ); return false; } } else if( LeftSideType == SToken::ET_Int ) { int LeftSideInt = LeftSide.AsInt(); int RightSideInt = ( RightSideType == SToken::ET_Int ) ? RightSide.AsInt() : (int)RightSide.AsFloat(); if( Operator == "==" ) { return ( LeftSideInt == RightSideInt ); } else if( Operator == "!=" ) { return ( LeftSideInt != RightSideInt ); } else if( Operator == "<" ) { return ( LeftSideInt < RightSideInt ); } else if( Operator == "<=" ) { return ( LeftSideInt <= RightSideInt ); } else if( Operator == ">" ) { return ( LeftSideInt > RightSideInt ); } else if( Operator == ">=" ) { return ( LeftSideInt >= RightSideInt ); } else { DEBUGWARNDESC( "Unknown operator in conditional expression" ); return false; } } else if( LeftSideType == SToken::ET_Float ) { float LeftSideFloat = LeftSide.AsFloat(); float RightSideFloat = ( RightSideType == SToken::ET_Float ) ? RightSide.AsFloat() : (float)RightSide.AsInt(); if( Operator == "==" ) { return ( LeftSideFloat == RightSideFloat ); } else if( Operator == "!=" ) { return ( LeftSideFloat != RightSideFloat ); } else if( Operator == "<" ) { return ( LeftSideFloat < RightSideFloat ); } else if( Operator == "<=" ) { return ( LeftSideFloat <= RightSideFloat ); } else if( Operator == ">" ) { return ( LeftSideFloat > RightSideFloat ); } else if( Operator == ">=" ) { return ( LeftSideFloat >= RightSideFloat ); } else { DEBUGWARNDESC( "Unknown operator in conditional expression" ); return false; } } else if( LeftSideType == SToken::ET_String ) { if( Operator == "==" ) { return ( LeftSide == RightSide ); } else if( Operator == "!=" ) { return ( LeftSide != RightSide ); } else if( Operator == "~=" ) { return ( LeftSide.StrICmp( RightSide ) ); } else if( Operator == "~!=" ) { return ( !LeftSide.StrICmp( RightSide ) ); } else { DEBUGWARNDESC( "Unknown operator in conditional expression" ); return false; } } else { DEBUGWARNDESC( "Unknown types in conditional expression" ); return false; } } else { DEBUGWARNDESC( "Mismatched types in conditional expression" ); return false; } }
// NOTE: This is a lot of duplicated code from the value parsing parts // of Parse(). Could do to clean this up and use common functions. void ConfigParser::ParseTiny( const IDataStream& Stream ) { Array< char > FirstPart; // Could be name or context Array< char > SecondPart; // Name if first part is context Array< char > ValuePart; SToken::ETokenType Type = SToken::ET_None; char QuoteType = '\"'; bool StringClosed = false; enum EParseState { EPS_FirstPart, EPS_SecondPart, EPS_ValuePart, } ParseState = EPS_FirstPart; while( !Stream.EOS() ) { char c = Stream.ReadInt8(); if( ParseState == EPS_FirstPart ) { if( c == ' ' || c == '\t' || c == '\n' || c == '\0' ) { // Ignore whitespace continue; } else if( c == ':' ) { FirstPart.PushBack( '\0' ); ParseState = EPS_SecondPart; continue; } else if( c == '=' ) { FirstPart.PushBack( '\0' ); ParseState = EPS_ValuePart; continue; } else { FirstPart.PushBack( c ); } } else if( ParseState == EPS_SecondPart ) { if( c == ' ' || c == '\t' || c == '\n' || c == '\0' ) { // Ignore whitespace continue; } else if( c == '=' ) { SecondPart.PushBack( '\0' ); ParseState = EPS_ValuePart; continue; } else { SecondPart.PushBack( c ); } } else if( ParseState == EPS_ValuePart ) { if( ( ( Type != SToken::ET_String || StringClosed ) && ( c == ' ' || c == '\t' ) ) || c == '\n' || c == '\0' ) { // Parse the value and set the config var ValuePart.PushBack( '\0' ); SimpleString Name = ( SecondPart.Size() > 1 ) ? SecondPart.GetData() : FirstPart.GetData(); SimpleString Context = ( SecondPart.Size() > 1 ) ? FirstPart.GetData() : ""; switch( Type ) { case SToken::ET_Bool: { // Just use the first character to determine truth bool Value = false; char first = ValuePart[0]; if( first == 't' || first == 'T' ) { Value = true; } ConfigManager::SetBool( Name, Value, Context ); } break; case SToken::ET_Int: { int Value = atoi( ValuePart.GetData() ); ConfigManager::SetInt( Name, Value, Context ); } break; case SToken::ET_Float: { float Value = (float)atof( ValuePart.GetData() ); ConfigManager::SetFloat( Name, Value, Context ); } break; case SToken::ET_String: { // Make a permanent copy of the string uint Length = (uint)strlen( ValuePart.GetData() ); char* pString = new char[ Length + 1]; memcpy_s( pString, Length + 1, ValuePart.GetData(), Length ); pString[ Length ] = '\0'; StringManager::AddString( StringManager::ESL_Permanent, pString ); ConfigManager::SetString( Name, pString, Context ); } break; default: WARNDESC( "Unexpected token" ); break; } // Prepare for next variable FirstPart.Clear(); SecondPart.Clear(); ValuePart.Clear(); Type = SToken::ET_None; ParseState = EPS_FirstPart; StringClosed = false; continue; } else { InnerParse( c, QuoteType, ValuePart, 0, Type, &StringClosed ); } } } }
SimpleString::SimpleString( const Array<char>& String ) : m_String( NULL ) , m_Length( 0 ) { Initialize( String.GetData() ); }
Mesh* UIWidgetFrame::CreateMesh() const { static const uint kNumVertices = 16; static const uint kNumIndices = 54; const Vector TopLeft = Vector( m_TopLeft.x, 0.0f, m_TopLeft.y ); const Vector BottomRight = TopLeft + Vector( m_Dimensions.x, 0.0f, m_Dimensions.y ); Array<Vector> Positions; Positions.Reserve( kNumVertices ); { Array<float> PositionsX; PositionsX.Reserve( 4 ); PositionsX.PushBack( TopLeft.x ); PositionsX.PushBack( TopLeft.x + m_Border ); PositionsX.PushBack( BottomRight.x - m_Border ); PositionsX.PushBack( BottomRight.x ); Array<float> PositionsY; PositionsY.Reserve( 4 ); PositionsY.PushBack( TopLeft.z ); PositionsY.PushBack( TopLeft.z + m_Border ); PositionsY.PushBack( BottomRight.z - m_Border ); PositionsY.PushBack( BottomRight.z ); for( uint Y = 0; Y < 4; ++Y ) { for( uint X = 0; X < 4; ++X ) { Positions.PushBack( Vector( PositionsX[ X ], 0.0f, PositionsY[ Y ] ) ); } } } Array<Vector2> UVs; UVs.Reserve( kNumVertices ); { Array<float> UVValues; UVValues.Reserve( 4 ); UVValues.PushBack( 0.0f ); UVValues.PushBack( 0.25f ); UVValues.PushBack( 0.75f ); UVValues.PushBack( 1.0f ); for( uint V = 0; V < 4; ++V ) { for( uint U = 0; U < 4; ++U ) { UVs.PushBack( Vector2( UVValues[ U ], UVValues[ V ] ) ); } } } Array<index_t> Indices; Indices.Reserve( kNumIndices ); for( index_t Y = 0; Y < 3; ++Y ) { for( index_t X = 0; X < 3; ++X ) { const index_t Base = X + Y * 4; Indices.PushBack( Base + 0 ); Indices.PushBack( Base + 4 ); Indices.PushBack( Base + 1 ); Indices.PushBack( Base + 4 ); Indices.PushBack( Base + 5 ); Indices.PushBack( Base + 1 ); } } IRenderer* const pRenderer = m_UIManager->GetRenderer(); IVertexBuffer* const VertexBuffer = pRenderer->CreateVertexBuffer(); IVertexDeclaration* const VertexDeclaration = pRenderer->GetVertexDeclaration( VD_POSITIONS | VD_UVS ); IIndexBuffer* const IndexBuffer = pRenderer->CreateIndexBuffer(); IVertexBuffer::SInit InitStruct; InitStruct.NumVertices = kNumVertices; InitStruct.Positions = Positions.GetData(); InitStruct.UVs = UVs.GetData(); VertexBuffer->Init( InitStruct ); IndexBuffer->Init( kNumIndices, Indices.GetData() ); IndexBuffer->SetPrimitiveType( EPT_TRIANGLELIST ); Mesh* const pMesh = new Mesh( VertexBuffer, VertexDeclaration, IndexBuffer ); pMesh->m_AABB = AABB( TopLeft, BottomRight ); return pMesh; }
void UIScreenEldMirror::CreateBackdropMesh() { ASSERT( !m_BackdropMesh ); EldritchFramework* const pFramework = EldritchFramework::GetInstance(); EldritchWorld* const pWorld = pFramework->GetWorld(); IRenderer* const pRenderer = pFramework->GetRenderer(); ASSERT( pWorld ); static const uint kNumVertices = 4; static const uint kNumIndices = 6; Vector2 UVMin; Vector2 UVMax; pWorld->GetTileUVs( m_MirrorBackdropTile, UVMin, UVMax ); Array<Vector> Positions; Array<Vector4> Colors; Array<Vector2> UVs; Array<index_t> Indices; // For beauty lighting with cube lights const Matrix MirrorRotation = Matrix::CreateRotationAboutZ( m_MirrorYaw ); Positions.PushBack( MirrorRotation * Vector( m_MirrorBackdropExtents, -m_MirrorBackdropDistance, -m_MirrorBackdropExtents + m_MirrorViewHeight ) ); Positions.PushBack( MirrorRotation * Vector( -m_MirrorBackdropExtents, -m_MirrorBackdropDistance, -m_MirrorBackdropExtents + m_MirrorViewHeight ) ); Positions.PushBack( MirrorRotation * Vector( m_MirrorBackdropExtents, -m_MirrorBackdropDistance, m_MirrorBackdropExtents + m_MirrorViewHeight ) ); Positions.PushBack( MirrorRotation * Vector( -m_MirrorBackdropExtents, -m_MirrorBackdropDistance, m_MirrorBackdropExtents + m_MirrorViewHeight ) ); Colors.PushBack( m_MirrorBackdropColor ); Colors.PushBack( m_MirrorBackdropColor ); Colors.PushBack( m_MirrorBackdropColor ); Colors.PushBack( m_MirrorBackdropColor ); UVs.PushBack( Vector2( UVMin.uv_u, UVMax.uv_v ) ); UVs.PushBack( Vector2( UVMax.uv_u, UVMax.uv_v ) ); UVs.PushBack( Vector2( UVMin.uv_u, UVMin.uv_v ) ); UVs.PushBack( Vector2( UVMax.uv_u, UVMin.uv_v ) ); Indices.PushBack( 0 ); Indices.PushBack( 1 ); Indices.PushBack( 3 ); Indices.PushBack( 0 ); Indices.PushBack( 3 ); Indices.PushBack( 2 ); IVertexBuffer* const pVertexBuffer = pRenderer->CreateVertexBuffer(); IVertexDeclaration* const pVertexDeclaration = pRenderer->GetVertexDeclaration( VD_POSITIONS | VD_FLOATCOLORS_SM2 | VD_UVS ); IIndexBuffer* const pIndexBuffer = pRenderer->CreateIndexBuffer(); IVertexBuffer::SInit InitStruct; InitStruct.NumVertices = kNumVertices; InitStruct.Positions = Positions.GetData(); InitStruct.FloatColors1 = Colors.GetData(); InitStruct.UVs = UVs.GetData(); pVertexBuffer->Init( InitStruct ); pIndexBuffer->Init( kNumIndices, Indices.GetData() ); pIndexBuffer->SetPrimitiveType( EPT_TRIANGLELIST ); m_BackdropMesh = new Mesh( pVertexBuffer, pVertexDeclaration, pIndexBuffer ); m_BackdropMesh->SetTexture( 0, pWorld->GetTileTexture() ); m_BackdropMesh->SetMaterialDefinition( "Material_World", pRenderer ); m_BackdropMesh->SetMaterialFlags( MAT_OFFSCREEN_0 | MAT_ALWAYS ); }