Jump to content
  • Advertisement

Tiege

Member
  • Content Count

    77
  • Joined

  • Last visited

Everything posted by Tiege

  1. I'm making a side scroller and just curious about possible collision methods for the map itself. The most practical I can think of is hard coding all the points on the map I want to make line segments for the boundaries. I also thought about making a second layer for the map which will be the actual physical part while the rest is passthrough. But if I have to hardcode the physical parts anyway then is it just a waste loading it if I don't really need it? Is there a way to make meshes physical with other meshes or is that all manually coded with collision boxes and spheres, etc?
  2. Tiege

    Ground Collision methods?

    Well i don't intend to use others' libraries :\. I don't need things like friction, impulse, etc. Just want my guy to not fall through the floor But thanks for the advice!
  3. Tiege

    Ground Collision methods?

    Sorry about the confusing terminology. Obviously I have little to no idea what I'm doing haha. Thanks for being patient with me. I like the idea of that convex hull method. How would I go about implementing that in my code? Also once I eventually do have my collision area mapped out then give a bounding box to the character or something how would I detect the intersection between the two? I have a map made and also kind of the collision mask to go with it. Would it just be simpler to make the collision meshes solid for my collision with the terrain and platforms?
  4. Tiege

    Ground Collision methods?

    You must be joking. Consider a data-driven approach instead, you might find JSON useful. Separating collision geometry from visible geometry is heavily recommended. It is standard in many AAA games for performance reasons, but it buys a lot of flexibility even in small projects (the infamous "secret room wall"). (1) Yes, there is, but it's not automatic. In general, meshes are approximated in some way. In general you'll have to figure out yourself whatever a mesh is solid or not. An artist will have to flag the mesh as "nonsolid". In certain systems, this "nonsolid" flag was embedded in material properties. (2) It is automatically [s]coded[/s] input (by using data-driven systems). Very little things are hardcoded nowadays. If your level is data, your collisions should be data as well (and preferably go together). Do not mix data and hard-coded stuff (hard-coded ~= assumption). It will sink way too much effort in the making. Historically, cubes/boxes/spheres have been used. Now k-DOPs, convex hulls, cones... if everything fails, the whole tri-mesh will be used. Trimeshes are typically quite slow, but sometimes they are necessary. [/quote] Thanks for the info. I was wondering about visible vs collision geometry because in tutorials where they create bounding boxes/spheres, I just wondered why bother loading an additional model if you have to program that anyway? The only thing that model gives is its max and min vertices to create a box. But for example think of a map in super smash bros melee. The background is the invisible geometry (im assuming) which has no interaction but gives the game visual. The collision geometry is the ground, the platforms, etc. The stuff the characters can actually stand on. This is basically what i'm trying to create. I would make a bounding box for the platforms but what about the ground when it's slanted and distorted so that it cant possibly be covered correctly by boxes? Something like this:
  5. For those of you out there who use Blender. How do you export a model with multiple animations in a single file? Is it through the action editor? Like if you add say a walk, idle, and run action then when you export those are all included? And how are they arranged to access using directx animation tracks?
  6. I'm making a side scroller and just curious about possible collision methods for the map itself. The most practical I can think of is hard coding all the points on the map I want to make line segments for the boundaries. I also thought about making a second layer for the map which will be the actual physical part while the rest is passthrough. But if I have to hardcode the physical parts anyway then is it just a waste loading it if I don't really need it? Is there a way to make meshes physical with other meshes or is that all manually coded with collision boxes and spheres, etc?
  7. Sorry I actually have a question. How did you fit more than one animation in a single file? And what program did you use? My friend is making models for me using Blender but were not sure exactly how to get multiple animations in the same .x file.
  8. In your If statement get rid of the != D3D_OK and just put ! infront of the function
  9. Can anyone see something in this code that I can't as to why my materials and textures wont load on my animated models? I'm sure the pathing is correct because I can get it to work for a static model but when I load mesh from hierarchy the model loads, renders, and animates but it's just black (no material or texture). Any thoughts? I am using code from tutorials I've read HRESULT CMeshHierarchy::CreateMeshContainer( LPCSTR Name, CONST D3DXMESHDATA *meshData, CONST D3DXMATERIAL *materials, CONST D3DXEFFECTINSTANCE *effectInstances, DWORD numMaterials, CONST DWORD *adjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER* retNewMeshContainer) { // Create a mesh container structure to fill and initilaise to zero values // Note: I use my extended version of the structure (D3DXMESHCONTAINER_EXTENDED) defined in MeshStructures.h D3DXMESHCONTAINER_EXTENDED *newMeshContainer=new D3DXMESHCONTAINER_EXTENDED; ZeroMemory(newMeshContainer, sizeof(D3DXMESHCONTAINER_EXTENDED)); // Always a good idea to initialise return pointer before proceeding *retNewMeshContainer = 0; // The mesh name (may be 0) needs copying over if (Name != NULL) { newMeshContainer->Name = new char[strlen(Name) + 1]; strcpy(newMeshContainer->Name, Name); } // The mesh type (D3DXMESHTYPE_MESH, D3DXMESHTYPE_PMESH or D3DXMESHTYPE_PATCHMESH) if (meshData->Type!=D3DXMESHTYPE_MESH) { // This demo does not handle mesh types other than the standard // Other types are D3DXMESHTYPE_PMESH (progressive mesh) and D3DXMESHTYPE_PATCHMESH (patch mesh) DestroyMeshContainer(newMeshContainer); return E_FAIL; } newMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; // Adjacency data - holds information about triangle adjacency, required by the ID3DMESH object DWORD dwFaces = meshData->pMesh->GetNumFaces(); newMeshContainer->pAdjacency = new DWORD[dwFaces*3]; if (adjacency) { memcpy(newMeshContainer->pAdjacency, adjacency, sizeof(DWORD) * dwFaces*3); } else { // Added 24/08/10: previously did not detect null adjacency if(FAILED( newMeshContainer->MeshData.pMesh->GenerateAdjacency( 1e-6f, (DWORD*)(void*)newMeshContainer->pAdjacency ) ) ) FillMemory((void*)newMeshContainer->pAdjacency, dwFaces*3, 0xFF ); } // Get the Direct3D device, luckily this is held in the mesh itself (Note: must release it when done with it) LPDIRECT3DDEVICE9 pd3dDevice = 0; meshData->pMesh->GetDevice(&pd3dDevice); // Changed 24/09/07 - can just assign pointer and add a ref rather than need to clone newMeshContainer->MeshData.pMesh=meshData->pMesh; newMeshContainer->MeshData.pMesh->AddRef(); // Create material and texture arrays. Note that I always want to have at least one newMeshContainer->NumMaterials = max(numMaterials,1); newMeshContainer->exMaterials = new D3DMATERIAL9[newMeshContainer->NumMaterials]; newMeshContainer->exTextures = new LPDIRECT3DTEXTURE9[newMeshContainer->NumMaterials]; ZeroMemory(newMeshContainer->exTextures, sizeof(LPDIRECT3DTEXTURE9) * newMeshContainer->NumMaterials); if (numMaterials>0) { // Load all the textures and copy the materials over for(DWORD i = 0; i < numMaterials; ++i) { newMeshContainer->exTextures = 0; newMeshContainer->exMaterials=materials.MatD3D; if(materials.pTextureFilename) { D3DXCreateTextureFromFile(pd3dDevice, materials.pTextureFilename, &newMeshContainer->exTextures); } } } else // make a default material in the case where the mesh did not provide one { ZeroMemory(&newMeshContainer->exMaterials[0], sizeof( D3DMATERIAL9 ) ); newMeshContainer->exMaterials[0].Diffuse.r = 0.5f; newMeshContainer->exMaterials[0].Diffuse.g = 0.5f; newMeshContainer->exMaterials[0].Diffuse.b = 0.5f; newMeshContainer->exMaterials[0].Specular = newMeshContainer->exMaterials[0].Diffuse; newMeshContainer->exTextures[0]=0; } // If there is skin data associated with the mesh copy it over if (pSkinInfo) { // save off the SkinInfo newMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); // Need an array of offset matrices to move the vertices from the figure space to the bone's space UINT numBones = pSkinInfo->GetNumBones(); newMeshContainer->exBoneOffsets = new D3DXMATRIX[numBones]; // Create the arrays for the bones and the frame matrices newMeshContainer->exFrameCombinedMatrixPointer = new D3DXMATRIX*[numBones]; // get each of the bone offset matrices so that we don't need to get them later for (UINT i = 0; i < numBones; i++) newMeshContainer->exBoneOffsets = *(newMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i)); // Note: in the Microsoft samples a GenerateSkinnedMesh function is called here in order to prepare // the skinned mesh data for optimial hardware acceleration. As mentioned in the notes this sample // does not do hardware skinning but instead uses software skinning. } else { // No skin info so 0 all the pointers newMeshContainer->pSkinInfo = 0; newMeshContainer->exBoneOffsets = 0; newMeshContainer->exSkinMesh = 0; newMeshContainer->exFrameCombinedMatrixPointer = 0; } // When we got the device we caused an internal reference count to be incremented // So we now need to release it pd3dDevice->Release(); // The mesh may contain a reference to an effect file if (effectInstances) { if (effectInstances->pEffectFilename) MessageBox(NULL, "Effect Instance", "Model Load Error", MB_OK); } // Set the output mesh container pointer to our newly created one *retNewMeshContainer = newMeshContainer; return S_OK; } void Model::DrawMeshContainer(LPD3DXMESHCONTAINER meshContainerBase, LPD3DXFRAME frameBase) { // Cast to our extended frame type D3DXFRAME_EXTENDED *frame = (D3DXFRAME_EXTENDED*)frameBase; // Cast to our extended mesh container D3DXMESHCONTAINER_EXTENDED *meshContainer = (D3DXMESHCONTAINER_EXTENDED*)meshContainerBase; // Loop through all the materials in the mesh rendering each subset for (unsigned int iMaterial = 0; iMaterial < meshContainer->NumMaterials; iMaterial++) { // use the material in our extended data rather than the one in meshContainer->pMaterials[iMaterial].MatD3D pd3dDevice->SetMaterial( &meshContainer->exMaterials[iMaterial] ); pd3dDevice->SetTexture( 0, meshContainer->exTextures[iMaterial] ); // Select the mesh to draw, if there is skin then use the skinned mesh else the normal one LPD3DXMESH pDrawMesh = (meshContainer->pSkinInfo) ? meshContainer->exSkinMesh: meshContainer->MeshData.pMesh; // Finally Call the mesh draw function pDrawMesh->DrawSubset(iMaterial); } }
  10. I'm trying to load an x file with multiple animations. So far the only way I know how is putting them at different frames. Example walking: 1 - 100, running 101 - 200. But how do I specify specific frames to loop through for animations? The X file animation tutorial on this site talks about tracks and setanimation. But I'm using Blender and I don't know how to set it up like that in blender.
  11. I'm making a side scrolling game and I have a problem that when I rotate my character to look left or right he gets rotated along the y axis and displaced instead of rotating him inplace. Is there a way to rotate him inplace? I tried moving him back after I he was rotated any way but that didn't work either. Can someone give a quick sample of how this would work? When I do manage to get to face the right direction in the right place, the axises are changed because of the rotation! Now his moving right and left goes diagnol and out towards the screen. When I load the model it's loaded at an angle that wont work for the game so I have to rotate it twice to get it in the right orientation. How can I rotate objects without changing the overall world axises of x,y,z?
  12. Tiege

    Rotation + Translation

    Ya I pinpointed it. It only works if the x file is animated too haha. I have to add an independent setTransform function if its not animated. Thinking about putting my matrix functions in my model class so each model can keep track of its own position etc. I have to toy more with matrices to make sure if I have 50 models up at once each keeping track of their own position I can link them all together
  13. When load an animated x file is there a function or method to select specific frames to shuffle through animations? For example if I have 0-100 walking and 101-200 running how do I select the ranges when I want. I know with x files you can use animation sets. But How do you assign animations to sets in the model editor? Im using Blender. I also heard its easier to do it the first way I mentioned but is that done in Blender or in my program with directx?
  14. Tiege

    Rotation + Translation

    I took about a week break since I got a new full time job and was never in the mood to think about this. But today I finally got it figured out and I want to thank all of you who put up with me and my non sensible help. Especially Yogurt and Whitewizard. Anyway I figured out my matrices were automatically being updated somewhere else in the animation code so I was basically doing it twice with my SetTransform functions. So the line of code that made what I wanted to work was : D3DXMatrixMultiply(&matWorld, &(matRotX * matRotY), &matTrans); since it just multiplies the matrices without updating them so they get updated later ( i have no idea where haha). This is exactly what I needed and thanks for all your helpful info and guidance!
  15. Tiege

    Rotation + Translation

    UPDATE: So after some tinkering I think I REALLY found the source of my problem. I noticed that my translation still applied without having any setTransform functions... My character is animated and I used the guide of this website to get it to work. I have an UpdateFrameMatrices() function my my model class which already uses matrices so I'm guessing this is where it is conflicting with what I want to apply to my object. Thank you guys for all your help so far I know I'm super annoying because I have no idea what's going on. Now I need to figure out how to apply transformations to the .x file animation tutorial code that is given on this website. If you can find where or even if they give me room to make me move and edit my object how I want let me know, I can't seem to find it. Source.cpp: #include "model.h" char* filename = "BarbA2.x"; //globals LPDIRECT3D9 d3dObject=NULL; LPDIRECT3DDEVICE9 d3dDevice; LPDIRECTINPUT8 din; // the pointer to our DirectInput interface LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device BYTE keystate[256]; // the storage for the key-information D3DXMATRIX matWorld; D3DXMATRIX resRotX; D3DXMATRIX resRotY; Model* pModel = NULL; Model* pModel2 = NULL; static float vector = 0; static bool jump = false; static float indexx = 0.0f; static float indexy = 0.0f; bool right = true; void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput void detect_input(void); // gets the current input state void cleanDInput(void); // closes DirectInput and releases memory void Render(); HRESULT InitD3D( HWND hWnd ) { //create D3D Object if( NULL == ( d3dObject=Direct3DCreate9(D3D_SDK_VERSION) ) ) return E_FAIL; //setup structure for parameters for D3D Device D3DPRESENT_PARAMETERS presParams; ZeroMemory(&presParams,sizeof(presParams)); presParams.Windowed=TRUE; presParams.SwapEffect=D3DSWAPEFFECT_DISCARD; presParams.BackBufferFormat=D3DFMT_UNKNOWN; presParams.PresentationInterval=D3DPRESENT_INTERVAL_ONE; //create D3D Device if( FAILED (d3dObject->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &d3dDevice) ) ) { return E_FAIL; } // Turn on ambient lighting d3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); return S_OK; } VOID SetupMatrices() { // Set up world matrix //Set Model Orientation // Set view matrix D3DXVECTOR3 vEyePt( 0.0f, 0.0f, 50.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); d3dDevice->SetTransform( D3DTS_VIEW, &matView ); // Set Projection Matrix D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 500.0f ); d3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } void checkInput() { if(keystate[DIK_LEFT] & 0x80) { indexx -= 0.5f; right = false; } if(keystate[DIK_RIGHT] & 0x80) { indexx += 0.5f; right = true; } if(keystate[DIK_UP] & 0x80) { if ( jump == false) { jump = true; vector = 2; } } return; } void Advance() { static float orientation = 0; static DWORD lastTime=timeGetTime(); float timeElapsed=0.001f*(timeGetTime()-lastTime); lastTime=timeGetTime(); //gravity indexy-=vector; if (indexy < 0) vector-=0.25; if (indexy > 0) { jump = false; vector=0; } if(keystate[DIK_R] & 0x80) orientation = 3.14159; if(keystate[DIK_L] & 0x80) orientation = 0; //pModel->SetOrientation(&matRot, right, indexx, indexy); //pModel->SetPosition(&matWorld,0,indexx,indexy); pModel->FrameMove(timeElapsed,&matWorld); return; } void Render() { D3DXMATRIX matTrans; D3DXMATRIX matRotX; D3DXMATRIX matRotY; //clear buffer d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,50,100),1.0f,0); //begin scene d3dDevice->BeginScene(); Advance(); checkInput(); //Fix orientation of character (only needed once) D3DXMatrixRotationX( &matRotX, D3DXToRadian(90.0f) ); D3DXMatrixRotationY( &matWorld, D3DXToRadian(90.0f) ); // Move character left or right D3DXMatrixTranslation(&matWorld, indexx, indexy, 0); //Transform character world //d3dDevice->SetTransform( D3DTS_WORLD, &(matRotX * matRotY) ); //d3dDevice->SetTransform( D3DTS_WORLD, &(matTrans) ); //Render Model pModel->DrawFrame(pModel->GetFrameRoot()); //end scene d3dDevice->EndScene(); //present screen d3dDevice->Present( NULL, NULL, NULL, NULL ); } void initDInput(HINSTANCE hInstance, HWND hWnd) { // create the DirectInput interface DirectInput8Create(hInstance, // the handle to the application DIRECTINPUT_VERSION, // the compatible version IID_IDirectInput8, // the DirectInput interface version (void**)&din, // the pointer to the interface NULL); // COM stuff, so we'll set it to NULL // create the keyboard device din->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used &dinkeyboard, // the pointer to the device interface NULL); // COM stuff, so we'll set it to NULL // set the data format to keyboard format dinkeyboard->SetDataFormat(&c_dfDIKeyboard); // set the control we will have over the keyboard dinkeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); } // this is the function that gets the latest input data void detect_input(void) { // get access if we don't have it already dinkeyboard->Acquire(); // get the input data dinkeyboard->GetDeviceState(256, (LPVOID)keystate); } // this is the function that closes DirectInput void cleanDInput(void) { dinkeyboard->Unacquire(); // make sure the keyboard is unacquired din->Release(); // close DirectInput before exiting } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { //case WM_COMMAND: // handle menu selections etc. //break; //case WM_PAINT: // draw our window - note: you must paint something here or not trap it! //break; case WM_DESTROY: PostQuitMessage(0); break; default: // We do not want to handle this message so pass back to Windows // to handle it in a default way return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style= CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc= (WNDPROC)WndProc; wcex.cbClsExtra= 0; wcex.cbWndExtra= 0; wcex.hInstance= hInstance; wcex.hIcon= 0; wcex.hCursor= LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName= 0; wcex.lpszClassName= "MyWindowClass"; wcex.hIconSm= 0; // Now we can go ahead and register our new window class RegisterClassEx(&wcex); HWND hWnd = CreateWindow("MyWindowClass", "Poop", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); //call initD3D InitD3D(hWnd); initDInput(hInstance, hWnd); // initialize DirectInput //Make model pModel = new Model(d3dDevice); //Load the new pModel->Load(filename); SetupMatrices(); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); //enter main loop MSG msg; while (PeekMessage(&msg, NULL, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); detect_input(); Render(); } cleanDInput(); return (int)msg.wParam; } model.cpp (my model class) #include "model.h" Model::Model(LPDIRECT3DDEVICE9 pD3DDevice) { pd3dDevice = pD3DDevice; pFrameRoot = NULL; boneMatrices = NULL; currentAnimationSet = -1; numAnimationSets = 0; maxBones = 0; pAnimController = NULL; } Model::~Model() { //Delete Animation Controller if (pAnimController) pAnimController->Release(); //if there is a frame hierarchyo if(pFrameRoot) { //Allocation class CMeshHierarchy Alloc; D3DXFrameDestroy(pFrameRoot, &Alloc); pFrameRoot = NULL; } //Delete the bones if (boneMatrices) delete [] boneMatrices; //Make the Device not point to the other device pd3dDevice = NULL; } void Model::Load(char* filename) { CMeshHierarchy Alloc; if(FAILED(D3DXLoadMeshHierarchyFromX( filename, D3DXMESH_MANAGED, pd3dDevice, &Alloc, NULL, &pFrameRoot, &pAnimController ))) { MessageBox(NULL, filename, "Model Load Error", MB_OK); } //Set Breakpoint to check value of pFrameRoot if (pFrameRoot) { SetupBoneMatrices((D3DXFRAME_EXTENDED*)pFrameRoot); if(pAnimController) numAnimationSets = pAnimController->GetMaxNumAnimationSets(); // Create the bone matrices array for use during FrameMove to hold the final transform boneMatrices = new D3DXMATRIX[maxBones]; ZeroMemory(boneMatrices, sizeof(D3DXMATRIX)*maxBones); } } void Model::FrameMove(float elapsedTime,const D3DXMATRIX *matWorld) { float speed = 30; elapsedTime/=speed; // Advance the time and set in the controller if (pAnimController != NULL) pAnimController->AdvanceTime(elapsedTime, NULL); currentTime+=elapsedTime; // Now update the model matrices in the hierarchy UpdateFrameMatrices(pFrameRoot, matWorld); // If the model contains a skinned mesh update the vertices UpdateSkinnedMesh(pFrameRoot); } void Model::UpdateSkinnedMesh(const D3DXFRAME *frameBase) { D3DXFRAME_EXTENDED *currentFrame = (D3DXFRAME_EXTENDED*)frameBase; D3DXMESHCONTAINER_EXTENDED* pMesh = (D3DXMESHCONTAINER_EXTENDED*)currentFrame->pMeshContainer; while(pMesh && pMesh->pSkinInfo) // handle chained skinned mesh added 24/08/10 { unsigned int Bones = pMesh->pSkinInfo->GetNumBones(); // Create the bone matrices that transform each bone from bone space into character space // (via exFrameCombinedMatrixPointer) and also wraps the mesh around the bones using the bone offsets // in exBoneOffsetsArray for (unsigned int i = 0; i < Bones; ++i) { // Note: during set up exFrameCombinedMatrixPointer is made to point to the correct frame matrix (exCombinedTransformationMatrix) // So it does not directly get updated but uses the existing frame calculated value from the correct 'controller' frame D3DXMatrixMultiply(&boneMatrices,&pMesh->exBoneOffsets, pMesh->exFrameCombinedMatrixPointer); } // We need to modify the vertex positions based on the new bone matrices. This is achieved // by locking the vertex buffers and then calling UpdateSkinnedMesh. UpdateSkinnedMesh takes the // original vertex data (in pMesh->MeshData.pMesh), applies the matrices and writes the new vertices // out to skin mesh (pMesh->exSkinMesh). // UpdateSkinnedMesh uses software skinning which is the slowest way of carrying out skinning // but is easiest to describe and works on the majority of graphic devices. // Other methods exist that use hardware to do this skinning - see the notes and the // DirectX SDK skinned mesh sample for more details void *srcPtr=0; pMesh->MeshData.pMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&srcPtr); void *destPtr=0; pMesh->exSkinMesh->LockVertexBuffer(0, (void**)&destPtr); // Update the skinned mesh pMesh->pSkinInfo->UpdateSkinnedMesh(boneMatrices, NULL, srcPtr, destPtr); // Note: bounds may have changed due to skinning! Need to recalc D3DXVECTOR3 min,max; D3DXComputeBoundingBox((D3DXVECTOR3*)destPtr,pMesh->exSkinMesh->GetNumVertices(), D3DXGetFVFVertexSize(pMesh->exSkinMesh->GetFVF()),&min,&max); // Unlock the meshes vertex buffers pMesh->exSkinMesh->UnlockVertexBuffer(); pMesh->MeshData.pMesh->UnlockVertexBuffer(); // If we have more than one mesh pMesh=(D3DXMESHCONTAINER_EXTENDED*)pMesh->pNextMeshContainer; } // If we have a sibling recurse if (currentFrame->pFrameSibling != NULL) UpdateSkinnedMesh(currentFrame->pFrameSibling); // If we have a child recurse if (currentFrame->pFrameFirstChild != NULL) UpdateSkinnedMesh(currentFrame->pFrameFirstChild); } void Model::UpdateFrameMatrices(const D3DXFRAME *frameBase, const D3DXMATRIX *parentMatrix) { D3DXFRAME_EXTENDED *currentFrame = (D3DXFRAME_EXTENDED*)frameBase; // If parent matrix exists multiply our frame matrix by it if (parentMatrix != NULL) D3DXMatrixMultiply(&currentFrame->exCombinedTransformationMatrix, &currentFrame->TransformationMatrix, parentMatrix); else currentFrame->exCombinedTransformationMatrix = currentFrame->TransformationMatrix; // If we have a sibling recurse if (currentFrame->pFrameSibling != NULL) UpdateFrameMatrices(currentFrame->pFrameSibling, parentMatrix); // If we have a child recurse if (currentFrame->pFrameFirstChild != NULL) UpdateFrameMatrices(currentFrame->pFrameFirstChild, &currentFrame->exCombinedTransformationMatrix); } void Model::SetupBoneMatrices(D3DXFRAME_EXTENDED *pFrame) { // Cast to our extended structure first D3DXMESHCONTAINER_EXTENDED* pMesh = (D3DXMESHCONTAINER_EXTENDED*)pFrame->pMeshContainer; // If this frame has a mesh and there is skin info, then setup the bone matrices // Note: handles multiple mesh (// Added 24/08/10 while(pMesh && pMesh->pSkinInfo) { // Create a copy of the mesh to skin into later D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]; if (FAILED(pMesh->MeshData.pMesh->GetDeclaration(Declaration))) return; pMesh->MeshData.pMesh->CloneMesh(D3DXMESH_MANAGED, Declaration, pd3dDevice, &pMesh->exSkinMesh); // Max bones is calculated for later use (to know how big to make the temp bone matrices array) maxBones=max(maxBones,(UINT)pMesh->pSkinInfo->GetNumBones()); // For each bone work out its matrix for (unsigned int i = 0; i < pMesh->pSkinInfo->GetNumBones(); i++) { // Find the frame containing the bone // Must do this from root as skinned mesh and bone frame are not together D3DXFRAME_EXTENDED* pTempFrame = (D3DXFRAME_EXTENDED*)D3DXFrameFind(pFrameRoot, pMesh->pSkinInfo->GetBoneName(i)); // set the bone part - Note just point it at the transformation matrix of the relevant frame (aliase) pMesh->exFrameCombinedMatrixPointer = &pTempFrame->exCombinedTransformationMatrix; } pMesh=(D3DXMESHCONTAINER_EXTENDED*)pMesh->pNextMeshContainer; } // Pass on to sibblings if(pFrame->pFrameSibling) SetupBoneMatrices((D3DXFRAME_EXTENDED*)pFrame->pFrameSibling); // Pass on to children if(pFrame->pFrameFirstChild) SetupBoneMatrices((D3DXFRAME_EXTENDED*)pFrame->pFrameFirstChild); } void Model::DrawFrame(LPD3DXFRAME frame) { // Draw all mesh containers in this frame LPD3DXMESHCONTAINER meshContainer = frame->pMeshContainer; while (meshContainer) { DrawMeshContainer(meshContainer, frame); meshContainer = meshContainer->pNextMeshContainer; } // Recurse for sibblings if (frame->pFrameSibling != NULL) DrawFrame(frame->pFrameSibling); // Recurse for children if (frame->pFrameFirstChild != NULL) DrawFrame(frame->pFrameFirstChild); } void Model::DrawMeshContainer(LPD3DXMESHCONTAINER meshContainerBase, LPD3DXFRAME frameBase) { // Cast to our extended frame type D3DXFRAME_EXTENDED *frame = (D3DXFRAME_EXTENDED*)frameBase; // Cast to our extended mesh container D3DXMESHCONTAINER_EXTENDED *meshContainer = (D3DXMESHCONTAINER_EXTENDED*)meshContainerBase; // Loop through all the materials in the mesh rendering each subset for (unsigned int iMaterial = 0; iMaterial < meshContainer->NumMaterials; iMaterial++) { // use the material in our extended data rather than the one in meshContainer->pMaterials[iMaterial].MatD3D pd3dDevice->SetMaterial( &meshContainer->exMaterials[iMaterial] ); pd3dDevice->SetTexture( 0, meshContainer->exTextures[iMaterial] ); // Select the mesh to draw, if there is skin then use the skinned mesh else the normal one LPD3DXMESH pDrawMesh = (meshContainer->pSkinInfo) ? meshContainer->exSkinMesh: meshContainer->MeshData.pMesh; // Finally Call the mesh draw function pDrawMesh->DrawSubset(iMaterial); } } allocatehierarchy.cpp: #include "allocatehierarchy.h" HRESULT CMeshHierarchy::CreateFrame(LPCSTR Name, LPD3DXFRAME *retNewFrame) { // Always a good idea to initialise a return pointer before proceeding *retNewFrame = 0; // Create a new frame using the derived version of the structure D3DXFRAME_EXTENDED *newFrame = new D3DXFRAME_EXTENDED; ZeroMemory(newFrame,sizeof(D3DXFRAME_EXTENDED)); // Now fill in the data members in the frame structure // Now initialize other data members of the frame to defaults D3DXMatrixIdentity(&newFrame->TransformationMatrix); D3DXMatrixIdentity(&newFrame->exCombinedTransformationMatrix); newFrame->pMeshContainer = 0; newFrame->pFrameSibling = 0; newFrame->pFrameFirstChild = 0; // Assign the return pointer to our newly created frame *retNewFrame = newFrame; // The frame name (note: may be 0 or zero length) if (Name != NULL) { newFrame->Name = new char[strlen(Name) + 1]; strcpy(newFrame->Name, Name); } return S_OK; } /** * \brief callback called when a mesh data is encountered during the .x file load * \param Name - name of the Mesh (const char*) * \param meshData - the mesh data * \param materials - material array * \param effectInstances - effect files / settings for the mesh * \param numMaterials - number of materials in the mesh * \param adjacency - adjacency array * \param pSkinInfo - skin info. * \param retNewMeshContainer - output pointer to assign our newly created mesh container * \return success code * \author Keith Ditchburn \date 17 July 2005 */ HRESULT CMeshHierarchy::CreateMeshContainer( LPCSTR Name, CONST D3DXMESHDATA *meshData, CONST D3DXMATERIAL *materials, CONST D3DXEFFECTINSTANCE *effectInstances, DWORD numMaterials, CONST DWORD *adjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER* retNewMeshContainer) { // Create a mesh container structure to fill and initilaise to zero values // Note: I use my extended version of the structure (D3DXMESHCONTAINER_EXTENDED) defined in MeshStructures.h D3DXMESHCONTAINER_EXTENDED *newMeshContainer=new D3DXMESHCONTAINER_EXTENDED; ZeroMemory(newMeshContainer, sizeof(D3DXMESHCONTAINER_EXTENDED)); // Always a good idea to initialise return pointer before proceeding *retNewMeshContainer = 0; // The mesh name (may be 0) needs copying over if (Name != NULL) { newMeshContainer->Name = new char[strlen(Name) + 1]; strcpy(newMeshContainer->Name, Name); } // The mesh type (D3DXMESHTYPE_MESH, D3DXMESHTYPE_PMESH or D3DXMESHTYPE_PATCHMESH) if (meshData->Type!=D3DXMESHTYPE_MESH) { // This demo does not handle mesh types other than the standard // Other types are D3DXMESHTYPE_PMESH (progressive mesh) and D3DXMESHTYPE_PATCHMESH (patch mesh) DestroyMeshContainer(newMeshContainer); return E_FAIL; } newMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; // Adjacency data - holds information about triangle adjacency, required by the ID3DMESH object DWORD dwFaces = meshData->pMesh->GetNumFaces(); newMeshContainer->pAdjacency = new DWORD[dwFaces*3]; if (adjacency) { memcpy(newMeshContainer->pAdjacency, adjacency, sizeof(DWORD) * dwFaces*3); } else { // Added 24/08/10: previously did not detect null adjacency if(FAILED( newMeshContainer->MeshData.pMesh->GenerateAdjacency( 1e-6f, (DWORD*)(void*)newMeshContainer->pAdjacency ) ) ) FillMemory((void*)newMeshContainer->pAdjacency, dwFaces*3, 0xFF ); } // Get the Direct3D device, luckily this is held in the mesh itself (Note: must release it when done with it) LPDIRECT3DDEVICE9 pd3dDevice = 0; meshData->pMesh->GetDevice(&pd3dDevice); // Changed 24/09/07 - can just assign pointer and add a ref rather than need to clone newMeshContainer->MeshData.pMesh=meshData->pMesh; newMeshContainer->MeshData.pMesh->AddRef(); // Create material and texture arrays. Note that I always want to have at least one newMeshContainer->NumMaterials = max(numMaterials,1); newMeshContainer->exMaterials = new D3DMATERIAL9[newMeshContainer->NumMaterials]; newMeshContainer->exTextures = new LPDIRECT3DTEXTURE9[newMeshContainer->NumMaterials]; ZeroMemory(newMeshContainer->exTextures, sizeof(LPDIRECT3DTEXTURE9) * newMeshContainer->NumMaterials); if (numMaterials>0) { // Load all the textures and copy the materials over for(DWORD i = 0; i < numMaterials; ++i) { newMeshContainer->exTextures = 0; newMeshContainer->exMaterials=materials.MatD3D; if(materials.pTextureFilename) { D3DXCreateTextureFromFile(pd3dDevice, materials.pTextureFilename, &newMeshContainer->exTextures); } } } else // make a default material in the case where the mesh did not provide one { ZeroMemory(&newMeshContainer->exMaterials[0], sizeof( D3DMATERIAL9 ) ); newMeshContainer->exMaterials[0].Diffuse.r = 0.5f; newMeshContainer->exMaterials[0].Diffuse.g = 0.5f; newMeshContainer->exMaterials[0].Diffuse.b = 0.5f; newMeshContainer->exMaterials[0].Specular = newMeshContainer->exMaterials[0].Diffuse; newMeshContainer->exTextures[0]=0; } // If there is skin data associated with the mesh copy it over if (pSkinInfo) { // save off the SkinInfo newMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); // Need an array of offset matrices to move the vertices from the figure space to the bone's space UINT numBones = pSkinInfo->GetNumBones(); newMeshContainer->exBoneOffsets = new D3DXMATRIX[numBones]; // Create the arrays for the bones and the frame matrices newMeshContainer->exFrameCombinedMatrixPointer = new D3DXMATRIX*[numBones]; // get each of the bone offset matrices so that we don't need to get them later for (UINT i = 0; i < numBones; i++) newMeshContainer->exBoneOffsets = *(newMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i)); // Note: in the Microsoft samples a GenerateSkinnedMesh function is called here in order to prepare // the skinned mesh data for optimial hardware acceleration. As mentioned in the notes this sample // does not do hardware skinning but instead uses software skinning. } else { // No skin info so 0 all the pointers newMeshContainer->pSkinInfo = 0; newMeshContainer->exBoneOffsets = 0; newMeshContainer->exSkinMesh = 0; newMeshContainer->exFrameCombinedMatrixPointer = 0; } // When we got the device we caused an internal reference count to be incremented // So we now need to release it pd3dDevice->Release(); // The mesh may contain a reference to an effect file if (effectInstances) { if (effectInstances->pEffectFilename) MessageBox(NULL, "Effect Instance", "Model Load Error", MB_OK); } // Set the output mesh container pointer to our newly created one *retNewMeshContainer = newMeshContainer; return S_OK; } /** * \brief callback called to deallocate the frame data * \param the frame to free * \return success result * \author Keith Ditchburn \date 17 July 2005 */ HRESULT CMeshHierarchy::DestroyFrame(LPD3DXFRAME frameToFree) { // Convert to our extended type. OK to do this as we know for sure it is: D3DXFRAME_EXTENDED *frame = (D3DXFRAME_EXTENDED*)frameToFree; delete []frame->Name; delete frame; return S_OK; } /** * \brief callback called to deallocate the mesh container data * \param the mesh data to free * \return success result * \author Keith Ditchburn \date 17 July 2005 */ HRESULT CMeshHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER meshContainerBase) { // Convert to our extended type. OK as we know for sure it is: D3DXMESHCONTAINER_EXTENDED* meshContainer = (D3DXMESHCONTAINER_EXTENDED*)meshContainerBase; if (!meshContainer) return S_OK; // name delete []meshContainer->Name; meshContainer->Name=0; // material array delete []meshContainer->exMaterials; meshContainer->exMaterials=0; // release the textures before deleting the array if(meshContainer->exTextures) { for(UINT i = 0; i < meshContainer->NumMaterials; ++i) { if (meshContainer->exTextures) meshContainer->exTextures->Release(); } } // texture array delete []meshContainer->exTextures; // adjacency data delete []meshContainer->pAdjacency; // bone parts delete []meshContainer->exBoneOffsets; // frame matrices delete []meshContainer->exFrameCombinedMatrixPointer; // release skin mesh if (meshContainer->exSkinMesh) meshContainer->exSkinMesh->Release(); // release the main mesh if (meshContainer->MeshData.pMesh) meshContainer->MeshData.pMesh->Release(); // release skin information if (meshContainer->pSkinInfo) meshContainer->pSkinInfo->Release(); // finally delete the mesh container itself delete meshContainer; meshContainer=0; return S_OK; }
  16. Tiege

    Rotation + Translation

    I think I'm starting to understand a little more about matrices. How that a matrix can be used to edit everything about an object before it renders it to world space. So obviously if I rotate the object around an axis and continue to edit that object in the SAME matrix space further the edits will be effected by that axis which was rotated. So I guess to fix this I'm wondering is there a way to edit the same object with two independent and separate matrices. Howver this method doesn't work... //Fix orientation of character (only needed once) D3DXMatrixRotationX( &matRotX, D3DXToRadian(90.0f) ); D3DXMatrixRotationY( &matRotY, D3DXToRadian(90.0f) ); // Move character left or right D3DXMatrixTranslation(&matTrans, indexx, indexy, 0); //Transform character world d3dDevice->SetTransform( D3DTS_WORLD, &(matRotX * matRotY) ); d3dDevice->SetTransform( D3DTS_WORLD, &(matTrans) ); Here I am trying to modify my world by two independent matrices to get my model to rotate, and then translate along default axises and not the ones changed after the rotation. I don't even see my character displayed when I try this Howver if I try d3dDevice->SetTransform( D3DTS_WORLD, &(matRotX * matRotY * matTrans) ); My character moves along changed axises making his movement all wrong. A lot of people mention something about a Matrix Identity. I've tried looking it up but no tutorial explains it well or how to apply it in this case. Can someone explain how I would go about doing this? I drew a simple diagram of what is happening as a result of the above code (all the matrices multipled together) and what my desired result is that im trying to get working: Notice how in the actual the translation is affected by the rotation. I need them to be independent of one another.
  17. Tiege

    Rotation + Translation

    Well, it is a way of thinking what happens when the transformation pipeline is processed. As such the authors of any 3D program need to apply it in the one or other way, at least if they don't program by trial. It is in particular useful for * understanding the terminology, * composing parent-child transformations (and hence doing forward kinematics), * understanding the commons and differences of world-objects and cameras, * composing Euler rotations to yield in a single rotation matrix, * rotating around arbitrary origins, * rotating around arbitrary axes (e.g. the local axes), * scaling along arbitrary axes, * using incremental rotations, * knowing where to incorporate LHS/RHS conversion, * understanding why moving the world is mathematically the same as (inversely) moving the camera, * and so on ... That are all practical purposes, aren't they? [/quote] Indeed but I just want to get this one thing working so I can move on with my game
  18. Tiege

    Rotation + Translation

    Stumped before I even start... haha So I don't get the identity part. How do I make an identity for what I want? I'm stumped how I move my character without using the already rotated matrix of matWorld. Here's a rather pathetic attempt to apply Wizard's psuedocode: void Render() { D3DXMATRIX matID; D3DXMATRIXA16 matWorld; D3DXMATRIX matRotX; D3DXMATRIX matRotY; //clear buffer d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,50,100),1.0f,0); //begin scene d3dDevice->BeginScene(); Advance(); checkInput(); //Matrix Identity D3DXMatrixIdentity(&matID); //Fix orientation of character (only needed once) D3DXMatrixRotationX( &matRotX, D3DXToRadian(90.0f) ); D3DXMatrixRotationY( &matRotY, D3DXToRadian(90.0f) ); // Move character left or right D3DXMatrixTranslation(&matWorld, indexx, indexy, 0); //Transform character world d3dDevice->SetTransform( D3DTS_WORLD, &(matWorld * matRotX * matRotY) ); //Render Model pModel->DrawFrame(pModel->GetFrameRoot()); //Reset to Identity d3dDevice->SetTransform( D3DTS_WORLD, &(matID) ); //end scene d3dDevice->EndScene(); //present screen d3dDevice->Present( NULL, NULL, NULL, NULL ); }
  19. Tiege

    Rotation + Translation

    Thanks for all the replies trying to help me out! I'm trying to piece through them now to see if I can pull out an answer. Yogurt sorry for being unclear about those rotations around x and y. If you recall in some of my previous posts when I load and render my mesh for the very first time, he is facing downward along the negative Y axis. This is where the x and y rotation of 90 degrees comes in to play to turn him upright, then turn him into facing the correct direction. This is only being applied once in my program to set him straight before the game actual runs. Afterwards yes the only rotation I will require will be along the Y along to flip him left and right (think about mario). Those rotations have been moved all over the place already trying to fix this. I have had them applying during every frame and not just once but the result is the same in all aspects. The other guys are right in that I have no idea how to use world matrices properly . Wizard right now the variables are global for testing purposes. If I can actually get them to work I do intend to organize them much for efficiently. They're also global because I am passing and modifying them through several functions such as FrameMove(). Right now I don't have terrain but just a blank screen with a blue background to display my character. In my render function above I assume the screen is rendered at the very end. Haegarr your post is very philosphical and very informative I hope I can apply it to my program Now i'm going to try out Wizard's psuedocode, I'm sure I'll be back in 5 minutes because I have no idea what I'm doing [color=#1C2837][size=2][color=#000000]D3DXMatrixIdentity[color=#666600](&[color=#000000]matWorld[color=#666600]); [color=#666600]works for the initalize identity right?
  20. Tiege

    Rotation + Translation

    In the code in the Setupmatrices function (which is ran once before everything is drawn) I have the lines: [color="#880000"]//Set Model Orientation[color="#000000"] D3DXMatrixRotationX[color="#666600"]( [color="#666600"]&[color="#000000"]matRotX[color="#666600"],[color="#000000"] D3DXToRadian[color="#666600"]([color="#006666"]90.0f[color="#666600"]) [color="#666600"]);[color="#000000"] D3DXMatrixRotationY[color="#666600"]( [color="#666600"]&[color="#000000"]matRotY[color="#666600"],[color="#000000"] D3DXToRadian[color="#666600"]([color="#006666"]90.0f[color="#666600"]) [color="#666600"]);[color="#000000"] d3dDevice[color="#666600"]->[color="#660066"]SetTransform[color="#666600"]([color="#000000"] D3DTS_WORLD[color="#666600"], [color="#666600"]&([color="#000000"]matRotX [color="#666600"]*[color="#000000"] matRotY[color="#666600"]) [color="#666600"]); [color="#666600"]This makes the mesh I load standing upright and facing right. [color="#666600"]Then in the advance function I have: D3DXMatrixTranslation[color="#666600"][color=#1C2837](&[color="#000000"][color=#1C2837]matWorld[color="#666600"][color=#1C2837],[color="#000000"][color=#1C2837] indexx[color="#666600"][color=#1C2837],[color="#000000"][color=#1C2837] indexy[color="#666600"][color=#1C2837],[color="#000000"][color=#1C2837] [color="#006666"][color=#1C2837]0[color="#666600"][color=#1C2837]);[color="#666600"][color=#1C2837] [color="#666600"][color=#1C2837] [color="#666600"][color=#1C2837]This moves the character left or right when I hit the left or right arrow keys.[color="#666600"][color=#1C2837] [color="#666600"][color=#1C2837] [color="#666600"][color=#1C2837]HOWEVER, the character moves in and out of the screen instead of left or right. But this only happens when I rotate him to make him face right. If I remove those rotations the left and right work but then my character is upside down facing into outer space. I'm just trying to fix this. It looks like when I rotate the mesh the world axises get rotated aswell which would result in my problem.
  21. Tiege

    Rotation + Translation

    It's only the main character now for testing. Obviously I plan to add more later but I can't even get it to work for one object? I just don't get how to rotate objects without messing up the world itself. Because it doesn't rotate the object itself, it rotates the world around it to make it look like the object is rotated.
  22. Tiege

    Animation Sets in Blender

    In blender you can manage different animations in actions. On the other hand, when you like to keep it easy, you could assign different animations to certain frame ranges,i.e. 1-100 walking, 101-200 running etc. [/quote] Then how would I specify which frames to use in my program? On the x file animation tutorial on this site it talks about selecting tracks. My friend can assign different animations to different frames but I don't know how I would shuffle through specific ones for specific actions
  23. Tiege

    Animation Sets in Blender

    Hope this is the right forum for this. So my friend is making models for me with Blender for a game. Simple question. How do you give a mesh multiple animation sets in Blender? I'm using directx so the file with be exported as a .x file The tutorials for animation with .x file mention animation sets so I'm sure it can be done. The question is... how?
  24. Tiege

    Rotation + Translation

    I'm guessing I'm just having a hard time wrapping my head around the method to do this. What I want is: My model loads and flips to the correct orientation. I can the move it left and right via translation along the x axis. I don't know how to change the world to flip him just ONCE and then reset it to normal because it's in a loop. I can't say: orient -> draw model -> reset world because then the model gets redrawn in the reset world matrix because of the render loop the next run will do reset world -> draw model ->reset world -> draw model Here's my program: #include "model.h" char* filename = "BarbA2.x"; //globals LPDIRECT3D9 d3dObject=NULL; LPDIRECT3DDEVICE9 d3dDevice; LPDIRECTINPUT8 din; // the pointer to our DirectInput interface LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device BYTE keystate[256]; // the storage for the key-information D3DXMATRIXA16 matWorld; D3DXMATRIX matRotX; D3DXMATRIX matRotY; D3DXMATRIX resRotX; D3DXMATRIX resRotY; D3DXMATRIX matID; Model* pModel = NULL; Model* pModel2 = NULL; static float vector = 0; static bool jump = false; static float indexx = 0.0f; static float indexy = 0.0f; bool right = true; void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput void detect_input(void); // gets the current input state void cleanDInput(void); // closes DirectInput and releases memory void Render(); HRESULT InitD3D( HWND hWnd ) { //create D3D Object if( NULL == ( d3dObject=Direct3DCreate9(D3D_SDK_VERSION) ) ) return E_FAIL; //setup structure for parameters for D3D Device D3DPRESENT_PARAMETERS presParams; ZeroMemory(&presParams,sizeof(presParams)); presParams.Windowed=TRUE; presParams.SwapEffect=D3DSWAPEFFECT_DISCARD; presParams.BackBufferFormat=D3DFMT_UNKNOWN; presParams.PresentationInterval=D3DPRESENT_INTERVAL_ONE; //create D3D Device if( FAILED (d3dObject->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &d3dDevice) ) ) { return E_FAIL; } // Turn on ambient lighting d3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); return S_OK; } VOID SetupMatrices() { // Set up world matrix D3DXMatrixIdentity(&matID); //Set Model Orientation D3DXMatrixRotationX( &matRotX, D3DXToRadian(90.0f) ); D3DXMatrixRotationY( &matRotY, D3DXToRadian(90.0f) ); d3dDevice->SetTransform( D3DTS_WORLD, &(matRotX * matRotY) ); // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction. D3DXVECTOR3 vEyePt( 0.0f, 0.0f, 50.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); d3dDevice->SetTransform( D3DTS_VIEW, &matView ); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered). D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 500.0f ); d3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } void checkInput() { if(keystate[DIK_LEFT] & 0x80) { indexx -= 0.5f; right = false; } if(keystate[DIK_RIGHT] & 0x80) { indexx += 0.5f; right = true; } if(keystate[DIK_UP] & 0x80) { if ( jump == false) { jump = true; vector = 2; } } return; } void Advance() { static float orientation = 0; static DWORD lastTime=timeGetTime(); float timeElapsed=0.001f*(timeGetTime()-lastTime); lastTime=timeGetTime(); //gravity indexy-=vector; if (indexy < 0) vector-=0.25; if (indexy > 0) { jump = false; vector=0; } if(keystate[DIK_R] & 0x80) orientation = 3.14159; if(keystate[DIK_L] & 0x80) orientation = 3; //pModel->SetOrientation(&matRot, right, indexx, indexy); //pModel->SetPosition(&matWorld,0,indexx,indexy); D3DXMatrixTranslation(&matWorld, indexx, indexy, 0); // d3dDevice->SetTransform( D3DTS_WORLD, &(matRotX * matRotY * matWorld) ); pModel->FrameMove(timeElapsed,&matWorld); return; } void Render() { //clear buffer d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,50,100),1.0f,0); //begin scene d3dDevice->BeginScene(); Advance(); checkInput(); //Render Model pModel->DrawFrame(pModel->GetFrameRoot()); //Reset World Identity d3dDevice->SetTransform( D3DTS_WORLD, &(matID) ); //end scene d3dDevice->EndScene(); //present screen d3dDevice->Present( NULL, NULL, NULL, NULL ); } void initDInput(HINSTANCE hInstance, HWND hWnd) { // create the DirectInput interface DirectInput8Create(hInstance, // the handle to the application DIRECTINPUT_VERSION, // the compatible version IID_IDirectInput8, // the DirectInput interface version (void**)&din, // the pointer to the interface NULL); // COM stuff, so we'll set it to NULL // create the keyboard device din->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used &dinkeyboard, // the pointer to the device interface NULL); // COM stuff, so we'll set it to NULL // set the data format to keyboard format dinkeyboard->SetDataFormat(&c_dfDIKeyboard); // set the control we will have over the keyboard dinkeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); } // this is the function that gets the latest input data void detect_input(void) { // get access if we don't have it already dinkeyboard->Acquire(); // get the input data dinkeyboard->GetDeviceState(256, (LPVOID)keystate); } // this is the function that closes DirectInput void cleanDInput(void) { dinkeyboard->Unacquire(); // make sure the keyboard is unacquired din->Release(); // close DirectInput before exiting } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { //case WM_COMMAND: // handle menu selections etc. //break; //case WM_PAINT: // draw our window - note: you must paint something here or not trap it! //break; case WM_DESTROY: PostQuitMessage(0); break; default: // We do not want to handle this message so pass back to Windows // to handle it in a default way return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style= CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc= (WNDPROC)WndProc; wcex.cbClsExtra= 0; wcex.cbWndExtra= 0; wcex.hInstance= hInstance; wcex.hIcon= 0; wcex.hCursor= LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName= 0; wcex.lpszClassName= "MyWindowClass"; wcex.hIconSm= 0; // Now we can go ahead and register our new window class RegisterClassEx(&wcex); HWND hWnd = CreateWindow("MyWindowClass", "Poop", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); //call initD3D InitD3D(hWnd); initDInput(hInstance, hWnd); // initialize DirectInput //Make model pModel = new Model(d3dDevice); //Load the new pModel->Load(filename); SetupMatrices(); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); //enter main loop MSG msg; while (PeekMessage(&msg, NULL, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); detect_input(); Render(); } cleanDInput(); return (int)msg.wParam; }
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!