gamedevlists-general Mailing List for gamedev (Page 57)
Brought to you by:
vexxed72
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
(28) |
Nov
(13) |
Dec
(168) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(51) |
Feb
(16) |
Mar
(29) |
Apr
(3) |
May
(24) |
Jun
(25) |
Jul
(43) |
Aug
(18) |
Sep
(41) |
Oct
(16) |
Nov
(37) |
Dec
(208) |
2003 |
Jan
(82) |
Feb
(89) |
Mar
(54) |
Apr
(75) |
May
(78) |
Jun
(141) |
Jul
(47) |
Aug
(7) |
Sep
(3) |
Oct
(16) |
Nov
(50) |
Dec
(213) |
2004 |
Jan
(76) |
Feb
(76) |
Mar
(23) |
Apr
(30) |
May
(14) |
Jun
(37) |
Jul
(64) |
Aug
(29) |
Sep
(25) |
Oct
(26) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(9) |
Feb
(3) |
Mar
|
Apr
|
May
(11) |
Jun
|
Jul
(39) |
Aug
(1) |
Sep
(1) |
Oct
(4) |
Nov
|
Dec
|
2006 |
Jan
(24) |
Feb
(18) |
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
(14) |
Aug
(29) |
Sep
(2) |
Oct
(5) |
Nov
(4) |
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(11) |
Sep
(9) |
Oct
(5) |
Nov
(4) |
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(34) |
Jun
|
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
From: gekido <mi...@ub...> - 2003-02-05 21:35:02
|
with this said, anyone know of any opensource projects implementing a base COM-style cross-platform & cross-compiler library out there? surely there must be someone that's done the hard part for us ;} just curious mike w www.uber-geek.ca > > > Personally I find COM very good at exactly what you want. > > > > Except for the cross platform thing. > > I specifically addressed that issue. COM is an idea not a tool. It can be > implemented on any platform. and as I said in my original post, > reimplementing the basics is a Good Thing because there is a lot ( Like > using the registry to find objects ) that you don't need from COM. |
From: Peter D. <pd...@mm...> - 2003-02-05 21:25:01
|
Noel Llopis wrote: > On Wed, 05 Feb 2003 22:53:49 +0200 > Peter Dimov <pd...@mm...> wrote: > >> Out of curiosity, can someone post a real example of using the >> QueryInterface pattern (in performance-critical code)? > > Sure, we use it in MechAssault. > > Every frame we quickly cull out any scene nodes that are not visible > from a camera, and then for each scene node we query to see if they > implement the IRenderable interface. If they do, they get a render > call. Yes, I envisioned something like that. What are the advantages of this approach over just providing a (possibly empty) render() in every node type? A virtual call can never lose to a QI + test + potential call. |
From: <phi...@pl...> - 2003-02-05 21:16:14
|
>>> Personally I find COM very good at exactly what you want. >> Except for the cross platform thing. >I specifically addressed that issue. COM is an idea not a tool. Ooops, apologies for jerking that knee a little too quickly... Cheers, Phil |
From: Noel L. <ll...@co...> - 2003-02-05 21:07:40
|
On Wed, 05 Feb 2003 22:53:49 +0200 Peter Dimov <pd...@mm...> wrote: > Out of curiosity, can someone post a real example of using the > QueryInterface pattern (in performance-critical code)? Sure, we use it in MechAssault. Every frame we quickly cull out any scene nodes that are not visible from a camera, and then for each scene node we query to see if they implement the IRenderable interface. If they do, they get a render call. Performance was never a problem in our case; It never even showed up anywhere in a profiler report. --Noel ll...@co... |
From: Peter D. <pd...@mm...> - 2003-02-05 20:54:00
|
Gareth Lewin wrote: >>> Personally I find COM very good at exactly what you want. >> >> Except for the cross platform thing. > > I specifically addressed that issue. COM is an idea not a tool. It > can be implemented on any platform. and as I said in my original post, > reimplementing the basics is a Good Thing because there is a lot ( > Like using the registry to find objects ) that you don't need from > COM. Out of curiosity, can someone post a real example of using the QueryInterface pattern (in performance-critical code)? |
From: Gareth L. <GL...@cl...> - 2003-02-05 20:47:45
|
> > Personally I find COM very good at exactly what you want. > > Except for the cross platform thing. I specifically addressed that issue. COM is an idea not a tool. It can be implemented on any platform. and as I said in my original post, reimplementing the basics is a Good Thing because there is a lot ( Like using the registry to find objects ) that you don't need from COM. |
From: <phi...@pl...> - 2003-02-05 19:41:50
|
>brian sharon <pud...@po...> wrote: >> Question: there were references to code bloat produced by RTTI. Is thatreally a big issue? It's just some bytes added per vtable - I'm wondering if anyone's measured it to come up with a more exact number than that. Noel Llopis <ll...@co...>: > You are right, it is probably not all that significant. I haven't measured it, and it can vary from implementation to implementation, but it's not going to amount to a lot of memory. The main drawback, on the PS2 at least, is that the RTTI information is in a seperate block, pointed to by an extra vtable member. This incurs an extra potential data cache miss every time the RTTI is accessed, and data cache misses are bad. Cheers, Phil |
From: <phi...@pl...> - 2003-02-05 19:36:36
|
> Personally I find COM very good at exactly what you want. Except for the cross platform thing. Cheers, Phil |
From: <phi...@pl...> - 2003-02-05 19:36:02
|
Alex Lindsay <ali...@au...>: > As far as I understand it, every polymorphic class is going to have a unique vtable pointer, and while it's compiler dependent, my experience is that the vtable pointer tends to be the first "member" data in every instance. DANGER! This assumption is not true for gcc, unless all of the classes you're making this assumption for have a virtual function in their root base class. For gcc, at least the versions I'm familiar with, the vtable is the first item in the first class in the heirarchy with a virtual function. To take Peter's example: struct X { int x; }; struct Y: public X { virtual ~Y(); }; In gcc, the vtable would be the second member in raw memory. Other than that, it's a nice, if not particularly portable, idea. Personally I'd like to have formal access to the vtable pointer (and the corresponding labels exposed), so you could do precisely this sort of 'quick and dirty' hand rolled RTTI. The standard RTTI scheme is, IMHO a bit, all or nothing, and with all being expensive overkill in many cases, nothing is what you usually get. Cheers, Phil |
From: Peter D. <pd...@mm...> - 2003-02-05 11:59:03
|
Alex Lindsay wrote: > Has anyone considered comparing the vtable pointers themselves in > order to identify a class? > > As far as I understand it, every polymorphic class is going to have a > unique vtable pointer, and while it's compiler dependent, my > experience is that the vtable pointer tends to be the first "member" > data in every instance. > > i.e. int vtable = *reinterpret_cast<int*>(someInstancePointer); > > I'm not too sure about multiple inheritance. It depends on your compiler. The MSVC object model always places the vptr at offset 0. struct X { int x; }; struct Y: public X { virtual ~Y(); }; On MSVC, Y::__vptr is at offset 0, and the X subobject is at offset 4. Note that this means that if you put Y* into a void* and then get X* from that void*, you'll be surprised. And there's no MI in sight. Other compilers, on the other hand, prefer to leave X at offset 0, and Y::__vptr goes at offset 4. Another interesting tidbit is that the vtable is not guaranteed to be unique. Even on MSVC, where the linker is very good at merging equal things, you could have one vtbl in the EXE and one in the DLL. The Windows loader isn't that good yet. This applies to &typeid(x), too. |
From: Thatcher U. <tu...@tu...> - 2003-02-05 00:14:29
|
On Feb 05, 2003 at 10:33 +1100, Alex Lindsay wrote: > Has anyone considered comparing the vtable pointers themselves in > order to identify a class? > > [...] > > I would love to hear problems with this! Well, one problem is that it identifies a class, but it doesn't cast for you, so it's not really solving the original problem. -- Thatcher Ulrich http://tulrich.com |
From: Alex L. <ali...@au...> - 2003-02-04 23:33:14
|
Has anyone considered comparing the vtable pointers themselves in order to identify a class? As far as I understand it, every polymorphic class is going to have a unique vtable pointer, and while it's compiler dependent, my experience is that the vtable pointer tends to be the first "member" data in every instance. i.e. int vtable = *reinterpret_cast<int*>(someInstancePointer); I'm not too sure about multiple inheritance. One problem is that you need an instance of every class you wish to identify so that you have a value to compare! Some start up function could harvest these from temporary instances. I would love to hear problems with this! Alex Lindsay |
From: Noel L. <ll...@co...> - 2003-02-04 23:06:17
|
On Tue, 04 Feb 2003 14:43:36 -0800 brian sharon <pud...@po...> wrote: > Question: there were references to code bloat produced by RTTI. Is that > really a big issue? It's just some bytes added per vtable - I'm > wondering if anyone's measured it to come up with a more exact number > than that. You are right, it is probably not all that significant. I haven't measured it, and it can vary from implementation to implementation, but it's not going to amount to a lot of memory. Most implementations add one extra entry to the vtable to every class that already has a vtable (if a class doesn't, you're not treating it polymorphically, so you don't need RTTI). So that's one dword per class. Big deal. In addition to that you have the actual information kept by each class. At least it's going to be the information contained in the type_info structure: decorated class name and sequence number. It probably has some other internal data. Even so, we're probably talking about 100 bytes per class? At a round 128 bytes per class, if you have 1000 classes with virtual functions, it will take 128 KB. So it's not totally peanuts in the case of a console with 32 MB or even 64 MB, but it's not a huge amount. Still, that's with 1000 different polymorphic classes, which is probably way on the high end for a normal game today. I'd guess that a lot of games are only using more on the order of a hundred polymorphic classes, which brings it down to a more reasonable 15-20 KB. Having said all that, I still don't like using C++'s RTTI for getting the interface pointers to classes. I prefer using the custom QueryInterface function we talked about. And for regular RTTI, I much prefer a custom system. They are so simple to implement too, that with the added flexibility they provide, there's almost not reason not to. --Noel ll...@co... |
From: brian s. <pud...@po...> - 2003-02-04 22:43:39
|
I would 3rd the recommendation for Inside COM, and point out that there are some other tricks you can pull off with a QueryInterface approach that can't be achieved with dynamic_cast (or rather, I don't see how to achieve them). The most useful one to my mind is aggregation. An object can be built as a collection of other objects (has-a rather than is-a), and those objects can delegate all QI calls to their parent. By doing this, given one interface pointer from the parent object, you can cross-cast to another interface, even though those 2 interfaces are implemented in separate classes. A rotten example: class COneTwo : public IUnknown { IOne * mOne; ITwo * mTwo; ... } With aggregation, one can get an IOne interface off the COneTwo object, and then get an ITwo interface off that IOne interface. But the actual implementations of IOne and ITwo are in completely different classes. When you picture being able to bolt on orthogonal behavior to objects, like combining IDebugRender with objects that implement other interfaces, this gets more interesting. No more do you have to put IDebugRender near the top of your inheritance tree; you just give an implementation to objects that need it, without modifying the implementation of the other interfaces that the object supports. Groovy! ATL Internals is a great book to read if you want to set up your COM system to support this and other such exotica (tear-off interfaces, etc). Question: there were references to code bloat produced by RTTI. Is that really a big issue? It's just some bytes added per vtable - I'm wondering if anyone's measured it to come up with a more exact number than that. My gut feeling is that it wouldn't be that significant, but I'm wondering if my gut is lying...or maybe the feeling in my gut is really coming from the Mexican food I had at lunch... --brian Noel Llopis wrote: >I found the book Inside COM to be extremely enlightening. The author >goes step by step developing a COM-like approach (until it becomes >full-blown COM), which is pretty much what you want to see. > >You can check out one of my articles in Game Programming Gems 2. It >talks about exactly this topic, and it provides some sample code >(although it seems you have figured it all of it by yourself already). > >Finally, at the danger of blowing my own trumpet too much, I have a >whole chapter dedicated to this in my upcoming book "C++ for Game >Programmers" (http://www.amazon.com/exec/obidos/ASIN/1584502274) > > >--Noel >ll...@co... > > > |
From: Ray <ra...@gu...> - 2003-02-04 22:22:59
|
Yay! thanks a lot! This is pretty much what I was looking for. - Ray Tom Spilman wrote: >>I am working on a simple chat filter for our network game. >>Are there any drop-in chat filters available? >>How does everyone else deal with chat filtering? > > > Check out http://jratcliff.flipcode.com/ for Ratcliff's "CleanLanguage" > filter. Tom |
From: Chris B. <Chr...@ma...> - 2003-02-04 22:02:49
|
Dosn't John Ratcliff have something like this: "This code snippet will take any stream of ASCII input in the English language and search for objectionable language. If offending language is found, then the original input will be replaced with non-offensive alternatives." http://jratcliff.flipcode.com/ -----Original Message----- From: Ray [mailto:ra...@gu...] Hi, I am working on a simple chat filter for our network game. Are there any drop-in chat filters available? NOTICE This e-mail and any attachments are confidential and may contain copyright material of Macquarie Bank or third parties. If you are not the intended recipient of this email you should not read, print, re-transmit, store or act in reliance on this e-mail or any attachments, and should destroy all copies of them. Macquarie Bank does not guarantee the integrity of any emails or any attached files. The views or opinions expressed are the author's own and may not reflect the views or opinions of Macquarie Bank. |
From: Tom S. <to...@pi...> - 2003-02-04 21:49:10
|
> I am working on a simple chat filter for our network game. > Are there any drop-in chat filters available? > How does everyone else deal with chat filtering? Check out http://jratcliff.flipcode.com/ for Ratcliff's "CleanLanguage" filter. Tom |
From: Mark W. <mw...@cs...> - 2003-02-04 21:23:58
|
I'm not sure if there are any off-the-shelf solutions for it, but if I were implementing something like it, it would probably make more sense to first store the filter words into a hashtable, then tokenize the input string into words using strtok() or the like, and do a word by word comparison with the hashtable, replacing each word in the input string as needed -- that way, you should be able to do it in time proportional only to the length of your input string, not the size of the filter word list. -- Mark At 03:17 PM 2/4/2003 -0600, you wrote: >Hi, >I am working on a simple chat filter for our network game. >Are there any drop-in chat filters available? >How does everyone else deal with chat filtering? > >I had thought of having a list of words and then strstr() for each one in >my message I want filtered, >That would be kinda slow though if the filter list was big. > >I had also thought of a dictionary tree to store the filter words and then >send the message i want filtered through the dictionary, starting with >each successive character in the msg. > >Am I missing something or does anyone have any better ideas? > > >- Ray -- Mark Wang mailto:mw...@cs... http://www.markwang.com/ AIM:markwang99 |
From: Ray <ra...@gu...> - 2003-02-04 21:14:47
|
Hi, I am working on a simple chat filter for our network game. Are there any drop-in chat filters available? How does everyone else deal with chat filtering? I had thought of having a list of words and then strstr() for each one in my message I want filtered, That would be kinda slow though if the filter list was big. I had also thought of a dictionary tree to store the filter words and then send the message i want filtered through the dictionary, starting with each successive character in the msg. Am I missing something or does anyone have any better ideas? - Ray |
From: Thatcher U. <tu...@tu...> - 2003-02-04 18:40:57
|
On Feb 04, 2003 at 10:42 -0000, Oscar Cooper wrote: > > On the plus side, this is simple and bug-free. However, I've received very > mixed messages about the virtues and vices of dynamic_cast. Some people say > it bloats code, others say it's lean and mean. Some say it's lightning fast, > others that it's appallingly slow. I've never used it heavily enough to > notice a hit. It's slow if you use it too much; we've seen some horrible dynamic_cast<> spikes in VTune. > The next most simple approach seems to be for the Entity base class to > provide a virtual accessor function for each interface, which returns NULL > by default but can be overriden by a derived class: > > IRenderable* const renderable = entity->GetIRenderable(); > > if (renderable != 0) > renderable->Render(); > > One major drawback here seems to be that the vtable for each Entity class > will be bloated by over a hundred bytes, which seems like a bad move for > cache limited situations. My personal recommendation is to use a combination of this, and dynamic_cast<>. Use dynamic_cast<> for the rarer situations, and use GetInterfaceX() for the cases where you want to call it frequently. This should require fewer interfaces than the full number of interfaces in your code, so less vtable bloat. Although I concur with most of the other comments in the thread -- any of these approaches should work, and I don't think there's any super-nice one you left out. Re combining approaches, you could cook up some template trickery to avoid exposing the optimization to the client code: ---- // In the Entity header: class DerivedClass; // forward opaque decl class Entity { public: virtual DerivedClass* GetDerivedClass(); }; template<class T> T DynamicCastFast(Entity* e) { return dynamic_cast<T>(e); } // Here's a specialization, to avoid dynamic_cast when we're casting // to DerivedClass*. template<DerivedClass*> DerivedClass* DynamicCastFast(Entity* e) { return e->GetDerivedClass(); } // Off in its own header... class DerivedClass : virtual public Entity { DerivedClass* GetDerivedClass() { return this; } }; // Client code does this, and doesn't have to care whether the // shortcut is implemented or not: { DerivedClass* dc = DynamicCastFast<DerivedClass*>(entity); } -- Thatcher Ulrich http://tulrich.com |
From: Noel L. <ll...@co...> - 2003-02-04 12:06:42
|
On Tue, 04 Feb 2003 10:42:59 +0000 Oscar Cooper <osc...@cr...> wrote: > I'm guessing that there will be less than a hundred derived classes, no more > than thirty two interfaces, and a few hundred object instances at any given > time. dynamic_cast is OK. It will do exactly what you want, and I don't expect it to be so slow as to be noticeable in your case. However, you will be forced to turn RTTI on for all your classes, which you might not want to do. Also RTTI code and non-RTTI code don't like to mix, so if you're using external libraries that don't have RTTI, that might just decide it for you. > Finally, the Entity base class could provide a single virtual accessor > function that takes an interface identifier as a parameter: > > IRenderable* const renderable = reinterpret_cast<IRenderable*>( > entity->QueryInterface(IID_IRenderable)); > That's a good, simple approach. It's so simple that there's no need to involve C++ RTTI. Like somebody else mentioned, I recommend you use only one function to get all your interfaces instead of one function per interface. That what I use also. That way you get no bloating of vtables and it's a cleaner interface (although you'll have to cast the returned pointer from void * to whatever you want). > There are two obvious implementations of this method: The derived class > either implements the function as conditional code, or maintains some kind > of look-up table. The former seems more favourable as a cross-platform > solution, again for cache reasons, but contains the most implementation > pitfalls. I just did it with conditional statements. They seemed to be just fine. > Any of these methods could be supplemented with an inexpensive test for > interface support by adding a constant data overhead to each Entity object > (in this case, four bytes). Each interface is assigned an identifier, which > corresponds to a single bit in a bitfield owned by the base class: That's an interesting optimization. I doubt you will need it calling it only 1000 times per frame but it's worth keeping in mind. I guess it depends whether most of your objects inherit from a lot of the interfaces or just a couple. Also, if you do that, you'll be forced to come up with some way of giving unique identifiers to each interface, which is not trivial, especially if other people are extending your code. You might have to register interfaces somehow and all that bookkeeping. > So, has anyone tried more than one of these approaches and found one to be > superior to the other(s) in production code? Are there any other ways to > achieve the same results which may be more suitable? Does anyone have any > tricks or tips they'd like to share? That's pretty much it. You've covered all the main points. I found the book Inside COM to be extremely enlightening. The author goes step by step developing a COM-like approach (until it becomes full-blown COM), which is pretty much what you want to see. You can check out one of my articles in Game Programming Gems 2. It talks about exactly this topic, and it provides some sample code (although it seems you have figured it all of it by yourself already). Finally, at the danger of blowing my own trumpet too much, I have a whole chapter dedicated to this in my upcoming book "C++ for Game Programmers" (http://www.amazon.com/exec/obidos/ASIN/1584502274) --Noel ll...@co... |
From: Wayne C. <wc...@re...> - 2003-02-04 11:23:28
|
> Some say it's lightning fast, others that it's appallingly slow. > I've never used it heavily enough to notice a hit. This depends on how you look at it and how much you're using it :) Compared to, say, just copying a pointer it is appallingly slow and if it's used a considerable amount the costs can begin to mount up. It's the RTTI that generally bloats code, all the type information has to go somewhere. Although if you start deriving from virtual base classes that can add a bit more (I've seen implementations where the processor spent a *lot* of time inside the RTTI\dynamic_cast code). Just make sure you profile regularly and have backup plans if it goes wrong. > The next most simple approach seems to be for the Entity base class to > provide a virtual accessor function for each interface, which returns NULL > by default but can be overriden by a derived class: > > One major drawback here seems to be that the vtable for each Entity class > will be bloated by over a hundred bytes, which seems like a bad move for > cache limited situations. I quite like this method, I'm not so worried by the vtable size, though. But more worried by the fact that you're limited to the supplied methods. So if you add a new class and it needs to be supported, then it needs to be added to the base class (meaning a *huge* recompile). Which limits the extensibility of the implementation. > Finally, the Entity base class could provide a single virtual accessor > function that takes an interface identifier as a parameter: This is the method I currently use, it's also how COM works. The only change from your example is that I pass in a pointer-to-a-pointer and the call returns a success\failure result. Eg IRenderable *pRenderable; If ( entity->QueryInterface( IID_IRenderable, ( void** )&pRenderable ) ) pRenderable->Render(); I usually implement the function as conditional code and to avoid the implementation pitfalls I use some macros to make it easy to implement. QueryInterface on the implementation side looks like: IMPLEMENT_CLASS( MyRenderableEntity ) IMPLEMENTS_INTERFACE( IEntity ) IMPLEMENTS_INTERFACE( IRenderable ) END_CLASS() A more in-depth description of this can be found in my (currently incomplete) SDK documentation located at http://www.btinternet.com/~nfactorial/MantraSDK.zip. Wayney -Virus scanned and cleared ok |
From: Gareth L. <GL...@cl...> - 2003-02-04 11:18:22
|
Personally I find COM very good at exactly what you want. You would have to "reimplement" COM. Which is good, because you don't need a lot of what it gives you, and you can streamline it for your own means. I would recommend reading Inside COM, it's a very good introduction and tries to teach you from the bottom up. RTTI is fairly fast in my tests on MSVC. But I've never tried GNU |
From: Oscar C. <osc...@cr...> - 2003-02-04 10:52:34
|
Hi people, Apologies for the length of this post. I'm interested in hearing about real-world experiences of using run-time type information with multiple inheritance in cross-platform (PC, PS2, Xbox, NGC) C++ games. The situation I'm considering is where all game entities are derived from a common Entity base class, and implement zero, one or more interface base classes. I've got a pointer to an Entity object. I want to know if it supports a particular interface, and get a pointer to that interface if it is supported. I'm guessing that there will be less than a hundred derived classes, no more than thirty two interfaces, and a few hundred object instances at any given time. I'd expect there to be less than a thousand interface queries per frame, but this is the least well known metric. Clearly there are a number of approaches available, but I have no hard facts to suggest which is likely to be most appropriate. Out-of-the-box C++ provides the solution by enabling RTTI language support and using dynamic_cast: IRenderable* const renderable = dynamic_cast<IRenderable*>(entity); if (renderable != 0) renderable->Render(); On the plus side, this is simple and bug-free. However, I've received very mixed messages about the virtues and vices of dynamic_cast. Some people say it bloats code, others say it's lean and mean. Some say it's lightning fast, others that it's appallingly slow. I've never used it heavily enough to notice a hit. The next most simple approach seems to be for the Entity base class to provide a virtual accessor function for each interface, which returns NULL by default but can be overriden by a derived class: IRenderable* const renderable = entity->GetIRenderable(); if (renderable != 0) renderable->Render(); One major drawback here seems to be that the vtable for each Entity class will be bloated by over a hundred bytes, which seems like a bad move for cache limited situations. Finally, the Entity base class could provide a single virtual accessor function that takes an interface identifier as a parameter: IRenderable* const renderable = reinterpret_cast<IRenderable*>( entity->QueryInterface(IID_IRenderable)); if (renderable != 0) renderable->Render(); There are two obvious implementations of this method: The derived class either implements the function as conditional code, or maintains some kind of look-up table. The former seems more favourable as a cross-platform solution, again for cache reasons, but contains the most implementation pitfalls. Any of these methods could be supplemented with an inexpensive test for interface support by adding a constant data overhead to each Entity object (in this case, four bytes). Each interface is assigned an identifier, which corresponds to a single bit in a bitfield owned by the base class: class Entity { public: enum InterfaceID { IID_IRenderable = 0x00000001 , IID_ICollideable = 0x00000002 }; public: bool SupportsInterface (const InterfaceID iid) const { return ((m_iid & iid) != 0); } protected: Entity (const unsigned int iid) : m_iid(iid) {}; private: unsigned int m_iid; }; So, has anyone tried more than one of these approaches and found one to be superior to the other(s) in production code? Are there any other ways to achieve the same results which may be more suitable? Does anyone have any tricks or tips they'd like to share? Cheers, Oscar Cooper. Creature Labs. |
From: Chris B. <Chr...@ma...> - 2003-02-03 22:43:30
|
I'd like to thank all who lent advice on this thread. I implemented the solution suggested by Chris Jones, Jason Maynard and other to use a fixed layout. I have opted for 800*600 as it seemed most intuitive to me as was what I had been working with. The only issue now is that my bitmap based fonts seem blurry at larger resolutions (like 1600x1200). To combat this I'm moving to a larger font size as larger font's appear unblurred. I assume this is just a mag filter artefact of 10 bit fonts. Once again thanks all, Chris NOTICE This e-mail and any attachments are confidential and may contain copyright material of Macquarie Bank or third parties. If you are not the intended recipient of this email you should not read, print, re-transmit, store or act in reliance on this e-mail or any attachments, and should destroy all copies of them. Macquarie Bank does not guarantee the integrity of any emails or any attached files. The views or opinions expressed are the author's own and may not reflect the views or opinions of Macquarie Bank. |