//------------------------------------------------------------------------------- // @ Player::Render() //------------------------------------------------------------------------------- // Render stuff //------------------------------------------------------------------------------- void Player::Render() { mLightPosUniform->SetValue(mLightPos[0], 0); mLightPosUniform->SetValue(mLightPos[1], 1); int i,j; for (j = -1; j <= 1; j++) { for (i = -1; i <= 1; i++) { // build 4x4 matrix IvMatrix44 transform; transform.Scaling(IvVector3(mRadius, mRadius, mRadius)); transform(0, 3) = 5.0f * i; transform(2, 3) = 5.0f * j; mViewPosUniform->SetValue(IvVector3(0.0f, -10.0f, 0.0f), 0); IvSetWorldMatrix(transform); mShader->GetUniform("modelMatrix")->SetValue(transform, 0); // draw geometry IvDrawUnitSphere(); } } } // End of Player::Render()
//------------------------------------------------------------------------------- // @ Game::Render() //------------------------------------------------------------------------------- // Render stuff //------------------------------------------------------------------------------- void Game::Render() { // set perspective matrix Perspective( IvRenderer::mRenderer->GetFOV(), (float)IvRenderer::mRenderer->GetWidth()/(float)IvRenderer::mRenderer->GetHeight(), IvRenderer::mRenderer->GetNearPlane(), IvRenderer::mRenderer->GetFarPlane() ); // set viewer IvSetDefaultViewer( -10.0f, 0.0f, 5.0f ); // draw axes IvDrawAxes(); // draw floor IvDrawFloor(); // draw some objects IvMatrix44 worldTransform; worldTransform.Translation( IvVector3( 0.0f, 0.0f, 1.0f ) ); IvSetWorldMatrix( worldTransform ); IvDrawCube(); worldTransform.Translation( IvVector3( 0.0f, 3.0f, 0.0f ) ); IvSetWorldMatrix( worldTransform ); IvDrawTeapot(); worldTransform.Translation( IvVector3( 0.0f, -2.5f, 1.0f ) ); IvSetWorldMatrix( worldTransform ); IvDrawSphere( 1.0f ); }
//------------------------------------------------------------------------------- // @ Player::Player() //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- Player::Player() { mRadius = 2.0f; mShader = IvRenderer::mRenderer->GetResourceManager()->CreateShaderProgram( IvRenderer::mRenderer->GetResourceManager()->CreateVertexShaderFromFile( "multiShader"), IvRenderer::mRenderer->GetResourceManager()->CreateFragmentShaderFromFile( "multiShader")); IvRenderer::mRenderer->SetShaderProgram(mShader); mShader->GetUniform("pointLightIntensity")->SetValue(IvVector3(20.f, 20.f, 0.0f), 0); mShader->GetUniform("ambientLightColor")->SetValue(IvVector3(0.0f, 0.0f, 0.2f), 0); mLightPos[0] = IvVector3(-15.0f, -10.0f, 0.0f); mLightPos[1] = IvVector3(15.0f, -10.0f, 0.0f); mSpecularPercentage = 0.25f; mAmbientFactor = 0.1f; mEmissiveFactor = 0.0f; ComputeMaterialComponents(); mLightPosUniform = mShader->GetUniform("pointLightPosition"); mViewPosUniform = mShader->GetUniform("viewPosition"); mCurrentLight = 0; } // End of Player::Player()
//------------------------------------------------------------------------------- // @ Player::Update() //------------------------------------------------------------------------------- // Main update loop //------------------------------------------------------------------------------- void Player::Update( float dt ) { float x = 0.0f, y = 0.0f, z = 0.0f; static bool lightPosChanged = true; // set up translation if (IvGame::mGame->mEventHandler->IsKeyDown('k')) { z -= 30.0f*dt; lightPosChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('i')) { z += 30.0f*dt; lightPosChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('l')) { x += 30.0f*dt; lightPosChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('j')) { x -= 30.0f*dt; lightPosChanged = true; } if (lightPosChanged) { mLightPos += IvVector3(x, y, z); lightPosChanged = false; } if (IvGame::mGame->mEventHandler->IsKeyDown('0')) { mShader->GetUniform("pointLightAttenuation")->SetValue( IvVector3(1.0f, 0.0f, 0.0f), 0); } if (IvGame::mGame->mEventHandler->IsKeyDown('1')) { mShader->GetUniform("pointLightAttenuation")->SetValue( IvVector3(0.0f, 0.25f, 0.0f), 0); } if (IvGame::mGame->mEventHandler->IsKeyDown('2')) { mShader->GetUniform("pointLightAttenuation")->SetValue( IvVector3(0.0f, 0.0f, 0.0125f), 0); } // clear transform if (IvGame::mGame->mEventHandler->IsKeyDown(' ')) { mLightPos = IvVector3(0.0f, -10.0f, 0.0f); } } // End of Player::Update()
//------------------------------------------------------------------------------- // @ Player::CreatePlane() //------------------------------------------------------------------------------- // Create vertex arrays for a plane centered around the origin //------------------------------------------------------------------------------- void Player::CreatePlane() { mPlaneVerts = IvRenderer::mRenderer->GetResourceManager()->CreateVertexBuffer( kTCPFormat, 4, nullptr, kDefaultUsage); IvTCPVertex* tempVerts = (IvTCPVertex*)(mPlaneVerts->BeginLoadData()); tempVerts->position = IvVector3(0.0f, -5.0f, -5.0f); tempVerts->texturecoord = IvVector2(1.0f, 0.0f); tempVerts->color.mAlpha = tempVerts->color.mRed = tempVerts->color.mGreen = tempVerts->color.mBlue = 255; tempVerts++; tempVerts->position = IvVector3(0.0f, -5.0f, 5.0f); tempVerts->texturecoord = IvVector2(1.0f, 1.0f); tempVerts->color.mAlpha = tempVerts->color.mRed = tempVerts->color.mGreen = tempVerts->color.mBlue = 255; tempVerts++; tempVerts->position = IvVector3(0.0f, 5.0f, -5.0f); tempVerts->texturecoord = IvVector2(0.0f, 0.0f); tempVerts->color.mAlpha = tempVerts->color.mRed = tempVerts->color.mGreen = tempVerts->color.mBlue = 255; tempVerts++; tempVerts->position = IvVector3(0.0f, 5.0f, 5.0f); tempVerts->texturecoord = IvVector2(0.0f, 1.0f); tempVerts->color.mAlpha = tempVerts->color.mRed = tempVerts->color.mGreen = tempVerts->color.mBlue = 255; mPlaneVerts->EndLoadData(); mPlaneIndices = IvRenderer::mRenderer->GetResourceManager()->CreateIndexBuffer(4, nullptr, kDefaultUsage); unsigned int* tempIndices = (unsigned int*)mPlaneIndices->BeginLoadData(); unsigned int i; for (i = 0; i < 4; i++) tempIndices[i] = i; mPlaneIndices->EndLoadData(); } // End of Player::CreatePlane()
//------------------------------------------------------------------------------- // @ Player::Render() //------------------------------------------------------------------------------- // Render stuff //------------------------------------------------------------------------------- void Player::Render() { // build 4x4 matrix IvMatrix44 transform; transform.Scaling(IvVector3(mRadius, mRadius, mRadius)); int i,j; for (j = -1; j <= 1; j++) { for (i = -1; i <= 1; i++) { transform(0, 3) = 5.0f * i; transform(2, 3) = 5.0f * j; mShader->GetUniform("spotLightPosition")->SetValue( mLightPos, 0); mShader->GetUniform("spotLightDir")->SetValue( mLightDir, 0); ::IvSetWorldMatrix(transform); mShader->GetUniform("modelMatrix")->SetValue(transform, 0); // draw geometry IvDrawUnitSphere(); } } } // End of Player::Render()
//------------------------------------------------------------------------------- // @ Player::Player() //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- Player::Player() { mRotate.Identity(); mScale = 1.0f; mTranslate.Zero(); mPlaneIndices = nullptr; mPlaneVerts = nullptr; mColorTexture = nullptr; mNormalTexture = nullptr; // Load the color and normal textures IvImage* image = IvImage::CreateFromFile("brickwork-texture.tga"); if (image) { mColorTexture = IvRenderer::mRenderer->GetResourceManager()->CreateTexture( (image->GetBytesPerPixel() == 4) ? kRGBA32TexFmt : kRGB24TexFmt, image->GetWidth(), image->GetHeight(), image->GetPixels(), kImmutableUsage); delete image; image = 0; } mColorTexture->SetMagFiltering(kBilerpTexMagFilter); mColorTexture->SetMinFiltering(kBilerpTexMinFilter); mColorTexture->SetAddressingU(kWrapTexAddr); mColorTexture->SetAddressingV(kWrapTexAddr); image = IvImage::CreateFromFile("brickwork_normal-map.tga"); if (image) { mNormalTexture = IvRenderer::mRenderer->GetResourceManager()->CreateTexture( (image->GetBytesPerPixel() == 4) ? kRGBA32TexFmt : kRGB24TexFmt, image->GetWidth(), image->GetHeight(), image->GetPixels(), kImmutableUsage); delete image; image = 0; } mNormalTexture->SetMagFiltering(kBilerpTexMagFilter); mNormalTexture->SetMinFiltering(kBilerpTexMinFilter); mNormalTexture->SetAddressingU(kWrapTexAddr); mNormalTexture->SetAddressingV(kWrapTexAddr); mShader = IvRenderer::mRenderer->GetResourceManager()->CreateShaderProgram( IvRenderer::mRenderer->GetResourceManager()->CreateVertexShaderFromFile( "normalShader"), IvRenderer::mRenderer->GetResourceManager()->CreateFragmentShaderFromFile( "normalShader")); mShader->GetUniform("NormalTexture")->SetValue(mNormalTexture); mShader->GetUniform("ColorTexture")->SetValue(mColorTexture); mLightPos = IvVector3(-0.8f, 0.8f, 0.8f); mLightPos.Normalize(); IvRenderer::mRenderer->SetShaderProgram(mShader); CreatePlane(); } // End of Player::Player()
//------------------------------------------------------------------------------- // @ Player::Player() //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- Player::Player() { mRadius = 5.0f; mSphereIndices = nullptr; mSphereVerts = nullptr; mShader = IvRenderer::mRenderer->GetResourceManager()->CreateShaderProgram( IvRenderer::mRenderer->GetResourceManager()->CreateVertexShaderFromFile( "directionalShader"), IvRenderer::mRenderer->GetResourceManager()->CreateFragmentShaderFromFile( "directionalShader")); IvRenderer::mRenderer->SetShaderProgram(mShader); IvVector3 radiance(1.0f, 1.0f, 1.0f); mShader->GetUniform("dirLightRadiance")->SetValue(radiance, 0); mRotate.Identity(); mLightDir = IvVector3(1.0f, 0.0f, 0.0f); CreateSphere(); } // End of Player::Player()
//------------------------------------------------------------------------------- // @ Obstacle::Obstacle() //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- Obstacle::Obstacle() : SimObject() { SetTranslate( IvVector3( 0.0f, 3.0f, 0.0f ) ); mElasticity = 0.25f; SetMass(20.0f); } // End of Obstacle::Obstacle()
//------------------------------------------------------------------------------- // @ Game::Render() //------------------------------------------------------------------------------- // Render stuff //------------------------------------------------------------------------------- void Game::Render() { // set viewer IvSetDefaultViewer( -10.0f, -2.0f, 5.f ); // draw plane if ( !mPlaneBuffer ) { mPlaneBuffer = IvRenderer::mRenderer->GetResourceManager()->CreateVertexBuffer(kCPFormat, 44, nullptr, kDefaultUsage); IvCPVertex* dataPtr = (IvCPVertex*) mPlaneBuffer->BeginLoadData(); for ( float x = -10.0f; x <= 10.0f; x += 2.0f ) { dataPtr->color = kYellow; dataPtr->position.Set( x, 1.0f, 10.0f ); ++dataPtr; dataPtr->color = kYellow; dataPtr->position.Set( x, 1.0f, -10.0f ); ++dataPtr; } for ( float z = -10.0f; z <= 10.0f; z += 2.0f ) { dataPtr->color = kYellow; dataPtr->position.Set( -10.0f, 1.0f, z ); ++dataPtr; dataPtr->color = kYellow; dataPtr->position.Set( 10.0f, 1.0f, z ); ++dataPtr; } (void) mPlaneBuffer->EndLoadData(); } IvRenderer::mRenderer->Draw( kLineListPrim, mPlaneBuffer ); // draw clipped triangle mClipper.StartClip(); mClipper.ClipVertex( IvVector3( 1.0f, 1.0f, 2.0f )+mPosition ); mClipper.ClipVertex( IvVector3( 0.0f, 3.0f, -2.0f )+mPosition ); mClipper.ClipVertex( IvVector3( -1.0f, -3.0f, -1.0f )+mPosition ); // duplicate first vertex (important) mClipper.ClipVertex( IvVector3( 1.0f, 1.0f, 2.0f )+mPosition ); mClipper.FinishClip(); }
//------------------------------------------------------------------------------- // @ IvVector3::Cross() //------------------------------------------------------------------------------- // Cross product by self //------------------------------------------------------------------------------- IvVector3 IvVector3::Cross( const IvVector3& vector ) const { return IvVector3( y*vector.z - z*vector.y, z*vector.x - x*vector.z, x*vector.y - y*vector.x ); } // End of IvVector3::Cross()
//------------------------------------------------------------------------------- // @ Cross() //------------------------------------------------------------------------------- // Cross product friend operator //------------------------------------------------------------------------------- IvVector3 Cross( const IvVector3& vector1, const IvVector3& vector2 ) { return IvVector3( vector1.y*vector2.z - vector1.z*vector2.y, vector1.z*vector2.x - vector1.x*vector2.z, vector1.x*vector2.y - vector1.y*vector2.x ); } // End of Cross()
//------------------------------------------------------------------------------- // @ Game::Render() //------------------------------------------------------------------------------- // Render stuff //------------------------------------------------------------------------------- void Game::Render() { // set perspective matrix float aspect = (float)IvRenderer::mRenderer->GetWidth()/(float)IvRenderer::mRenderer->GetHeight(); if ( mUseOrthographic ) { Orthographic( -aspect*3.0f+mXCenter, aspect*3.0f+mXCenter, -3.0f+mYCenter, 3.0f+mYCenter, IvRenderer::mRenderer->GetNearPlane(), IvRenderer::mRenderer->GetFarPlane() ); } else { Frustum( -aspect*3.0f+mXCenter, aspect*3.0f+mXCenter, -3.0f+mYCenter, 3.0f+mYCenter, IvRenderer::mRenderer->GetNearPlane(), IvRenderer::mRenderer->GetFarPlane() ); } // set viewer ::IvSetDefaultViewer( 6.0f, 0.0f, 5.f ); // draw axes ::IvDrawAxes(); // draw floor ::IvDrawFloor(); // draw some objects IvMatrix44 worldTransform; worldTransform.Translation( IvVector3( 0.1f, 0.0f, 1.0f ) ); ::IvSetWorldMatrix( worldTransform ); ::IvDrawCube(); worldTransform.Translation( IvVector3( 0.1f, 3.0f, 0.0f ) ); ::IvSetWorldMatrix( worldTransform ); ::IvDrawTeapot(); worldTransform.Translation( IvVector3( 0.1f, -2.5f, 1.0f ) ); ::IvSetWorldMatrix( worldTransform ); ::IvDrawSphere( 1.0f ); }
//------------------------------------------------------------------------------- // @ Player::Player() //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- Player::Player() { mRadius = 2.0f; mShader = IvRenderer::mRenderer->GetResourceManager()->CreateShaderProgram( IvRenderer::mRenderer->GetResourceManager()->CreateVertexShaderFromFile( "pointShader"), IvRenderer::mRenderer->GetResourceManager()->CreateFragmentShaderFromFile( "pointShader")); IvRenderer::mRenderer->SetShaderProgram(mShader); mShader->GetUniform("pointLightIntensity")->SetValue(IvVector3(1.0f, 1.0f, 1.0f), 0); mShader->GetUniform("pointLightAttenuation")->SetValue(IvVector3(0.0f, 0.0f, 0.0125f), 0); mLightPos = IvVector3(0.0f, -10.0f, 0.0f); } // End of Player::Player()
//------------------------------------------------------------------------------- // @ Player::CreateQuad() //------------------------------------------------------------------------------- // Create a quad, centered around the origin //------------------------------------------------------------------------------- void Player::CreateQuad() { const float size = 7.0f; mQuadVerts = IvRenderer::mRenderer->GetResourceManager()->CreateVertexBuffer( kCPFormat, 4, nullptr, kDefaultUsage); // temporary pointers that can be stepped along the arrays IvCPVertex* tempVerts = (IvCPVertex*)(mQuadVerts->BeginLoadData()); tempVerts->color = kGrey; tempVerts->position = IvVector3(0.0f, -size, size); tempVerts++; tempVerts->color = kGrey; tempVerts->position = IvVector3(0.0f, size, size); tempVerts++; tempVerts->color = kGrey; tempVerts->position = IvVector3(0.0f, -size, -size); tempVerts++; tempVerts->color = kGrey; tempVerts->position = IvVector3(0.0f, size, -size); tempVerts++; mQuadVerts->EndLoadData(); mQuadIndices = IvRenderer::mRenderer->GetResourceManager()-> CreateIndexBuffer(4, nullptr, kDefaultUsage); unsigned int* tempIndices = (unsigned int*)(mQuadIndices->BeginLoadData()); int j; for (j = 0; j < 4; j++) *(tempIndices++) = j; mQuadIndices->EndLoadData(); }
//------------------------------------------------------------------------------- // @ Obstacle::Update() //------------------------------------------------------------------------------- // Main update loop //------------------------------------------------------------------------------- void Obstacle::Update( float dt ) { if (IvGame::mGame->mEventHandler->IsKeyDown(' ')) { SetTranslate( IvVector3( 0.0f, 3.0f, 0.0f ) ); mRotate.Identity(); mVelocity.Zero(); mAngularMomentum.Zero(); mAngularVelocity.Zero(); } SimObject::Update( dt ); }
//------------------------------------------------------------------------------- // @ IvQuat::Rotate() //------------------------------------------------------------------------------- // Rotate vector by quaternion // Assumes quaternion is normalized! //------------------------------------------------------------------------------- IvVector3 IvQuat::Rotate( const IvVector3& vector ) const { ASSERT( IsUnit() ); float pMult = w*w - x*x - y*y - z*z; float vMult = 2.0f*(x*vector.x + y*vector.y + z*vector.z); float crossMult = 2.0f*w; return IvVector3( pMult*vector.x + vMult*x + crossMult*(y*vector.z - z*vector.y), pMult*vector.y + vMult*y + crossMult*(z*vector.x - x*vector.z), pMult*vector.z + vMult*z + crossMult*(x*vector.y - y*vector.x) ); } // End of IvQuat::Rotate()
//------------------------------------------------------------------------------- // @ Player::Update() //------------------------------------------------------------------------------- // Main update loop //------------------------------------------------------------------------------- void Player::Update( float dt ) { IvMatrix33 rotateX, rotateY, rotateZ; IvMatrix33 rotate; float heading = 0.0f, pitch = 0.0f, roll = 0.0f; // clear transform if (IvGame::mGame->mEventHandler->IsKeyPressed(' ')) { if (mRun) { // reset animations mTime = 0.0f; mRun = false; heading = mStartHeading; pitch = mStartPitch; roll = mStartRoll; mSlerpRotate = mStartRotate; mNumPoints = 0; mRotate.Rotation( heading, pitch, roll ); } else { // start 'er up again mRun = true; } } // swap orientation reps if (IvGame::mGame->mEventHandler->IsKeyPressed('x')) { mUseQuat = !mUseQuat; mNumPoints = 0; } if (mRun) { // get the next time step mTime += dt; if ( mTime > 8.0f ) mTime = 8.0f; float alpha = mTime/8.0f; // interpolate heading = mStartHeading*(1.0f - alpha) + mEndHeading*alpha; pitch = mStartPitch*(1.0f - alpha) + mEndPitch*alpha; roll = mStartRoll*(1.0f - alpha) + mEndRoll*alpha; Slerp(mSlerpRotate, mStartRotate, mEndRotate, alpha); // set rotation matrix based on current orientation rep if (mUseQuat) { mRotate.Rotation(mSlerpRotate); } else { mRotate.Rotation( heading, pitch, roll ); } // add new path points if (mNumPoints < 1280 && mFrameCounter == 0) { mStoredPoints[0][mNumPoints] = mRotate*IvVector3(1.0f, -1.0f, 1.0f); mStoredPoints[1][mNumPoints++] = mRotate*IvVector3(-1.0f, 0.0f, -1.0f); } mFrameCounter = (mFrameCounter + 1) % 10; } } // End of Player::Update()
//------------------------------------------------------------------------------- // @ Player::CreateSphere() //------------------------------------------------------------------------------- // Create vertex arrays for a sphere centered around the origin //------------------------------------------------------------------------------- void Player::CreateSphere() { // Creates a grid of points, shaped into a sphere. This is not an // efficient way to create a sphere (the verts are not evenly distributed), // but it shows how to set up arrays of vertices and normals const unsigned int steps = 32; const unsigned int verts = steps * steps; mSphereVerts = IvRenderer::mRenderer->GetResourceManager()->CreateVertexBuffer( kCPFormat, verts, nullptr, kDefaultUsage); // temporary pointers that can be stepped along the arrays IvCPVertex* tempVerts = (IvCPVertex*)(mSphereVerts->BeginLoadData()); // A double loop, walking around and down the sphere const float phiIncrement = kPI / (steps - 1); const float thetaIncrement = kTwoPI / steps; unsigned int j; for (j = 0; j < steps; j++) { float theta = thetaIncrement * j; float sinTheta, cosTheta; IvSinCos(theta, sinTheta, cosTheta); unsigned int i; for (i = 0; i < steps; i++) { float phi = phiIncrement * i - kHalfPI; float sinPhi, cosPhi; IvSinCos(phi, sinPhi, cosPhi); tempVerts->position = IvVector3(mRadius * cosTheta * cosPhi, mRadius * sinTheta * cosPhi, mRadius * sinPhi); tempVerts->color.mAlpha = 255; tempVerts->color.mRed = (255 * j) / (steps - 1); tempVerts->color.mGreen = 0; tempVerts->color.mBlue = (255 * i) / (steps - 1); tempVerts++; } } mSphereVerts->EndLoadData(); // Create index arrays - just a 32x31-quad mesh of triangles // Each of the 32 strips has 31 * 2 triangles plus two dummy indices // This means that there are 31 * 2 + 2 + 2 (two extra to start the // strip, and two extra to end the previous strip) indices in each // strip, although we can avoid two indices in the first strip, as // there is no previous strip to be ended in that case. Thus, // 64 + 66 * 31 indices for the entire sphere const unsigned int sphereIndexCount = steps * 2 + (steps - 1) * (steps * 2 + 2); mSphereIndices = IvRenderer::mRenderer->GetResourceManager()-> CreateIndexBuffer(sphereIndexCount, nullptr, kDefaultUsage); UInt32* tempIndices = (UInt32*)(mSphereIndices->BeginLoadData()); for (j = 0; j < steps; j++) { UInt32 baseIndex0 = steps * j; UInt32 baseIndex1 = steps * ((j + 1) % steps); // restart the strip by doubling the last and next indices if (j != 0) { *(tempIndices++) = tempIndices[-1]; *(tempIndices++) = baseIndex0; } unsigned int i; for (i = 0; i < steps; i++) { *(tempIndices++) = baseIndex0; *(tempIndices++) = baseIndex1; baseIndex0++; baseIndex1++; } } mSphereIndices->EndLoadData(); } // End of Player::CreateSphere()
//------------------------------------------------------------------------------- // @ operator/() //------------------------------------------------------------------------------- // Scalar division //------------------------------------------------------------------------------- IvVector3 IvVector3::operator/( float scalar ) { return IvVector3( x/scalar, y/scalar, z/scalar ); } // End of operator/()
//------------------------------------------------------------------------------- // @ operator*() //------------------------------------------------------------------------------- // Scalar multiplication //------------------------------------------------------------------------------- IvVector3 operator*( float scalar, const IvVector3& vector ) { return IvVector3( scalar*vector.x, scalar*vector.y, scalar*vector.z ); } // End of operator*()
//------------------------------------------------------------------------------- // @ operator*() //------------------------------------------------------------------------------- // Scalar multiplication //------------------------------------------------------------------------------- IvVector3 IvVector3::operator*( float scalar ) { return IvVector3( scalar*x, scalar*y, scalar*z ); } // End of operator*()
//------------------------------------------------------------------------------- // @ IvVector3::operator-=() (unary) //------------------------------------------------------------------------------- // Negate self and return //------------------------------------------------------------------------------- IvVector3 IvVector3::operator-() const { return IvVector3(-x, -y, -z); } // End of IvVector3::operator-()
//------------------------------------------------------------------------------- // @ IvVector3::operator-() //------------------------------------------------------------------------------- // Subtract vector from self and return //------------------------------------------------------------------------------- IvVector3 IvVector3::operator-( const IvVector3& other ) const { return IvVector3( x - other.x, y - other.y, z - other.z ); } // End of IvVector3::operator-()
//------------------------------------------------------------------------------- // @ IvVector3::operator+() //------------------------------------------------------------------------------- // Add vector to self and return //------------------------------------------------------------------------------- IvVector3 IvVector3::operator+( const IvVector3& other ) const { return IvVector3( x + other.x, y + other.y, z + other.z ); } // End of IvVector3::operator+()
//------------------------------------------------------------------------------- // @ Player::Update() //------------------------------------------------------------------------------- // Main update loop //------------------------------------------------------------------------------- void Player::Update( float dt ) { float x = 0.0f, y = 0.0f, z = 0.0f; static bool lightPosChanged = true; // set up translation if (IvGame::mGame->mEventHandler->IsKeyDown('k')) { z -= 3.0f*dt; lightPosChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('i')) { z += 3.0f*dt; lightPosChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('l')) { x += 3.0f*dt; lightPosChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('j')) { x -= 3.0f*dt; lightPosChanged = true; } if (lightPosChanged) { mLightPos[mCurrentLight] += IvVector3(x, y, z); lightPosChanged = false; } if (IvGame::mGame->mEventHandler->IsKeyDown('0')) { mShader->GetUniform("pointLightAttenuation")->SetValue( IvVector4(1.0f, 0.0f, 0.0f, 0.0f), 0); } if (IvGame::mGame->mEventHandler->IsKeyDown('1')) { mShader->GetUniform("pointLightAttenuation")->SetValue( IvVector4(0.0f, 0.25f, 0.0f, 0.0f), 0); } if (IvGame::mGame->mEventHandler->IsKeyDown('2')) { mShader->GetUniform("pointLightAttenuation")->SetValue( IvVector4(0.0f, 0.0f, 0.0125f, 0.0f), 0); } bool materialChanged = false; if (IvGame::mGame->mEventHandler->IsKeyDown('q')) { mAmbientFactor += dt; materialChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('a')) { mAmbientFactor -= dt; materialChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('w')) { mSpecularPercentage += dt; materialChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('s')) { mSpecularPercentage -= dt; materialChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('e')) { mEmissiveFactor += dt; materialChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyDown('d')) { mEmissiveFactor -= dt; materialChanged = true; } if (IvGame::mGame->mEventHandler->IsKeyPressed('c')) { mCurrentLight = (mCurrentLight + 1) % NUM_LIGHTS; } // clear transform if (IvGame::mGame->mEventHandler->IsKeyPressed(' ')) { mLightPos[0] = IvVector3(-15.0f, -10.0f, 0.0f); mLightPos[1] = IvVector3(15.0f, -10.0f, 0.0f); mEmissiveFactor = 0.0f; mAmbientFactor = 0.1f; mSpecularPercentage = 0.25f; materialChanged = true; } if (materialChanged) { ComputeMaterialComponents(); } } // End of Player::Update()
//------------------------------------------------------------------------------- // @ Player::Update() //------------------------------------------------------------------------------- // Main update loop //------------------------------------------------------------------------------- void Player::Update( float dt ) { // get change in transform for this frame IvMatrix44 scale, rotate, xlate, unxform, rexform; scale.Identity(); rotate.Identity(); float s = 1.0f; float r = 0.0f; float x = 0.0f, y = 0.0f, z = 0.0f; // set up scaling if (IvGame::mGame->mEventHandler->IsKeyDown(';')) { s -= 0.25f*dt; } if (IvGame::mGame->mEventHandler->IsKeyDown('p')) { s += 0.25f*dt; } scale.Scaling(IvVector3(s, s, s)); // set up rotate if (IvGame::mGame->mEventHandler->IsKeyDown('o')) { r -= kPI*0.25f*dt; } if (IvGame::mGame->mEventHandler->IsKeyDown('u')) { r += kPI*0.25f*dt; } rotate.RotationZ( r ); // set up translation if (IvGame::mGame->mEventHandler->IsKeyDown('k')) { x -= 3.0f*dt; } if (IvGame::mGame->mEventHandler->IsKeyDown('i')) { x += 3.0f*dt; } if (IvGame::mGame->mEventHandler->IsKeyDown('l')) { y -= 3.0f*dt; } if (IvGame::mGame->mEventHandler->IsKeyDown('j')) { y += 3.0f*dt; } xlate.Translation( IvVector3(x, y, z) ); // clear transform if (IvGame::mGame->mEventHandler->IsKeyDown(' ')) { mTransform.Identity(); } // append transforms for this frame to current transform // note order: // since scale is uniform in this example, we can apply first in transform chain // then we apply old transform // then translate center to origin, rotate around origin, // then retranslate to old position // then finally, apply new translation IvVector3 originalXlate( mTransform(0,3), mTransform(1,3), mTransform(2,3) ); unxform.Translation( -originalXlate ); rexform.Translation( originalXlate ); mTransform = xlate*rexform*rotate*unxform*mTransform*scale; // alternatively, we can save some processing by clearing mTransform's translation // and adding originalXlate to the new translation. The result would be // mTransform = xlate*rotate*mTransform*scale; } // End of Player::Update()
//------------------------------------------------------------------------------- // @ Player::CreateCylinder() //------------------------------------------------------------------------------- // Create vertex arrays for a cylinder centered around the origin //------------------------------------------------------------------------------- void Player::CreateCylinder() { // Creates a grid of points, shaped into a cylinder. In order to avoid a // texturing anomaly, we cannot simply share the vertical seam edge vertices // They must be duplicated; one copy must have a U-coord of 0.0, the other a // U-coord of 1.0f const unsigned int steps = 32; mCylinderVerts = IvRenderer::mRenderer->GetResourceManager()->CreateVertexBuffer( kTCPFormat, (steps + 1) * steps, nullptr, kDefaultUsage); IvTCPVertex* tempVerts0 = (IvTCPVertex*)(mCylinderVerts->BeginLoadData()); // temporary pointers that can be stepped along the arrays const float phiIncrement = kPI / (steps - 1); const float thetaIncrement = kTwoPI / steps; unsigned int i,j; // A double loop, walking around and down the cylinder for (j = 0; j <= steps; j++) { float theta = thetaIncrement * j; float u = j / (float)steps; float sinTheta, cosTheta; IvSinCos(theta, sinTheta, cosTheta); for (i = 0; i < steps; i++) { float phi = -kHalfPI + phiIncrement * i; float v = i / (float)(steps - 1); if (i == 0) { tempVerts0->position = IvVector3(0.0f, 0.0f, -mRadius); } else if (i == (steps - 1)) { tempVerts0->position = IvVector3(0.0f, 0.0f, mRadius); } else { tempVerts0->position = IvVector3(mRadius * cosTheta, mRadius * sinTheta, mRadius * IvSin(phi)); } tempVerts0->texturecoord = IvVector2(u, v); tempVerts0->color.mAlpha = tempVerts0->color.mRed = tempVerts0->color.mGreen = tempVerts0->color.mBlue = 255; tempVerts0++; } } mCylinderVerts->EndLoadData(); // Create index arrays - just a 32x31-quad mesh of triangles // Each of the 32 strips has 31 * 2 triangles plus two dummy indices // This means that there are 31 * 2 + 2 + 2 (two extra to start the // strip, and two extra to end the previous strip) indices in each // strip, although we can avoid two indices in the first strip, as // there is no previous strip to be ended in that case. Thus, // 64 + 66 * 31 indices for the entire cylinder unsigned int cylinderIndexCount = steps * 2 + (steps - 1) * (steps * 2 + 2); mCylinderIndices = IvRenderer::mRenderer->GetResourceManager()->CreateIndexBuffer( cylinderIndexCount, nullptr, kDefaultUsage); UInt32* tempIndices = (UInt32*)mCylinderIndices->BeginLoadData(); for (j = 0; j < steps; j++) { UInt32 baseIndex0 = steps * j; UInt32 baseIndex1 = steps * (j + 1); // restart the strip by doubling the last and next indices if (j != 0) { *(tempIndices++) = tempIndices[-1]; *(tempIndices++) = baseIndex0; } unsigned int i; for (i = 0; i < steps; i++) { *(tempIndices++) = baseIndex0; *(tempIndices++) = baseIndex1; baseIndex0++; baseIndex1++; } } mCylinderIndices->EndLoadData(); } // End of Player::CreateCylinder()
void IvPointRendererD3D11::Setup() { sVertexShader[kPFormat] = sVertexShaderPFormat; sVertexShader[kCPFormat] = sVertexShaderCPFormat; sVertexShader[kNPFormat] = sVertexShaderNPFormat; sVertexShader[kCNPFormat] = sVertexShaderCNPFormat; sVertexShader[kTCPFormat] = sVertexShaderTCPFormat; sVertexShader[kTNPFormat] = sVertexShaderTNPFormat; sFragmentShader[kPFormat] = sFragmentShaderP; sFragmentShader[kCPFormat] = sFragmentShaderCP; sFragmentShader[kNPFormat] = sFragmentShaderCP; sFragmentShader[kCNPFormat] = sFragmentShaderCP; sFragmentShader[kTCPFormat] = sFragmentShaderTCP; sFragmentShader[kTNPFormat] = sFragmentShaderTCP; for (int format = 0; format < kVertexFormatCount; ++format) { // create the shaders sShaders[format] = IvRenderer::mRenderer->GetResourceManager()->CreateShaderProgram( IvRenderer::mRenderer->GetResourceManager()->CreateVertexShaderFromString( sVertexShader[format]), IvRenderer::mRenderer->GetResourceManager()->CreateFragmentShaderFromString( sFragmentShader[format])); // create the vertex layout D3D11_INPUT_ELEMENT_DESC* elements = nullptr; UINT numElements = 0; const char* shaderString = nullptr; switch (format) { case kPFormat: elements = sPFormatElements; numElements = sizeof(sPFormatElements) / sizeof(D3D11_INPUT_ELEMENT_DESC); shaderString = sVertexShaderPFormat; break; case kCPFormat: elements = sCPFormatElements; numElements = sizeof(sCPFormatElements) / sizeof(D3D11_INPUT_ELEMENT_DESC); shaderString = sVertexShaderCPFormat; break; case kNPFormat: elements = sNPFormatElements; numElements = sizeof(sNPFormatElements) / sizeof(D3D11_INPUT_ELEMENT_DESC); shaderString = sVertexShaderNPFormat; break; case kCNPFormat: elements = sCNPFormatElements; numElements = sizeof(sCNPFormatElements) / sizeof(D3D11_INPUT_ELEMENT_DESC); shaderString = sVertexShaderCNPFormat; break; case kTCPFormat: elements = sTCPFormatElements; numElements = sizeof(sTCPFormatElements) / sizeof(D3D11_INPUT_ELEMENT_DESC); shaderString = sVertexShaderTCPFormat; break; case kTNPFormat: elements = sTNPFormatElements; numElements = sizeof(sTNPFormatElements) / sizeof(D3D11_INPUT_ELEMENT_DESC); shaderString = sVertexShaderTNPFormat; break; } ID3DBlob* code; ID3DBlob* errorMessages = nullptr; // compile the shader to assembly // it's not ideal to compile the vertex shader again, but we only have to // go through this process once to create the layout if (FAILED(D3DCompile(shaderString, strlen(shaderString) + 1, nullptr, nullptr, nullptr, "vs_main", "vs_4_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG, 0, &code, &errorMessages))) { const char* errors = reinterpret_cast<const char*>(errorMessages->GetBufferPointer()); DEBUG_OUT("Vertex shader error: "); DEBUG_OUT(errors << std::endl); errorMessages->Release(); ASSERT(false); return; } if (errorMessages) { errorMessages->Release(); } ID3D11Device* device = static_cast<IvRendererD3D11*>(IvRenderer::mRenderer)->GetDevice(); if (FAILED(device->CreateInputLayout(elements, numElements, code->GetBufferPointer(), code->GetBufferSize(), &sInputLayout[format]))) { code->Release(); ASSERT(false); return; } code->Release(); } // create the quad buffer float xCoord = 1.0f / static_cast<float>(IvRenderer::mRenderer->GetWidth()); float yCoord = 1.0f / static_cast<float>(IvRenderer::mRenderer->GetHeight()); IvPVertex verts[4] = { IvVector3(xCoord, -yCoord, 0.0f), IvVector3(xCoord, yCoord, 0.0f), IvVector3(-xCoord, -yCoord, 0.0f), IvVector3(-xCoord, yCoord, 0.0f) }; sQuadBuffer = IvRenderer::mRenderer->GetResourceManager()->CreateVertexBuffer(kPFormat, 4, verts, kImmutableUsage); }