   Asking for a bit of help...
  Hi. First, some background. I've been having some problems lately. A string of failed projects has left me struggling to write even simple programs. I always try to plan projects well, and usually do, but they go wrong because I second-guess myself, and I always have that nagging feeling that whatever I'm doing, it's Not The Right Way™. I also see things, on these forums and in general research for projects, that make me change my designs "for the better", leading to failure. I have tried, and I think I'm pulling myself out of it, but I need some help from you, the good people of GameDev. It's good to talk to people, and discuss ideas, and I think that might be half my problem: I have no one to talk to about these matters, no one to even bounce ideas off, let alone someone to say, "Yeah, that code looks OK."I have started a medium-sized project which will do some simple animation, and will demonstrate some game principles (there's a simple class factory for game world objects, that kind of thing). However, at the moment, I'm coding the support structure, and for that, I have looked to various frameworks and also to the Ogre engine. I have tried to keep the code as reusable as possible, and have created a namespace to keep all my support classes in. The animation I mention will concern static meshes moving at certain pivot points, and as such, I have taken a scene graph approach to modelling the game world. I have a scene graph class, along with a scene graph node class. Every frame, the scene graph is drawn by a renderer (I have yet to write this). I also wrote a simple log class, that is a singleton (and can be used by all parts of the program, from the support classes to the main application class and the game classes it contains).I've run into a slight problem, however. In order to load meshes, I need to be able to create textures. I see two solutions to this:1. Make a texture manager class, and make it a singleton. Then, any mesh loader can create textures and associate them with a mesh.2. Do it another way (but, try as I might, I can't see another way of doing it. I probably could think of one, but it's 2am, and I need to sleep. I have a creeping suspicion, though, that I'm partitioning my code too much; my classes are not intergrated enough to accomplish what I want. I should also probably mention that I'm using classes for everything. This probably isn't good either).See, I would have been happy to use singletons, but I saw a post here which said "If you're using more than two singletons in a project, chances are, you need to redesign". Perhaps that's right, perhaps that's wrong. I don't know, and my self-doubt has now stalled my project. Any help at all is very much appreciated. Also, if anyone is willing critique my design or code, please PM me...EDIT: A little more explanation of how I think my scene graph system should work: When I create an instance of a game object, it's constructor looks for the meshes it requires (which will have been precached), and creates scene graph nodes which point to those meshes. If you had a model in two parts, where the first was the parent, and the second was the child, two nodes would be created which contained pointers to the meshes, and the node which pointed to the child mesh would be the child of the node which pointed to the parent mesh. Each node has a position and an orientation relative to the node above it, so to draw the hypothetical model mentioned, you would translate from the world origin to the parent node's position, draw the mesh it pointed to, then translate again, to the child node's position (relative to the parent node), and draw the mesh it pointed to. Is this basically correct?   
  First, any time you wonder if you're going about things the wrong way, or not using the best/cleanest method, open and look through the Quake 2 source code. This will prove to you that it is entirely possible to make a great game with a terrible, messy, and hack-filled design.Anyways, as for the specific problem, singletons are the de facto standard for texture managers. This allows a couple things:1) Texture creation, destruction, and access is centralized. Classes don't need to manage their own textures; instead, it's done in a single place and cleanly.2) If you make a pure virtual base class singleton, and then derive from it, you get an extremely useful side effect. You can use the singleton accessors to get the pointer to the singleton by referring to the base class (e.g. TextureManager::GetSingleton()->Bla()). However, the actual call will be routed down through the virtual table to the appropriate class (e.g. OGLTextureManager, D3DTextureManager).So you can write:new OGLTextureManager();And an OpenGL manager is created. No one needs to know that this is an OpenGL manager. Simply refer to TextureManager::GetSingleton and everything is routed to the right person. This doesn't work with statics, and it's sort of manageable with globals, but singleton cleans it up and wraps it nicely.Now go sleep.   ;  A belated thank you, Promit.I have implemented a singleton CTextureMgr object, and derived a COpenGLTextureMgr from it. It is simple at the moment, with two functions: CreateTexture and SelectTexture. CreateTexture returns a pointer to a CTexture, and SelectTexture accepts a pointer to a CTexture. I also have a COpenGLTexture, derived from COpenGLTexture. This appears to be working well.EDIT: <br><br>Oh, and hooray for me. My university exam results came back, and they were good. Very good. Excellent, you might say <img src="http://www.gamedev.net/community/forums/images/icons/icon6.gif"><br><br><!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - iNsAn1tY on July 17, 2004 11:06:42 PM]<!–EDIT–></span><!–/EDIT–>;Quote:First, any time you wonder if you're going about things the wrong way, or not using the best/cleanest method, open and look through the Quake 2 source code. This will prove to you that it is entirely possible to make a great game with a terrible, messy, and hack-filled design.well said.in answer to the question:Everyone has an opinion on everything. Which is all it is, jsut an opinion. When you read or hear someones opinion never assume it's the 'The Right Way™'. It's their opinion, and if it works best for them, good for them. Doesn't mean it's good for you. You can learn from it however.So.I present my opinion ;)The texture management side of things, you seem to be onto the right track.The way I do things: (this works for me, so it might give you some ideas)the only 'publically' accessable class (ie, the only one I let the rest of my code use) is a 'CTexture' class, which is a very simple wrapper around a CTextureObject class (which is not accessable).CTexture has the appropriate getSize() methods, etc. And it has a number of static create method (pretty much every object I use has a static create method or two). This is the way I go about doing 'managers'.Then there are COpenGLTextureObject and CDirect3DTexture object, which inherit from CTextureObject (CTextureObject is a mostly abstract class). Both API texture objects have access to the COpenGLRenderer and CDirect3DRenderer classes, which help them load the texture.So CTexture only exposes the most basic functionality, and is always accessed by a pointer reference.At it's simplest the texture managment side of the picture is jsut a hash-table... so you don't end up loading a texture twice...Then there is various other classes that use CTexture, such as CTextureEffect and CTextureStage... etc.As I say, I generally keep 'managers' in the background out of sight. A coder using your code as a library should never need to use a manager..I feel that:CTexture * tex= CTexture::create("mytexture.bmp");is a bit easier to use than:CTexture * tex= CTextureManager::getInstance()->createTexture("myTexture.bmp");especially when it's consistent over all object types.But the disadvantage is when it comes to implementation, having a bunch of create methods in every single object can become a hassle to do.. and usually will require a macro.. which isn't perticuarly nice code...(I've been thinking recently that a globally accessable set of template functions would do the trick, eg:CTexture * tex=create<CTexture>("mytexture.bmp"); )But hey, this is just my opinion :)do what you feel comfortable with, and if you are going to make sweeping changes to code, backup backup backup, then go through every case that would change, and make sure it doesn't require some backwards hack to get it work with the new system.And only make a sweeping change when it gives you a clear advantage in code. If it looks nicer, well, it's probably not worth the effort. But if it makes your code more flexible and allows you to do things that otherwise needed hacks, then definitly give it a try.   ;Quote:Original post by iNsAn1tYI've run into a slight problem, however. In order to load meshes, I need to be able to create textures. I see two solutions to this:1. Make a texture manager class, and make it a singleton. Then, any mesh loader can create textures and associate them with a mesh.2. Do it another way (but, try as I might, I can't see another way of doing it. I probably could think of one, but it's 2am, and I need to sleep. I have a creeping suspicion, though, that I'm partitioning my code too much; my classes are not intergrated enough to accomplish what I want. I should also probably mention that I'm using classes for everything. This probably isn't good either).See, I would have been happy to use singletons, but I saw a post here which said "If you're using more than two singletons in a project, chances are, you need to redesign".Here is my resource manager design; it is based on a flyweight design pattern (is is not perfect) and only requires one singleton for all of the resources:Since it is hard to read within the forum; here is the URL:DiagramQuote:Each node has a position and an orientation relative to the node above it, so to draw the hypothetical model mentioned, you would translate from the world origin to the parent node's position, draw the mesh it pointed to, then translate again, to the child node's position (relative to the parent node), and draw the mesh it pointed to. Is this basically correct?I would question whether rendering as you described above would work for transparent objects?  Generally speaking transparent objects have to be drawn after opaque object?  Also, it is best to sort transparent object before they are rendered?  I think you can use the hierarchy to perform spacial culling; but I don't think it will work for rendering unless all your object are opaque? If this is not the case; please explain how this would work; because it would definitely be easier than sorting?   