// Startup D3D resources void EditExt::D3DInit() { // Get the D3D device used by the runtime pDevice = (IDirect3DDevice9*)pEditTime->GetDisplayDevice(); if (pDevice == NULL) { MessageBox(NULL, "No DirectX device available", "3D Cube Error", MB_OK | MB_ICONHAND); return; } // Set up the cube vertices hr = pDevice->CreateVertexBuffer(sizeof(TLVERTEX) * 36, D3DUSAGE_WRITEONLY, D3DFVF_TLVERTEX, D3DPOOL_MANAGED, &pVertices, NULL); if (FAILED(hr)) { MessageBox(NULL, "Failed to create vertex buffer", "3D Cube Error", MB_OK | MB_ICONHAND); return; } UpdateVertices(); //Here we build our View Matrix, think of it as our camera. //First we specify that our viewpoint is 8 units back on the Z-axis eye_vector = D3DXVECTOR3( 0.0f, 0.0f, 8.0f ); //We are looking towards the origin lookat_vector = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); //The "up" direction is the positive direction on the y-axis up_vector = D3DXVECTOR3(0.0f,1.0f,0.0f); D3DXMatrixLookAtLH(&view_matrix,&eye_vector, &lookat_vector, &up_vector); SIZE s; s.cx = GetSystemMetrics(SM_CXSCREEN); s.cy = GetSystemMetrics(SM_CYSCREEN); aspect=((float)s.cx / (float)s.cy); D3DXMatrixPerspectiveFovLH(&projection_matrix, //Result Matrix D3DX_PI/4, //Field of View, in radians. aspect, //Aspect ratio 1.0f, //Near view plane 100.0f ); //Far view plane D3DXMatrixIdentity(&worldMatrix); D3DXMatrixIdentity(&rotMatrix); D3DXMatrixIdentity(&transMatrix); D3DXMatrixIdentity(&scaleMatrix); // The vectors used in screen projection orig.x = 0; orig.y = 0; orig.z = 0; normal.x = 0; normal.y = 0; normal.z = 1; // Normal facing the view CreateZBuffer(); }
///////////////////////////// // EDITTIME drawing // Draw your object in the frame editor. void EditExt::Draw() { float ox = pInfo->objectX - (pInfo->objectWidth / 2); float oy = pInfo->objectY - (pInfo->objectHeight / 2); CRect objectRec(ox, oy, ox + pInfo->objectWidth, oy + pInfo->objectHeight); float scaledZ = z / (pInfo->pEditTime->GetEyeDistance3d() / 8.0); float scaledHeight = depth / (pInfo->pEditTime->GetEyeDistance3d() / 8.0); pEditTime->SetTexture(pEditTime->AddImageAsTexture(imgTexture)); pEditTime->EndBatch(); if (pDevice == NULL) D3DInit(); HRESULT hr; // Ensure Z buffer created CreateZBuffer(); // Clear the Z buffer if necessary unsigned int curFrame = pEditTime->GetFrameCount(); unsigned int lastFrame = (unsigned int)pEditTime->GetLayoutKey("zbufferclearframe"); if (lastFrame < curFrame) { hr = pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0); if (FAILED(hr)) MessageBox(NULL, "Failed to clear Z buffer", "3D Box object", MB_OK | MB_ICONHAND); pEditTime->SetLayoutKey("zbufferclearframe", (void*)curFrame, false); } pDevice->SetRenderState(D3DRS_LIGHTING,FALSE); //pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); We cant change the culling because its unchangeable at runtime because Ashley didn't add it as a cr render state, and probably wont add it coz that would be feature creeping pDevice->SetTransform(D3DTS_VIEW, &view_matrix); pDevice->SetTransform(D3DTS_PROJECTION, &projection_matrix); pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); pDevice->GetViewport(&viewport); D3DXMatrixIdentity(&worldMatrix); // Enable the Z stencil if (true) { hr = pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); if (FAILED(hr)) MessageBox(NULL, "Failed to enable Z buffer", "3D Box object", MB_OK | MB_ICONHAND); } if (!drawInit) { // Calculate world units per pixel D3DXVECTOR3 pt1, pt2; ProjectScreenToWorld(&pt1, 0.0f, 0.0f, 0.0f); ProjectScreenToWorld(&pt2, 1.0f, 1.0f, 0.0f); worldPxX = pt1.x - pt2.x; worldPxY = pt1.y - pt2.y; if (worldPxX < 0) worldPxX = -worldPxX; if (worldPxY < 0) worldPxY = -worldPxY; drawInit = true; } // Calculate scaling matrix D3DXMatrixScaling(&scaleMatrix, pInfo->objectWidth * worldPxX * scale, pInfo->objectHeight * worldPxY * scale, scaledHeight * pEditTime->GetZoom() * scale); // Calculate the X and Y world coords to place the box at. D3DXVECTOR3 objectSpace; float objX = pInfo->objectX; float objY = pInfo->objectY; pEditTime->TranslateFrameToScreenCoords(objX, objY); ProjectScreenToWorld(&objectSpace, objX, objY, 0.0f); //D3DXMatrixRotationYawPitchRoll(&rotMatrix, RADIANS(yaw), RADIANS(pitch), RADIANS(pInfo->objectAngle) + RADIANS(roll)); D3DXMATRIX rotMatrixX, rotMatrixY, rotMatrixZ, rotMatrix; D3DXMatrixRotationY(&rotMatrixY, -RADIANS(yaw)); D3DXMatrixRotationX(&rotMatrixX, -RADIANS(pitch)); D3DXMatrixRotationZ(&rotMatrixZ, cr::to_radians(pInfo->objectAngle + roll)); D3DXMatrixMultiply(&rotMatrix, &rotMatrixY, &rotMatrixX); D3DXMatrixMultiply(&rotMatrix, &rotMatrix, &rotMatrixZ); // Multiply the translation, rotation and scaling matrices together to the world matrix D3DXMatrixTranslation(&transMatrix, objectSpace.x, objectSpace.y, scaledZ *pEditTime->GetZoom()); D3DXMatrixMultiply(&worldMatrix, &scaleMatrix, &rotMatrix); D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &transMatrix ); // Use our translated, rotated and scaled matrix as the world matrix hr = pDevice->SetTransform(D3DTS_WORLD, &worldMatrix); if (FAILED(hr)) MessageBox(NULL, "Failed to set transform", "3D Box object", MB_OK | MB_ICONHAND); // Use our vertex stream for(vector<obj>::iterator o = myobject.objs.begin(); o != myobject.objs.end(); o++) { IDirect3DVertexBuffer9* pVertices = (IDirect3DVertexBuffer9*)o->vertexBuffer; IDirect3DIndexBuffer9* pIndexes= (IDirect3DIndexBuffer9*)o->indexBuffer; if(pVertices && pIndexes) { hr = pDevice->SetStreamSource(0, pVertices, 0, sizeof(TLVERTEX)); if (FAILED(hr)) MessageBox(NULL, "Failed to set stream source", "3D Object", MB_OK | MB_ICONHAND); hr = pDevice->SetIndices(pIndexes); if (FAILED(hr)) MessageBox(NULL, "Failed to set indices", "3D Object", MB_OK | MB_ICONHAND); pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, //PrimitiveType 0,0, o->points.size(), 0, o->number_of_indexes / 3); // Each face is 2 triangles } } // Disable the Z stencil hr = pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); if (FAILED(hr)) MessageBox(NULL, "Failed to disable Z buffer", "3D Box object", MB_OK | MB_ICONHAND); // Restore 2D mode pEditTime->SetTexture(-1); pEditTime->EndBatch(); pEditTime->Restore2DMode(); // Draw a 2D shadow to show where the box lies in the 2D layout float ow = pInfo->objectWidth; float oh = pInfo->objectHeight; double HotSpotAngle = atan2(oh, ow); double HotSpotDist = sqrt(ow*ow + oh*oh) / 2; float dx = HotSpotDist * cos(RADIANS(pInfo->objectAngle) + HotSpotAngle); float dy = HotSpotDist * sin(RADIANS(pInfo->objectAngle) + HotSpotAngle); pEditTime->Blitrc(pInfo->objectX - dx, pInfo->objectY - dy, ow, oh, pInfo->objectAngle, 0x40404040); }
///////////////////////////// // EDITTIME drawing // Draw your object in the frame editor. void EditExt::Draw() { float ox = pInfo->objectX - (pInfo->objectWidth / 2); float oy = pInfo->objectY - (pInfo->objectHeight / 2); CRect objectRec(ox, oy, ox + pInfo->objectWidth, oy + pInfo->objectHeight); float scaledZ = z / (pInfo->pEditTime->GetEyeDistance3d() / 8.0 * riseScale); float scaledHeight = height / (pInfo->pEditTime->GetEyeDistance3d() / 8.0 * riseScale); pEditTime->EndBatch(); if (pDevice == NULL) D3DInit(); HRESULT hr; // Ensure Z buffer created CreateZBuffer(); // Clear the Z buffer if necessary unsigned int curFrame = pEditTime->GetFrameCount(); unsigned int lastFrame = (unsigned int)pEditTime->GetLayoutKey("zbufferclearframe"); if (lastFrame < curFrame) { hr = pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0); if (FAILED(hr)) MessageBox(NULL, "Failed to clear Z buffer", "3D Box object", MB_OK | MB_ICONHAND); pEditTime->SetLayoutKey("zbufferclearframe", (void*)curFrame, false); } pDevice->SetRenderState(D3DRS_LIGHTING,FALSE); pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); //Default culling pDevice->SetTransform(D3DTS_VIEW, &view_matrix); pDevice->SetTransform(D3DTS_PROJECTION, &projection_matrix); pDevice->GetViewport(&viewport); D3DXMatrixIdentity(&worldMatrix); // Enable the Z stencil if (zbuffer) { hr = pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); if (FAILED(hr)) MessageBox(NULL, "Failed to enable Z buffer", "3D Box object", MB_OK | MB_ICONHAND); } if (!drawInit) { // Calculate world units per pixel D3DXVECTOR3 pt1, pt2; ProjectScreenToWorld(&pt1, 0.0f, 0.0f, 0.0f); ProjectScreenToWorld(&pt2, 1.0f, 1.0f, 0.0f); worldPxX = pt1.x - pt2.x; worldPxY = pt1.y - pt2.y; if (worldPxX < 0) worldPxX = -worldPxX; if (worldPxY < 0) worldPxY = -worldPxY; drawInit = true; } // Calculate scaling matrix D3DXMatrixScaling(&scaleMatrix, pInfo->objectWidth * worldPxX, pInfo->objectHeight * worldPxY, scaledHeight * pEditTime->GetZoom()); // Calculate the X and Y world coords to place the box at. D3DXVECTOR3 objectSpace; float objX = pInfo->objectX;// + pInfo->objectWidth / 2; float objY = pInfo->objectY;// + pInfo->objectHeight / 2; pEditTime->TranslateFrameToScreenCoords(objX, objY); ProjectScreenToWorld(&objectSpace, objX, objY, 0.0f); D3DXMatrixRotationYawPitchRoll(&rotMatrix, 0.0f, 0.0f, RADIANS(pInfo->objectAngle)); // Multiply the translation, rotation and scaling matrices together to the world matrix D3DXMatrixTranslation(&transMatrix, objectSpace.x, objectSpace.y, (scaledZ+scaledHeight/2.0f)*pEditTime->GetZoom()); D3DXMatrixMultiply(&worldMatrix, &rotMatrix, &transMatrix); D3DXMatrixMultiply(&worldMatrix, &scaleMatrix, &worldMatrix); // Use our translated, rotated and scaled matrix as the world matrix hr = pDevice->SetTransform(D3DTS_WORLD, &worldMatrix); if (FAILED(hr)) MessageBox(NULL, "Failed to set transform", "3D Box object", MB_OK | MB_ICONHAND); // Use our vertex stream hr = pDevice->SetStreamSource(0, pVertices, 0, sizeof(TLVERTEX)); if (FAILED(hr)) MessageBox(NULL, "Failed to set stream source", "3D Box object", MB_OK | MB_ICONHAND); UpdateTextures(); // Draw each face separately for (int i = 0; i < 6; i++) { pEditTime->SetTexture(textures[i]); pEditTime->EndBatch(); pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, //PrimitiveType i * 6, 2); // Each face is 2 triangles } // Disable the Z stencil hr = pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); if (FAILED(hr)) MessageBox(NULL, "Failed to disable Z buffer", "3D Box object", MB_OK | MB_ICONHAND); // Restore 2D mode pEditTime->SetTexture(-1); pEditTime->EndBatch(); pEditTime->Restore2DMode(); // Draw a 2D shadow to show where the box lies in the 2D layout float ow = pInfo->objectWidth; float oh = pInfo->objectHeight; double HotSpotAngle = atan2(oh, ow); double HotSpotDist = sqrt(ow*ow + oh*oh) / 2; float dx = HotSpotDist * cos(RADIANS(pInfo->objectAngle) + HotSpotAngle); float dy = HotSpotDist * sin(RADIANS(pInfo->objectAngle) + HotSpotAngle); pEditTime->Blitrc(pInfo->objectX - dx, pInfo->objectY - dy, ow, oh, pInfo->objectAngle, 0x40404040); }