Endar

Members
  • Content count

    2278
  • Joined

  • Last visited

Community Reputation

668 Good

About Endar

  • Rank
    Contributor
  1. It's probably a better idea if I describe what type of assets I have and how I compile and deal with them.   First of all, when I "compile" an asset, I'm basically converting it into a generic data chunk format, which can set up pointers between different chunks. So, when it is loaded from this generic data chunk format, it is in it's runtime format.   These assets are static and are not intended to change. These assets are basic C structures compiled in C++, but with no member functions or virtual functions. As their first data member, they have an Asset struct so a pointer to the asset can be casted as an Asset and we can do ref counting and other basic things.   There are some bits of data that need transformation, like when loading a model (Asset type is called ModelTemplate), it needs to convert an array of vertices into a Direct X vertex buffer. This is handled specifically by the derived Asset Manager, and creates the DX vertex buffers, and then frees the data chunks that comprise the vertex and index buffers.   So, I have a base Asset Manager which does this generic deserialization, which then calls a post-load virtual function in the ModelAssetManager which does the vertex buffer conversion.   All the data chunks are POD essentially (or made up of other structures that are), and the deserialization process will create ptrs between the different chunks. These required ptrs are registered at compile time, by the source chunk, the destination chunk, and an offset into each.   Then, in order to use the loaded asset, I have a separate object that references the Asset. So, I'll create a Model object with a reference to the ModelTemplate, and this instanced object does NOT inherit or contain Asset.   So, for another example, I have an EntityTemplate which is compiled into this generic format and loaded by the Asset Manager. Then, when I want to use it to create a runtime Entity, I create a separate Entity object which refers to the EntityTemplate and use the unchanging data inside the EntityTemplate to create the Entity.   Then I have assets such as Textures and Shaders which will just be loaded directly by Direct X, but I still want to create an Asset object with a ptr to the DX texture or shader object so I can still do it through my Asset Manager interface, it's just that the derived asset manager will create a Texture object (essentially a struct with an Asset object, and a ptr to a DX texture) and get DX to load the texture instead of loading everything from my generic data chunk format. I mean, I could compile a very small header object which, as a result loads the texture using DX, but that seems unwieldy and unnecessary to have what will amount to a secondary 40 byte "Asset" header that has no real data inside it to load a texture.   I guess my issue is that I was converting everything in my engine (fairly mechanically and obviously without enough forethought) to C++ objects because previously everything (Renderer, Asset Manager, etc) were C structs and separate functions instead of C++ objects with member functions. But because for my assets everything needs to be POD, I can't use C++ objects at all because of the virtual function table issue. Well, technically I could, but every time I added a virtual function I would have to rebuild all the assets, and that's just silly.   So I was wondering if anyone had a better idea, or if there was a standard way of being able to have C++ objects with virtual functions as assets that are loaded from file without having a really complex, member by member serialize/deserialize process.
  2. Okay, for starters, it's been quite a while since I've been on GD, so take pity on me, and the possible uselessness of my tags and other things :) GD.net has been enhanced significantly since I was regularly posting last, and I'm excited to see it :) At the moment I'm in the middle of enhancing the asset management in my engine. I find myself needing to make a distinction between "internal" assets and "external" assets. Internal assets are assets that are compiled specifically for my engine using my own tools, to a basic data chunk format which defines a set of data chunks and pointer references between those chunks. Nothing super complicated, just something to get compiled static assets up and loaded with a minimum of fuss without having to write a loader or interpreter for each and every different kind of asset. External assets are assets such as textures and shaders which I want to be able to deal with generically as assets, but are actually directly loaded and dealt with by Direct X. So, I have a base class "Asset", so for every asset I can quickly and easily just cast to an Asset and release it's reference count, etc, etc, all the basic stuff that one would want to do to a basic asset. But I also want to deal with external asset through the same Asset interface, to make things simpler for my whole engine. At the moment, most internal assets are composed of basic C structures, where the "Asset" structure is the first. Example: struct ModelTemplate{ Asset m_Asset; // blah other Model and geometry related data }; But most of my engine had been written in C style, and not C++ style, and I recently decided that it was stupid, and have spent a bit of time converting things to C++ OO style, including the Asset Managers, and the Asset struct into proper classes. My current problem is that I can have the base Asset Manager class quite easily load from my internal data chunk format, but if I want to keep the same Asset Manager -> Asset interface, then I'll start having issues, because with C++ objects, it's quite likely that I'll at some point be dealing with virtual functions in my derived Asset classes. Which means that with External assets, I can always create an Asset object and set a ptr to the Direct 3D asset (ie. texture or shader, etc) without an issue, but then if I ever have a virtual function on a non-external assets, then I immediately have problems, because the power of the Internal asset system (chunk based format) is also it's weakness, the fact that it just copies data around and links pointers, and has no knowledge of virtual function tables, whereas when referencing data members of a class, the size of the virtual function table is automatically accounted for and offset from the beginning of the object. I'm certain that at some point, I'll end up overwriting a virtual table of function pointers. And I don't want to have to remember and re-compile all the assets of a certain type whenever I add another virtual function to an Asset derived class. I'm trying to think of my options, and I can only think of 2:Make the asset compilation much more complicated, much more akin to a full serialization, de-serialization set of methods.Go back to the old way of having all the assets be simple data structs without any virtual functions and write all their functionality as C-style functions which accept a ptr to the struct as the first parameter.I'm leaning towards the second option even though it means that I'll be mixing C and C++ style code, I think that it will work better overall. Does anyone have any suggestions? Have I been clear enough, or did I ramble a bit? Is there a standard way to handle something like this? I mean, I'm not dealing with legacy code, just an Asset Manager generic asset loader which is blind to type, and other Asset Managers which are specific and don't load the assets themselves ...
  3. 512k is a pretty big heap. From what I remember, it's smaller on a lot of hardware. Well, it's not really going to matter. I mean, you don't want to store it in a binary file, but the thing is that even if you increase the stack size and define it in the executable, it won't be that hard to extract it from the executable. In the exe, that data is going to be somewhere in there, defined exactly as you put it in, otherwise it wouldn't work. So there's little difference between having it in a file, or having it defined in the exe. I don't know exactly what the array is. Is it the data that you want to encrypt, or is it data that you use to encrypt other data? Is it possible to calculate it on the fly? Even just up front so you can allocate onto the heap and calculate it all at once?
  4. As long as the language is in widespread use, then you'll get good experience with it, and there'll be enough people around to help you. I find that C and C++ are good for learning the lower level stuff as you can do the lower level stuff with it quite easily, like memory management. Yes, it's not the correct tool for everything, but with any programming language as widespread and non-specialised as C/C++ (and others such as python), you'll learn how to program. I'm not referring to the syntax and usage of the language, I'm referring to learning how to see a problem, and then break it down into components and problems that you can solve bit by bit to come up with a complete working solution. That is a portable skill across all programming languages and is not restricted to just C++.
  5. You would generate a projectile of a specific type that has a specific movement that would update it's position each frame. This could be a function that calculates it's position using a trig function, such as a sine or cosine wave, or for more complex paths that can't be calculated with a math or programming function easily, I've seen some people that have an editor that can define a path (just a set of points on the screen for the bullet to move between), and then have the projectile move between those points. Actually, the use I saw was for the patterns and movements of enemy ships in a similar type of game, but there's no reason why it couldn't be used for bullets. Then you just generate a hundred or several hundred of them at different points on the screen and let them go. You will probably need instance specific data for each one, for anything that's not a simple up-down or left-right movement. In the video, with the first wave, they were each doing exactly the same movement except for the directions they were doing it in. That's what I mean by instance specific data. So, to conclude, you want to create a movement type that projectiles can follow. You make one that looks kinda alright by itself, and then you spawn 100 projectiles that point in different directions, and that's why they look so cool. Later on, if you want to to something as complicated as in the video, you'll want to be able to define a chain of movement types for a bullet, but that's a bit more complicated as you have to decide how to determine when one of the movement types ends and when it's time to start the next one. You could do it based on time, or distance travelled, or something like that. You could even have one as time, another as distance, another as part of a complete circle revolution, etc, etc. Basically it's up to you.
  6. You basically want to be looking at tying scripting languages like lua and python into C/C++ (assuming that's what you're using). I can't think of any tutorials off the top of my head, but once you've chosen your scripting language, you should be able to find it easily using google. Basically you'll want a game object of some sort that will wrap a script and update it with the rest of the game in the game update loop. There will also be a way, no matter what scripting language you use, to bind (convert) a script call into a C/C++ call, so you'll be implementing those functions as well. Basically, take a look on the forums about what scripting language to choose because, there have been many many people that have asked in the past, and it partially relies on what you'll be using it for and how you want to use it. When you've made a decision on language, then you can look at how to integrate it into your game.
  7. It really depends. I mean, if you're resetting the world and not the character states, then it's not a big deal at all. I mean, most worlds will be in a state of constant reset anyway. Once you've completed a quest, then another character/party can complete that quest and you move on. But if you're talking about resetting the character states as well, then absolutely not, if you do that, then there's not incentive for your players to play the game. They won't be able to keep anything, and even though you're saying it up front, you're effectively robbing them of anything that they've been able to achieve. The fact that you're robbing everyone at the same time doesn't matter, in my opinion.
  8. I have a fairly simple xml file format that I want to load and decided to use XML serialization. [code] <tools> <tool name="tool name" path="tool path"> <required_tags> <tag>tag1</tag> <tag>tag2</tag> </required_tags> </tool> </tools>[/code] My class definition looks like so: [code] [XmlType("tool")] public class Tool { [XmlAttribute("name")] public string Name { get; set; } [XmlAttribute("path")] public string Path { get; set; } [XmlArray("required_tags")] [XmlArrayItem("tag")] public string[] RequiredTagList { get; set; } } [XmlRoot("tools")] public class ToolList : List<Tool> { }[/code] This works fine, but I feel that creating an empty class to inherit from a container to act just as a container without any extra functionality is kinda clunky and unnecessary. I was looking for a typedef analogue in C# (can you tell I come from a C/C++ background?) and I found this: [code] using ToolList = List<Tool>;[/code] Which the compiler accepts fine, but since it's not a class declaration, I can't seem to add the XML serialization metadata to it, the compiler complains. Is there any way to get this working with the 'using' statement instead of the empty class?
  9. *sigh* You are completely correct. I am, now irritated that I didn't realise that before. I would have expected it to throw an error complaining that the expression didn't evaluate to a function, or something similar. Well, now I know, thanks. Maybe, regardless of the contents of the file, I should just make all source files cpp. Would make it slightly longer to compile, and might mess with the generated code. Maybe I should do it anyway and deal with the problems as they arise?
  10. I've posted this here because I can't see a compilation error and am not doing anything unusual, so I wondered whether this might be a d3d problem that someone else has come across. I'm working in DX9 and I'm just trying to release a vertex buffer. [code] void ModelManager_ModelTemplateDestroy(void* pData, Asset* pAsset) { <snip> // iterate through all the MeshTemplates and their RendererStreams to destroy their D3D VertexBuffers { u32 uCount; u32 uStreamCount; for(uCount = 0; uCount < pModelTemplate->m_uMeshCount; ++uCount) { MeshTemplate* pMeshTemplate = pModelTemplate->m_paMeshTemplates[uCount]; for(uStreamCount = 0; uStreamCount < pMeshTemplate->m_uStreamCount; ++uStreamCount) { RendererStream* pRendererStream = &pMeshTemplate->m_aStreams[uStreamCount]; if( pRendererStream ) { if( pRendererStream->pD3DVertexBuffer ) { pRendererStream->pD3DVertexBuffer->Release(); // <<<<<<<<<<<<<<<<<<<<<<<< pRendererStream->pD3DVertexBuffer = 0; } }//if(pRendererStream) }//for(uStreamCount < pMeshTemplate->m_uStreamCount) }//for(uCount < pModelTemplate->m_uMeshCount) } } [/code] The compile error comes out as [code]1>.\source\ModelManager.c(348) : error C2039: 'Release' : is not a member of 'IDirect3DVertexBuffer9'[/code] except that d3d9.h is included and the next line in the error (see declaration of 'IDirect3DVertexBuffer9') actually takes you do the interface definition where you can clearly see the macro for defining the "Release" function. I've tried a clean and rebuild, also tried compiling with the line commented out, I get no other errors that could be cascading down onto it. The code is in a source file, so I'm not getting some weird include circular error or anything. I'm at a loss. Am I going crazy? What am I missing?
  11. [quote name='Hodgman' timestamp='1308203754' post='4823949'] You can break your asset file into a few chunks - e.g. the parts that should end up in system-RAM, the parts that should end up in VRAM, and the parts you only need temporarily for annoying post-load processing (hopefully not needed). When loading a file, you can read the sizes of these chunks up front, malloc them, and then read the file into the allocations. [/quote] This is exactly how my asset reader/writer works, it resolves ptrs and everything, makes it really easy to write an asset in it's runtime format and automatically load it all. [quote name='Hodgman' timestamp='1308203754' post='4823949'] On PC, I follow the same design of having a "VRAM" chunk in the file, except there's a post-load event which gives the data to D3D and the deallocates the "VRAM" allocation. This is just a fact of life on PC :/ Seeing you know you're only going to hold onto this allocation for a short period of time, you can choose to allocate them from a separate area to your main allocations to avoid fragmenting your heap. [/quote] Yeah, I kinda suspected. I'll probably just add in extra ptrs for a D3D Vertex and Index buffer to the runtime structure, and when it gets written out, just write it out as 0 and then at runtime I'll create the buffers, set the ptrs and then free the other memory. So they'll always be at least 1 unused ptr in the structure, but that's not too big an issue for me considering it effectively solves this problem. [quote name='Hodgman' timestamp='1308203754' post='4823949'] GPU resource creation is slow, so I'd recommend doing it on your loading screen instead of on first-use. Ideally D3D won't have to copy resources in/out of VRAM because you shouldn't be allocating more memory than the card has available, right? [img]http://public.gamedev.net/public/style_emoticons/default/wink.gif[/img] [/quote] Uh ... yeah ... sure .... Well, I'm not now, I'm just using basic models to test all of this, and I've written some code to output a very basic ID3DXMesh into my own text model format (which gets compiled into a binary asset, as described above by another tool), so I've got the teapot that I can use, and whatever else can be created as a ID3DXMesh test model. Later on when I'm doing a project or a tech demo, I hope I wouldn't fill up the VRAM on the GPU, that'd be pretty crazy!
  12. What about in terms of loading assets? At the moment the way my assets load is that they're all bundled up in what is essentially the runtime format, but I'm obviously not able to load a vertex buffer directly, and since my asset loading system is general and works the same way for all assets, then I'll need to load the geometry as normal, then as an asset post-load step (which my system already supports) create the vertex buffers, copy the data in and throw away my own loaded data. Not a big deal in implementation, although preferable would be to do no processing after load, but my issue is that at one point I'll essentially have 2 copies of the data in memory, even if it's for less than a single frame. Maybe it's just not a big enough deal for most models and on a PC? At the moment my mentality is more of a console programmer (cause that's where my experience lies). And should the creation be when you load/create a model, or when it's actually going to be rendered? I'm not yet up to scene management, but at some point I'll be partitioning my geometry and using a frustum to cull objects that aren't being drawn. Should the objects that aren't being drawn still have existing vertex buffers? Is that the standard practice, and simply let DX manage them and pull them out from the GPU (or rather, not copy them in)?
  13. I'm working with DX9 at the moment, planning to move to DX11 when I finally upgrade my comp and move to Windows 7. But at the moment, when I'm rendering some geometry, I'm creating the vertex buffer immediately before the draw call and then releasing it immediately after. This was just to make it easier when I was starting out, and I was going to re-visit it later on. I think now may be later enough, so I wanted to ask about what vertex buffers actually do and whether I should be creating vertex buffers for everything that I want to render and throw away the copy of the geometry that i usually keep. Vertex buffers give the data to DX so DX can copy it to the GPU for rendering when appropriate, right? I'm assuming that most developers don't create a vertex buffer, use it immediately and then throw it away. Should I be keeping them all around as soon as the mesh/geometry is loaded?
  14. [quote name='Nypyren' timestamp='1306809582' post='4817732'] Beware things that *seem* to be dead code - some scripting systems I've seen use reflection (or some other kind of runtime lookup) when a script is interacting with the engine code. Removal of such engine code will compile, but then mysteriously crash at runtime when the particular script tries to call the associated engine code. [/quote] Yeah, a better idea (depending on language and compiler) would be to compile the app, lib, whatever it is, and then actually view the debug map files generated at the end to make certain that the classes/functions weren't left in the lib because of some command line switch to the compiler to disable stripping of unused code and classes. Then you can be absolutely sure that you can get rid of them, because if they're not in the final product, then they're obviously not used at all!
  15. Preferably, have them send email a contract, print out several copies (of the pages you need to sign), sign them, send them via snail mail to the other party, have them sign it, and then send your copy back. So, the work starts when you each have a signed copy of the contract.