void CChunkTrees::CreateTreeVBO() { if (s_iTreeVBO != ~0) return; Vector vecRight(0, 0, 2.5f); Vector vecUp(0, 10, 0); Vector v1 = -vecRight + vecUp; Vector v2 = -vecRight; Vector v3 = vecRight; Vector v4 = vecRight + vecUp; CRenderingContext r(GameServer()->GetRenderer()); r.BeginRenderTris(); r.TexCoord(0.0f, 1.0f); r.Vertex(v1); r.TexCoord(0.0f, 0.0f); r.Vertex(v2); r.TexCoord(1.0f, 0.0f); r.Vertex(v3); r.TexCoord(0.0f, 1.0f); r.Vertex(v1); r.TexCoord(1.0f, 0.0f); r.Vertex(v3); r.TexCoord(1.0f, 1.0f); r.Vertex(v4); r.CreateVBO(s_iTreeVBO, s_iTreeVBOSize); }
//----------------------------------------------------------------------------- // Purpose: Checks a position to make sure a corner of a building can live there //----------------------------------------------------------------------------- bool CBaseObject::VerifyCorner( const Vector &vBottomCenter, float xOffset, float yOffset ) { // Start slightly above the surface Vector vStart( vBottomCenter.x + xOffset, vBottomCenter.y + yOffset, vBottomCenter.z + 0.1 ); trace_t tr; UTIL_TraceLine( vStart, vStart - Vector( 0, 0, TF_OBJ_GROUND_CLEARANCE ), MASK_PLAYERSOLID_BRUSHONLY, this, COLLISION_GROUP_PLAYER_MOVEMENT, &tr ); // Cannot build on very steep slopes ( > 45 degrees ) if ( tr.fraction < 1.0f ) { Vector vecUp(0,0,1); tr.plane.normal.NormalizeInPlace(); float flDot = DotProduct( tr.plane.normal, vecUp ); if ( flDot < 0.65 ) { // Too steep return false; } } return !tr.startsolid && tr.fraction < 1; }
// 初期化 IZ_BOOL CMyAppl::Init( HINSTANCE hInst, HWND hDeviceWindow, HWND hFocusWindow) { static const IZ_UINT MEM_SIZE = 16 * 1024 * 1024; // 16MB static IZ_UINT8 MEM_BUF[MEM_SIZE]; // システム初期化 IZ_BOOL ret = CMySystem::GetInstance().Init(MEM_SIZE, MEM_BUF); VRETURN(ret); // グラフィックスデバイス設定 izanagi::SGraphicsDeviceInitParams sParams; { sParams.hFocusWindow = hFocusWindow; sParams.hDeviceWindow = hDeviceWindow; sParams.Windowed = IZ_TRUE; // 画面モード(ウインドウモード) sParams.BackBufferWidth = SCREEN_WIDTH; // バックバッファの幅 sParams.BackBufferHeight = SCREEN_HEIGHT; // バックバッファの高さ sParams.MultiSampleType = D3DMULTISAMPLE_NONE; // マルチ・サンプリングの種類 sParams.Adapter = D3DADAPTER_DEFAULT; sParams.DeviceType = D3DDEVTYPE_HAL; sParams.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; sParams.DepthStencilFormat = D3DFMT_D24S8; sParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; } // デバイスリセット ret = CMySystem::GetInstance().GetGraphicsDevice()->Reset(sParams); VRETURN(ret); // デバッグフォント初期化 ret = CMySystem::GetInstance().InitDebugFont(); VRETURN(ret); // リセット用コールバックセット //CMySystem::GetInstance().GetGraphicsDevice()->SetResetCallBack(_ResetResource); // ステート初期化 ret = CStateManager::GetInstance().Init(); VRETURN(ret); // カメラ初期化 { izanagi::math::CVector vecPos(0.0f, 0.0f, 20.0f, 1.0f); izanagi::math::CVector vecRef(0.0f, 0.0f, 0.0f, 1.0f); izanagi::math::CVector vecUp(0.0f, 1.0f, 0.0f, 1.0f); CMyCamera::GetInstance().Init( vecPos, vecRef, vecUp, 1.0f, 1000.0f, izanagi::math::CMath::Deg2Rad(90.0f), (IZ_FLOAT)SCREEN_WIDTH / SCREEN_HEIGHT); } #if 1 // パッド初期化 { D_INPUT* pInput = NULL; HRESULT hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL); IZ_ASSERT(SUCCEEDED(hr)); ret = CMySystem::GetInstance().InitKeyboard(); if (ret) { izanagi::SInputDeviceInitParam sInitParam(pInput, hDeviceWindow); CMySystem::GetInstance().GetKeyboard()->Init(&sInitParam); } pInput->Release(); //VRETURN(ret); } #endif return IZ_TRUE; }
void CGame::Draw() { Vector vecForward = m_hPlayer->GetGlobalView(); Vector vecUp(0, 1, 0); // Cross-product http://www.youtube.com/watch?v=FT7MShdqK6w Vector vecRight = vecUp.Cross(vecForward).Normalized(); CRenderer* pRenderer = GetRenderer(); // Tell the renderer how to set up the camera. pRenderer->SetCameraPosition(m_hPlayer->GetGlobalOrigin() - vecForward * 6 + vecUp * 3 - vecRight * 0.5f); pRenderer->SetCameraDirection(vecForward); pRenderer->SetCameraUp(Vector(0, 1, 0)); pRenderer->SetCameraFOV(90); pRenderer->SetCameraNear(0.1f); pRenderer->SetCameraFar(1000); // This rendering context is a tool for rendering things to the screen. // All of our drawing commands are part of it. CRenderingContext r(pRenderer); // Clear the depth buffer and set a background color. r.ClearDepth(); r.ClearColor(Color(210, 230, 255)); // CRenderer::StartRendering() - This function sets up OpenGL with the // camera information that we passed it before. pRenderer->StartRendering(&r); m_oFrameFrustum = CFrustum(r.GetProjection() * r.GetView()); // First tell OpenGL what "shader" or "program" to use. r.UseProgram("model"); // Set the sunlight direction. The y component is -1 so the light is pointing down. Vector vecSunlight = Vector(1, -1, 1).Normalized(); // Uncomment this code to make the sunlight rotate: //Vector vecSunlight = Vector(cos(Game()->GetTime()), -1, sin(Game()->GetTime())).Normalized(); r.SetUniform("vecSunlight", vecSunlight); r.SetUniform("bLighted", false); r.SetUniform("bDiffuse", false); // Render the ground. r.SetUniform("vecColor", Vector4D(0.6f, 0.7f, 0.9f, 1)); r.SetUniform("vecCameraPosition", GetRenderer()->GetCameraPosition()); r.BeginRenderTriFan(); r.Normal(Vector(0, 1, 0)); r.Tangent(Vector(1, 0, 0)); r.Bitangent(Vector(0, 0, 1)); r.TexCoord(Vector2D(0, 1)); r.Vertex(Vector(-30, 0, -30)); r.TexCoord(Vector2D(0, 0)); r.Vertex(Vector(-30, 0, 30)); r.TexCoord(Vector2D(1, 0)); r.Vertex(Vector(30, 0, 30)); r.TexCoord(Vector2D(1, 1)); r.Vertex(Vector(30, 0, -30)); r.EndRender(); r.SetUniform("bLighted", true); // Prepare a list of entities to render. m_apRenderOpaqueList.clear(); m_apRenderTransparentList.clear(); for (size_t i = 0; i < MAX_CHARACTERS; i++) { CCharacter* pCharacter = GetCharacterIndex(i); if (!pCharacter) continue; // We need to scale the AABB using the character's scale values before we can use it to calculate our center/radius. AABB aabbSizeWithScaling = pCharacter->m_aabbSize * pCharacter->m_vecScaling; Vector vecCharacterCenter = pCharacter->GetGlobalOrigin() + aabbSizeWithScaling.GetCenter(); float flCharacterRadius = aabbSizeWithScaling.GetRadius(); // If the entity is outside the viewing frustum then the player can't see it - don't draw it. // http://youtu.be/4p-E_31XOPM if (!m_oFrameFrustum.SphereIntersection(vecCharacterCenter, flCharacterRadius)) continue; if (pCharacter->m_bDrawTransparent) m_apRenderTransparentList.push_back(pCharacter); else m_apRenderOpaqueList.push_back(pCharacter); } // Draw all opaque characters first. DrawCharacters(m_apRenderOpaqueList, false); for (size_t i = 0; i < MAX_CHARACTERS; i++) { CCharacter* pCharacter = GetCharacterIndex(i); if (!pCharacter) continue; if (!pCharacter->m_bEnemyAI) continue; float flRadius = 3.5f; Vector vecIndicatorOrigin = NearestPointOnSphere(m_hPlayer->GetGlobalOrigin(), flRadius, pCharacter->GetGlobalOrigin()); float flBoxSize = 0.1f; r.SetUniform("vecColor", Color(255, 0, 0, 255)); r.RenderBox(vecIndicatorOrigin - Vector(1, 1, 1)*flBoxSize, vecIndicatorOrigin + Vector(1, 1, 1)*flBoxSize); } // Sort the transparent render list so that we paint the items farther from the camera first. http://youtu.be/fEjZrwDKdi8 MergeSortTransparentRenderList(); // Now draw all transparent characters, sorted by distance from the camera. DrawCharacters(m_apRenderTransparentList, true); r.SetUniform("bDiffuse", false); // Render any bullet tracers that may have been created. float flBulletTracerTime = 0.1f; for (size_t i = 0; i < Game()->GetTracers().size(); i++) { if (Game()->GetTime() < Game()->GetTracers()[i].flTimeCreated + flBulletTracerTime) { Vector vecStart = Game()->GetTracers()[i].vecStart; Vector vecEnd = Game()->GetTracers()[i].vecEnd; r.SetUniform("vecColor", Vector4D(1, 0.9f, 0, 1)); r.BeginRenderLines(); r.Normal(Vector(0, 1, 0)); r.Vertex(vecStart); r.Vertex(vecEnd); r.EndRender(); } } // Render any puffs that may have been created. float flPuffTime = 0.3f; for (size_t i = 0; i < Game()->GetPuffs().size(); i++) { if (Game()->GetTime() < Game()->GetPuffs()[i].flTimeCreated + flPuffTime) { float flTimeCreated = Game()->GetPuffs()[i].flTimeCreated; float flTimeOver = Game()->GetPuffs()[i].flTimeCreated + flPuffTime; float flStartSize = 0.2f; float flEndSize = 2.0f; float flSize = Remap(Game()->GetTime(), flTimeCreated, flTimeOver, flStartSize, flEndSize); Vector vecOrigin = Game()->GetPuffs()[i].vecOrigin; int iOrange = (int)Remap(Game()->GetTime(), flTimeCreated, flTimeOver, 0, 255); r.SetUniform("vecColor", Color(255, iOrange, 0, 255)); r.RenderBox(vecOrigin - Vector(1, 1, 1)*flSize, vecOrigin + Vector(1, 1, 1)*flSize); } } GraphDraw(); pRenderer->FinishRendering(&r); // Call this last. Your rendered stuff won't appear on the screen until you call this. Application()->SwapBuffers(); }
// In this Update() function we need to update all of our characters. Move them around or whatever we want to do. // http://www.youtube.com/watch?v=c4b9lCfSDQM void CGame::Update(float dt) { Vector x0 = m_hPlayer->GetGlobalOrigin(); // The approach function http://www.youtube.com/watch?v=qJq7I2DLGzI m_hPlayer->m_vecMovement.x = Approach(m_hPlayer->m_vecMovementGoal.x, m_hPlayer->m_vecMovement.x, dt * 65); m_hPlayer->m_vecMovement.z = Approach(m_hPlayer->m_vecMovementGoal.z, m_hPlayer->m_vecMovement.z, dt * 65); Vector vecForward = m_hPlayer->GetGlobalView(); vecForward.y = 0; vecForward.Normalize(); Vector vecUp(0, 1, 0); // Cross product http://www.youtube.com/watch?v=FT7MShdqK6w Vector vecRight = vecUp.Cross(vecForward); float flSaveY = m_hPlayer->m_vecVelocity.y; m_hPlayer->m_vecVelocity = vecForward * m_hPlayer->m_vecMovement.x + vecRight * m_hPlayer->m_vecMovement.z; m_hPlayer->m_vecVelocity.y = flSaveY; // Update position and vecMovement. http://www.youtube.com/watch?v=c4b9lCfSDQM m_hPlayer->SetTranslation(m_hPlayer->GetGlobalOrigin() + m_hPlayer->m_vecVelocity * dt); m_hPlayer->m_vecVelocity = m_hPlayer->m_vecVelocity + m_hPlayer->m_vecGravity * dt; // Make sure the player doesn't fall through the floor. The y dimension is up/down, and the floor is at 0. Vector vecTranslation = m_hPlayer->GetGlobalOrigin(); if (vecTranslation.y < 0) m_hPlayer->SetTranslation(Vector(vecTranslation.x, 0, vecTranslation.z)); // Grab the player's translation and make a translation only matrix. http://www.youtube.com/watch?v=iCazI3nKBf0 Vector vecPosition = m_hPlayer->GetGlobalOrigin(); Matrix4x4 mPlayerTranslation; mPlayerTranslation.SetTranslation(vecPosition); // Create a set of basis vectors that do what we need. vecForward = m_hPlayer->GetGlobalView(); vecForward.y = 0; // Flatten the angles so that the box doesn't rotate up and down as the player does. vecForward.Normalize(); // Re-normalize, we need all of our basis vectors to be normal vectors (unit-length) vecUp = Vector(0, 1, 0); // The global up vector vecRight = -vecUp.Cross(vecForward).Normalized(); // Cross-product: https://www.youtube.com/watch?v=FT7MShdqK6w // Use these basis vectors to make a matrix that will transform the player-box the way we want it. // http://youtu.be/8sqv11x10lc Matrix4x4 mPlayerRotation(vecForward, vecUp, vecRight); Matrix4x4 mPlayerScaling = Matrix4x4(); // Produce a transformation matrix from our three TRS matrices. // Order matters! http://youtu.be/7pe1xYzFCvA m_hPlayer->SetGlobalTransform(mPlayerTranslation * mPlayerRotation * mPlayerScaling); Vector x1 = m_hPlayer->GetGlobalOrigin(); float flPlayerDistanceTraveled = m_hPlayer->m_flDistanceTraveled; // Add the distance traveled this frame. flPlayerDistanceTraveled += (x1 - x0).Length(); m_hPlayer->m_flDistanceTraveled = flPlayerDistanceTraveled; float flMonsterSpeed = 0.5f; for (size_t i = 0; i < MAX_CHARACTERS; i++) { CCharacter* pCharacter = GetCharacterIndex(i); if (!pCharacter) continue; if (!pCharacter->m_bEnemyAI) continue; // Update position and movement. http://www.youtube.com/watch?v=c4b9lCfSDQM pCharacter->m_vecVelocity = (m_hPlayer->GetGlobalOrigin() - pCharacter->GetGlobalOrigin()).Normalized() * flMonsterSpeed; pCharacter->SetTranslation(pCharacter->GetGlobalOrigin() + pCharacter->m_vecVelocity * dt); } if (Game()->GetTime() >= m_projectile_initial_time + 8) { m_projectile_position[0] = m_projectile_initial_position; m_projectile_velocity[0] = m_projectile_initial_velocity = Vector((float)(mtrand()%1000)/250-2, 2.5, (float)(mtrand()%1000)/250-2) * 5; m_projectile_initial_time = Game()->GetTime(); m_projectile_break_time = Game()->GetTime() + PredictProjectileMaximumHeightTime(m_projectile_initial_velocity, m_projectile_gravity); m_projectile_number = 1; } if (Game()->GetTime() >= m_projectile_break_time && m_projectile_number == 1) { for (int i = 1; i < MAX_PROJECTILES; i++) { m_projectile_position[i] = m_projectile_position[0]; m_projectile_velocity[i] = m_projectile_velocity[0] + Vector((float)(mtrand()%1000)/250-2, (float)(mtrand()%1000)/250-2, (float)(mtrand()%1000)/250-2); } m_projectile_number = MAX_PROJECTILES; } // Simulate the projectile for (int i = 0; i < m_projectile_number; i++) { m_projectile_position[i] = m_projectile_position[i] + m_projectile_velocity[i] * dt; m_projectile_velocity[i] = m_projectile_velocity[i] + m_projectile_gravity * dt; if (m_projectile_position[i].y < 0) { MakePuff(m_projectile_position[i]); m_projectile_position[i].y = 9999999; // Move it way up high and out of sight until it gets reset. Sort of a hack, no big deal. } } }
//------------------------------------------------------------------------ int CGraphicsLayer::CreateShader() { HRESULT r=0; DWORD ShaderFlags=D3D10_SHADER_ENABLE_STRICTNESS; ID3D10Blob *pErrors = 0; // Compile shaders ID3D10Blob* pBlobVS = NULL; ID3D10Blob* pBlobHS = NULL; ID3D10Blob* pBlobDS = NULL; ID3D10Blob* pBlobPS = NULL; ID3D10Blob* pBlobGS = NULL; ID3D10Blob* pBlobGSFur = NULL; if(CompileShaderFromFile( L"D3D11SimpleFx.hlsl", "SmoothVS", "vs_5_0", &pBlobVS )!=S_OK){return 1;} if(CompileShaderFromFile( L"D3D11SimpleFx.hlsl", "SmoothHS", "hs_5_0", &pBlobHS )!=S_OK){return 1;} if(CompileShaderFromFile( L"D3D11SimpleFx.hlsl", "SmoothDS", "ds_5_0", &pBlobDS )!=S_OK){return 1;} if(CompileShaderFromFile( L"D3D11SimpleFx.hlsl", "SmoothGS", "gs_5_0", &pBlobGS )!=S_OK){return 1;} if(CompileShaderFromFile( L"D3D11SimpleFx.hlsl", "FurGS", "gs_5_0", &pBlobGSFur )!=S_OK){return 1;} if(CompileShaderFromFile( L"D3D11SimpleFx.hlsl", "SmoothPS", "ps_5_0", &pBlobPS )!=S_OK){return 1;} if(m_pDevice->CreateVertexShader( pBlobVS->GetBufferPointer(), pBlobVS->GetBufferSize(), NULL, &m_pVSGouraud )!=S_OK){return 1;} if(m_pDevice->CreateHullShader( pBlobHS->GetBufferPointer(), pBlobHS->GetBufferSize(), NULL, &m_pHSSmooth )!=S_OK){return 1;} if(m_pDevice->CreateDomainShader( pBlobDS->GetBufferPointer(), pBlobDS->GetBufferSize(), NULL, &m_pDSSmooth )!=S_OK){return 1;} if(m_pDevice->CreateGeometryShader( pBlobGS->GetBufferPointer(), pBlobGS->GetBufferSize(), NULL, &m_pGSSmooth )!=S_OK){return 1;} if(m_pDevice->CreatePixelShader( pBlobPS->GetBufferPointer(), pBlobPS->GetBufferSize(), NULL, &m_pPSGouraud )!=S_OK){return 1;} if(m_pDevice->CreateGeometryShader( pBlobGSFur->GetBufferPointer(), pBlobGSFur->GetBufferSize(), NULL, &m_pGSFur )!=S_OK){return 1;} D3D11_INPUT_ELEMENT_DESC defaultLayout[] = { {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT ,0, 0,D3D11_INPUT_PER_VERTEX_DATA,0}, }; if(m_pDevice->CreateInputLayout( defaultLayout, ARRAYSIZE( defaultLayout ), pBlobVS->GetBufferPointer(), pBlobVS->GetBufferSize(), &m_pVertexLayout )!=S_OK){return 1;} m_pDeviceContext->IASetInputLayout(m_pVertexLayout); if(CreateConstantsBuffer()!=S_OK){return 1;} D3DXMATRIX mtxWorld; D3DXMatrixIdentity(&mtxWorld); SetWorldMtx(mtxWorld); D3DXMATRIX mtxView; D3DXVECTOR3 vecEye(3.0f, 3.0f, 3.5f); D3DXVECTOR3 vecAt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vecUp(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&mtxView, &vecEye, &vecAt, &vecUp); SetViewMtx(mtxView); D3DXMatrixPerspectiveFovLH(&m_mProj, (float)D3DX_PI * 0.5f, m_rcScreenRect.right/(float)m_rcScreenRect.bottom, 0.1f, 50.0f); UpdateMatrices(); }