Slyfox

Members
  • Content count

    133
  • Joined

  • Last visited

Community Reputation

157 Neutral

About Slyfox

  • Rank
    Member
  1. Recommended XML Parsers

    Thanks, very much for your suggestions I will explore them all. The reason I intend on using XML for configs is due to the human readability factor and it's something that I have come across quite often with the software I work with, so it's more of a case of developing skills that I need within the work place. Previously I have always written configs as text files and written parsers myself. Lua is on the list of things to learn but that has to wait for now. I've already written many scripts in python so I'm sure Lua won't be too much of a leap. Cheers all!
  2. Hi, I'm faced with the classic conundrum of needing to integrate an XML parser into my C++ applications and as the saying goes "There is no point reinventing the wheel." I was wondering if anyone could recommend any in particular? I've been using TinyXML but have ran into issues iterating between sibling elements. This aside I don't really like the fact that it is not natively unicode and I also found that the documentation was of little use for what I want to do. I'm only really looking to use the parser to load settings from a config.xml file, so I'm not really fussed about it's ability to write out to xml files. The big plus of TinyXML is that it was only 6 files that I needed to include in my projects. I have spent time looking into other parsers but you don't really get a good feel for them until you start using them and I'm trying not to get too sidetracked from the task at hand. Any suggestions are welcome :-) [Edited by - Slyfox on December 20, 2010 1:24:03 PM]
  3. Reducing CPU usage and the message loop

    Thankyou all for your responses, I'm now back from work and am now going to try resolve this issue. @Evil Steve - The application I'm developing is kind of a hyrbid, it's not a game per se but it does need to run in 'real' time. It's my understanding that the function GetMessage() is designed for event driven applications so in this case would not be applicable? Is that correct? My frate rate limiter look like the following: // Make sure the application isn't sleeping if (!Engine::GetEngine()->GetSleep()) { // Check the tick count to see if a frame has elapsed iTickCount = GetTickCount(); if (iTickCount > iTickTrigger) { iTickTrigger = iTickCount + Engine::GetEngine()->GetFrameDelay(); pApplication->RunApplicationFrame(); } } Where GetFrameDelay is equal to 1000 / desired frame rate So as you suggested I am running a busy loop. @Hodgman I've tried adding Sleep(0) in the way you suggested and in various other positions but this doesn't reduce the cpu usage, it only "works" when I pass in a millisecond value such as 1. I'd prefer to pass a zero if at all possible
  4. Reducing CPU usage and the message loop

    Hi, thanks for your reply. Sorry I did forget to mention that I do have frame rate limiting code built into that else clause based on the tickrate. I can confirm that this limiting code is definitely working and the CPU issue still occurs even at a frame rate of 1fps!
  5. Hi I've been working on a windows based project and have been specifically avoiding the use of DirectX as I want this to project to rely purely on the windows API. Last night I got to a point where I decided to see what CPU usage my application was currently using seeing as it is still in a very basic state. To my surprise it was actually using 50% of my core 2 duo CPU. I investigated this problem further and deduced that the problem occurs because of the message loop that I am using because I was able to reproduce this problem by changing the message loop on a freshly created win32 project in visual studio 2010 express edition. Oddly this is the same message loop that appears in all of the books I have on games including both DirectX and windows applications. the loop appears as such... while(msg.message != WM_QUIT) { if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // Do other frame update } } } A friend suggested that adding a sleep(1) into the loop would solve the issue, which it did but I consider this to be a hack. Is there another way around this? Perhaps an improved message loop? Any help would be much appreciated!
  6. Moving and rotating object

    If you are trying to make something move in 2D and you are wanting it to move in the direction that it is facing try researching the topic "Polar Coordinate Systems" this uses cosine and sine to calculate a movement vector that can then be applied to the object that you wish to move.
  7. How to compute frame rate

    I would suggest that your curtime and pretime variables are returning the same values as GetTickCount is not very precise with modern cpus resulting in a devision by zero hence the error. Try setting a breakpoint and stepping through to check the values (f9 - set break point and f10 to step through) this is assuming you are using visual studio. A much better and more precise way to calculate frame rate if you are using DirectX is to use the functions QueryPerformanceCounter() and QueryPerformanceFrequency() you can find out all you need about these functions within the help files of visual studio. edit: oops someone beat me to it :-)
  8. Polymorphism and Copy Constructors

    Problem solved thanks to cloning! Thanks everyone for your help, for anyone following this thread I simply did the following.... Within my Model class header file I added: virtual Model* Clone() const{return new Model(*this);}; Similarly in my AnimatedPlaneModel header file I added: virtual AnimatedPlaneModel* Clone() const{return new AnimatedPlaneModel(*this);}; then all I had to do was in the copy constructor of animal I replaced the line m_pModel = new Model(*rhs.m_pModel); // With this line m_pModel = rhs.m_pModel->Clone(); Now everything has been copied correctly and no data has been lost, thanks again!
  9. Polymorphism and Copy Constructors

    With the original problem I recieved no compile errors and the application ran fine I just noticed that I had lost my varying textures because that data had not been transferred. This happened because my model pointer m_pModel was using polymorphism to point at a AnimatedPlaneModel and the additional data held by the AnimatedPlaneModel was lost when the pointer's data was copied back into another Model pointer. Is this still not slicing? It was only when I was trying to implement the virtual clone function that I was recieving compile time errors. I am now trying again using the link submitted by nobodynews. Cheers! edit: btw the reason I said again was because in the first instance of experiencing the slicing I tried to use the AnimatedPlaneModel copy constructor but it rejected me passing the model pointer into it for obvious reasons. [Edited by - Slyfox on April 23, 2010 6:52:30 AM]
  10. Polymorphism and Copy Constructors

    I kind of understand what you are saying but am still running into the same issue. I tried creating a clone function in model and animatedplane model but when I try to use it, it again complains that it cannot convert parameter 1 from *Model to AnimatedPlaneModel*. Could please try and clarify how you would used the clone function, cheers! Oh btw wikipedia describes my problem as being a result of slicing http://en.wikipedia.org/wiki/Object_slicing
  11. Hi, my problem seems as difficult to explain as it is to solve, but I'll give it a try... I have a class within my code called Model that deals with creating 3D models from .x files. From this I have derived the class AnimatedPlaneModel which allows multiple texture to be loaded for a model and displayed to allow animation at a 2D level. Ok In my main code I have a class called GameEntity from which all games objects are derived. GameEntity contains a pointer to a Model object called m_pModel, which is used in the function to LoadModel load a model. m_pModel = new Model(); From GameEntity I have then derived the class Animal this class overrides the LoadModel function of GameEntity and uses polymorphism to make m_pModel point to an AnimatedPlaneModel instead. m_pModel = new AnimatedPlaneModel(); Hopefully explained that ok, now the problem occurs when I later derive a class from Animal called Spider. I create a spider object without object, but next I want to create an array of spiders and copy the data from that first spider into the elements in the array and this is where the copy constructors come into effect. I have written a copy constructor into Animal that looks like the following // Copy Constructor Animal(const Animal & rhs) { m_fAnimationRate = rhs.m_fAnimationRate; m_fHeadingAngle = rhs.m_fHeadingAngle; m_fSpeed = rhs.m_fSpeed; m_vTargetVector = rhs.m_vTargetVector; m_pModel = new Model(*rhs.m_pModel); // Create a seperate model for the animal // in a new memory location but copy all the // data across } This works as it then calls the copy constructor of the model class and copies all the data, but I have realised that I have lost my animated texture data and all the spiders look the same, so instead I tried replacing the line m_pModel = new Model(*rhs.m_pModel); //with this line m_pModel = new AnimatedPlaneModel(*rhs.m_pModel); I figured this would first call the copy constructor of the AnimatedPlaneModel store the animated texture data and then call the model copy constructor, however visual studio complains that *rhs.m_pModel is of type model not AnimatedPlaneModel despite the fact that it is pointing to an AnimatedPlaneModel and this is where I am stuck. I have tried casting but to no avail. Sorry if this very long winded but I hoped by writing it out it might help me clarify it in my own head. Any help would be much appreciated! Cheers.
  12. Memory Leak Nightmare

    Thankyou so much Erik! All the memory leaks are fixed and everything is destroyed cleanly and without error now :-). Thanks for the advice Scourage but during this application I increase the elements of the vector but the number of element is never reduced so using the vector shouldn't waste any memory. Out of interest if you use .pop_back does that not free up the memory used by the std::vector? Cheers!
  13. Memory Leak Nightmare

    Ah ok that makes sense and as I recall I've come across that before because I use that function on m_d3dxMesh, which I now remember having the same problem with a long time ago. Cheers it has fixed the problem with the LPDIRECT3DTEXTURE9 but now that's repaired a similar problem is occuring with m_vMeshMaterials, I copy the data across in much the same way... for( DWORD i = 0; i < rhs.m_vMeshMaterials.size(); i++ ) { m_vMeshMaterials.push_back( rhs.m_vMeshMaterials[i] ); } Obviously I can't use AddRef() in this situation because it is a D3DMATERIAL9*. I appreciate that because they are pointers they all point to the same memory location so once it's been cleaned up once it can't be done again.
  14. Memory Leak Nightmare

    Hey everyone thanks alot for your help, by changing the vector to store LPDIRECT3DTEXTURE9 objects rather than pointers and then calling release of these objects it has solved the problem of the memory leaks :-) . The Only problem I face now is within the copy constructor of the model class, when I instantiate a model object using another model object I need to copy the data held in m_vMeshTextures across to the new model. I have tried achieving this using the following code: for( DWORD i = 0; i < rhs.m_vMeshTextures.size(); i++ ) { m_vMeshTextures.push_back( rhs.m_vMeshTextures[i] ); } This appears to work and the application runs fine. However when I then exit the application and the destructor is called the application triggers a break point because the second time the destructor is called on an object instantiated from another object the texture file has already been destroyed and when the application tries to release it again it causes it to break. Can anyone suggest as to how the texture could be copied to a new memory location in the copy constructor or alternatively how to prevent release being called multiple times in the destructor? I have already tried if ( !m_vMeshTextures.empty() ) { for( DWORD i = 0; i < m_vMeshTextures.size(); i++ ) { if( m_vMeshTextures[i] != NULL ) m_vMeshTextures[i]->Release(); } m_vMeshTextures.clear(); } which doesn't work because it never returns null.
  15. Memory Leak Nightmare

    The lines that I comment out for it to work is if( FAILED( D3DXCreateTextureFromFileA( m_d3dDevice, d3dxMaterials[i].pTextureFilename, &*m_vMeshTextures[i] ) ) ) { m_vMeshTextures[i] = NULL; } Perhaps if I post all of my Model object it would be easier to understand and can see if I'm failing to clean up properly: Model.h //------------------------------------------------------------------------------------------------------------------- // Include Files //------------------------------------------------------------------------------------------------------------------- #include <d3dx9.h> #include <string> #include <vector> //------------------------------------------------------------------------------------------------------------------- // Name: Class Model // Desc: Used to create .x model objects //------------------------------------------------------------------------------------------------------------------- class Model { protected: LPDIRECT3DDEVICE9 m_d3dDevice; // Model direct 3D device LPD3DXBUFFER m_d3dxMaterialBuffer; // Direct 3D material buffer DWORD m_dwNumberOfMaterials; // Used to store number of materials LPD3DXMESH m_d3dxMesh; // Used to store mesh object std::vector <D3DMATERIAL9*> m_vMeshMaterials; // Materials for the mesh LPDIRECT3DTEXTURE9* m_pMeshTextures; // Texture for the mesh std::vector <LPDIRECT3DTEXTURE9*> m_vMeshTextures; D3DXVECTOR3 m_vPosition; // Position of the mesh in world space D3DXVECTOR3 m_vScale; // Scale of the mesh in world space D3DXVECTOR3 m_vRotation; // Rotation of the mesh in world space float m_fSpeed; // Speed of the mesh in the world; std::string m_strType; // Stores the type of model, for identifying models within // other functions. // Matrices D3DXMATRIXA16 m_matWorld; // World matrix public: // Constructor(s) / Destructor Model(){}; Model(LPDIRECT3DDEVICE9 & Device, std::string strType): m_d3dDevice( Device ), m_fSpeed( 0 ), m_strType( strType) {}; virtual ~Model(); // Copy Constructor Model( const Model & rhs); // General Methods HRESULT CreateModel( std::string FileName, HWND hWnd ); virtual const void Render(); void SetScale( float x, float y, float z ) { m_vScale = D3DXVECTOR3( x, y, z ); }; void SetRotation( float x, float y, float z ) { m_vRotation = D3DXVECTOR3( x, y, z ); }; void SetPosition( float x, float y, float z ) { m_vPosition = D3DXVECTOR3( x, y, z ); }; void SetSpeed( float fSpeed ) { m_fSpeed = fSpeed; }; // Accessor Methods const D3DXVECTOR3 GetScale() { return m_vScale; }; const D3DXVECTOR3 GetRotation() { return m_vRotation; }; const D3DXVECTOR3 GetPosition() { return m_vPosition; }; const float GetSpeed() { return m_fSpeed; }; const std::string GetModelType() { return m_strType; }; }; Model.cp //------------------------------------------------------------------------------------------------------------------- // Name: Model.cpp // Desc: Definition for Model class //------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------- // Include Files //------------------------------------------------------------------------------------------------------------------- #include "Model.h" //------------------------------------------------------------------------------------------------------------------- // Name: ~Model() // Desc: Clean up if model object is destroyed //------------------------------------------------------------------------------------------------------------------- Model::~Model() { if( m_d3dxMesh != NULL ) { m_d3dxMesh->Release(); m_d3dxMesh = NULL; } if ( !m_vMeshTextures.empty() ) { for( int i = 0; i < m_vMeshTextures.size(); i++ ) { delete m_vMeshTextures[i]; } m_vMeshTextures.clear(); } if( !m_vMeshMaterials.empty() ) { for( int i = 0; i < m_vMeshMaterials.size(); i++ ) { delete m_vMeshMaterials[i]; } m_vMeshMaterials.clear(); } } //------------------------------------------------------------------------------------------------------------------- // Name: Model( const Model & ) // Desc: Copy constructors, used to create copies of a model object //------------------------------------------------------------------------------------------------------------------- Model::Model(const Model &rhs) { m_d3dDevice = rhs.m_d3dDevice; m_d3dxMaterialBuffer = rhs.m_d3dxMaterialBuffer; m_dwNumberOfMaterials = rhs.m_dwNumberOfMaterials; m_d3dxMesh = rhs.m_d3dxMesh; m_d3dxMesh->AddRef(); // Increase reference count m_vPosition = rhs.m_vPosition; m_vScale = rhs.m_vScale; m_vRotation = rhs.m_vRotation; m_matWorld = rhs.m_matWorld; // Copy information pointed to into a safe new memory location //m_pMeshMaterial = new D3DMATERIAL9; //m_pMeshTextures = new LPDIRECT3DTEXTURE9[ m_dwNumberOfMaterials ]; //for( DWORD i = 0; i < m_dwNumberOfMaterials; i++ ) //{ // m_pMeshMaterials[i] = rhs.m_pMeshMaterials[i]; // m_pMeshTextures[i] = rhs.m_pMeshTextures[i]; //} } HRESULT Model::CreateModel(std::string FileName, HWND hWnd) { // Add file extension to the filename allowing models to be stored in a seperate folder std::string FileDirectory = "Models/" + FileName; // Load the mesh from the extended file path. if( FAILED ( D3DXLoadMeshFromXA( FileDirectory.c_str(), D3DXMESH_SYSTEMMEM, m_d3dDevice, NULL, &m_d3dxMaterialBuffer, NULL, &m_dwNumberOfMaterials, &m_d3dxMesh ) ) ) { // If the file cannot be found check in the original directory if ( FAILED( D3DXLoadMeshFromXA( FileName.c_str(), D3DXMESH_SYSTEMMEM, m_d3dDevice, NULL, &m_d3dxMaterialBuffer, NULL, &m_dwNumberOfMaterials, &m_d3dxMesh ) ) ) { // Create error message, display message box and exit gracefully. std::string strError = "Could not find " + FileName; MessageBoxA( hWnd, strError.c_str(), "Error!", MB_OK | MB_ICONEXCLAMATION ); return E_FAIL; } } // Get pointer to the material buffer D3DXMATERIAL* d3dxMaterials = ( D3DXMATERIAL* )m_d3dxMaterialBuffer->GetBufferPointer(); // Create new mesh and texture objects based on the total number of materials for the mesh D3DMATERIAL9* m_pMeshMaterial = new D3DMATERIAL9; if ( m_pMeshMaterial == NULL ) return E_OUTOFMEMORY; for( int i = 0; i < m_dwNumberOfMaterials; i++ ) { m_vMeshMaterials.push_back( m_pMeshMaterial ); } LPDIRECT3DTEXTURE9* m_pMeshTexture = new LPDIRECT3DTEXTURE9; if ( m_pMeshTextures == NULL ) return E_OUTOFMEMORY; for( int i = 0; i < m_dwNumberOfMaterials; i++ ) { m_vMeshTextures.push_back( m_pMeshTexture ); } for( DWORD i = 0; i < m_dwNumberOfMaterials; i++ ) { // Copy the material *m_vMeshMaterials[i] = d3dxMaterials[i].MatD3D; // Set the ambient colour for the material (D3DX does not do this) m_vMeshMaterials[i]->Ambient = m_vMeshMaterials[i]->Diffuse; if( d3dxMaterials[i].pTextureFilename != NULL && lstrlenA( d3dxMaterials[i].pTextureFilename ) > 0 ) { // Create the texture if( FAILED( D3DXCreateTextureFromFileA( m_d3dDevice, d3dxMaterials[i].pTextureFilename, &*m_vMeshTextures[i] ) ) ) { m_vMeshTextures[i] = NULL; } } } m_d3dxMaterialBuffer->Release(); m_d3dxMaterialBuffer = NULL; // Set scale, rotation and position m_vScale = D3DXVECTOR3( 1.0f, 1.0f, 1.0f ); m_vRotation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); m_vPosition = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); return S_OK; } //------------------------------------------------------------------------------------------------------------------- // Name: Render() // Desc: Used to render the model //------------------------------------------------------------------------------------------------------------------- const void Model::Render() { // Meshes are divided into subsets, one for each material. Render them in a loop for ( DWORD i = 0; i < m_dwNumberOfMaterials; i++ ) { // Set the material and texture for this subset m_d3dDevice->SetMaterial(& *m_vMeshMaterials[i] ); m_d3dDevice->SetTexture( 0, *m_vMeshTextures[i] ); // Draw the mesh subset m_d3dxMesh->DrawSubset( i ); } }