Jump to content
  • Advertisement

CraZeE

Member
  • Content Count

    349
  • Joined

  • Last visited

Everything posted by CraZeE

  1. CraZeE

    A program of particle fire

    i'm running on a Radeon Mobility X300 - 72fps Just curious, how ARE you doing your rendering for the particles? I'm asking because I've worked on a particle engine a few years back and it gives a decent 100+ fps on my old geforce4 running on a pentium 2 :O Unless you're doing something unique, i believe you shud be getting much better framerates for what (seems) like a simple implementation. Enlighten us :)
  2. by large worlds, i'm assuming you're worried bout particles in the distance OR huge number of systems across different locations in the world. they are somewhat 2 separate problems that I would treat differently. 1. as distance increases, the detail level will not be perceptible. i would recommend performing some form of LOD to minimize processing. This applie to both the aforementioned scenarios. 2. precision may not be an issue unless you're performing per-particle transformation at world coordinates. Excluding live systems in immediate vicinity of visible area, systems located far away could be rendered to texture. That way, precision is not an issue, and u just need to render the texture ala imposters on the world.
  3. just came off the top of my head... IF you're having a problem of accessing functions in a namespace due to declaration oerder, then it is NOT a namespace issue. Functions, in general, are required to be at least 'declared' before using. If your code calls a function (in a namespace) and the function prototype hasnt been declared at the point of using it, then its gonna be a standard link error. Either way, its not the namespace thats the problem, its the order you declare the function in the namespace with respect to the function caller. Hope that made sense.
  4. namespace forward declaration? honestly havent heard of this, nor the need for it. Namespaces are special compared to classes. Class/type declarations must me complete with respect to file. As in: // In A.h class A { // class contents... void firstFunction(void); }; You can't have this after you do the above: // In A-2.h class A { // class content 'extention' void secondFunction(void); }; The above just wont work and compiler will kick ur a** about type redefinition, etc. Namespaces dont have this limitation actually. You can open and close a namespace (almost) anytime and anywhere, each content being universally appended into ONE in the background. So why do you have this namespace issue again?
  5. CraZeE

    Confusion: Libraries, .lib and .DLL

    whoa~ reading up on multithreading is useful but it is overkill for your situation. Here's the breakdown as best as i can explain. Most programs are linked to a C Runtime Library (CRT). The runtime library itself exists in a few forms: 1. Single Threaded 2. Single Threaded Debug 3. Multi Threaded 4. Multi Threaded Debug 5. Multi Threaded DLL 6. Multi Threaded DLL debug Now, without getting to much into detail yet of each variant, here's the important news: You *must* ensure that all components in a project are all compiled using the same runtime library. So if you make an EXE project that links to a LIB file and a DLL (jsut for example), you must make sure that they're all configured to link to the same type of runtime library. In the case of bundled or 3rd party LIB/DLLs, they usually provide different variants of their libraries OR they should tell you explicitly which type their library is linked to. To change this setting, check the project properties. Select C/CC, Code Generation -> Runtime Library dropdown. As to what each variant does, that's a bit more complicated. The easiest to understand is the Debug/Non-debug runtimes. When you're compiling into a debug configuration, you should use the Debug runtime. Easy! Why? Coz the debug runtimes will have debug symbols and information that permit you to do your code debugging properly. As for multi/single threaded, that I cant really explain easily. However, I can help on the Multithreaded vs Multithreaded DLL. The DLL version will generate smaller output files, but the target system must have the runtime libraries installed. Which means, if you create an installer for your app, you wanna make sure that: 1. You check that the user has the runtimes installed 2. If not, you bundle the runtime DLL with your app Point 2 makes its a moot point to use DLLs, especially when developing on .NET 2003 and above coz their runtime files may not be the same as the defaults bundled in the OS. If you wanna avoid all this 'DLL not found' errors, then link to the standard multithreaded runtime. You get a larger file output, but chances are it'll be smaller than bundling the runtimes with your installer :)
  6. how do you handle motion/path updates for particles? is it hardcoded? if it is, i would recommend implementing some way to provide the particle system with a 'behavior' function. that way, particle behavior is not linked to the system in general although such a behavior can also be replicated if done this way. This would be handy coz you can just swap the 'behavior' and the particle/system will adapt to it. Imagine a fire system in a windless environment, then when you introduce wind, the behavior is updated by just providing a new function. the same can be applied to any modifieable element of the system. I created a system once that had pluggable motion and emission area. It promotes extensibility to the system, though it seriously depends on how much extensibility you'd like to have.
  7. generally speaking, casting to a base class is always possible... but you're trying to cast a base class to a derived class. Haven't actually done that myself, but it seems logically valid that it would fail. casting to base class is valid, however, because the base class in its entirety is a part of the derived class. casting to a derived class however is not recommended (if not illegal in the first place ). Imagine: class A { // Simplified for brevity public: virtual int DoSomething(); }; class B: public A { public: virtual int DoSomething(); virtual int DoSomethingElse(); }; // USAGE possiblities? A* toBase = dynamic_cast<A*>( new B() ); toBase->DoSomething(); //toBase->DoSomethingElse(); <-- This will give compile time error B* toDerived = dynamic_cast<B*>( new A() ); // Don't think this will work // Why? Because the following would cause a runtime error if the above // succeeded. A pointer to B will allow access to a defined 'DoSomethingElse' // which is non-existent in the original class-A toDerived->DoSomethingElse(); not sure if my explanation helps, but thats my 2cents.
  8. yes, as Muncher puts it, most system APi callbacks have at least one void* parameter that can be used for arbitrary data. In most cases, especially in an object-based application, you can (and should) piggyback the 'this' into the parameter. just keep note of this limitation and/or solution whem making your own callback mechanisms in the future. You can apply this same logic into designing your callbacks ;)
  9. Quote:I do feel that the VS2005 compiler is extremely picky. On VC6 and any other compiler and IDE combo, I could have: MessageBox(NULL,"Hello","Hello",MB_OK); On VC2005, MessageBox(NULL,L"Hello",L"Hello",MB_OK); That L parameter came out of nowhere. It's annoying, especially if you've never used the compiler and don't know it's even supposed to be there. erm.. i think you need to know your IDE more before comparing it with others. The 'L' parameter has been around for a LONG time and not just in VS2005. I've seen it in .Net and .Net2k3 (cant confirm for vc6). What it stands for has already been explained by JohnB. Quote:Is it just me or was that a blank message...? The first parameter is a handle to the owner window. So the Messagebox command specified in the example has a title of 'Hello' and content of 'Hello' with an OK button, and it is linked to the desktop (i think).
  10. u didnt mention the OS you're running on so its a gamble. If u're using windows (highly likely), then there's a collection of functions on console formatting. However, these use the Win32 API and might be a bit complicated at first. For exact details, check out MSDN.
  11. CraZeE

    Operator overloading class members

    out of curiosity, wats the reason for the operators to be private? If you're gonna use them from outside of the class, then chances are you won't have permission to access private methods.
  12. CraZeE

    creating a DLL

    i'm not very used to anything besides a standard DLL (so COM is not my expertise). So here are wat i (hopefully) know on DLLs: Pros ==== 1. Dynamic loading (duh!) - Since the client app and the DLL are not linked (though possible) at compile-time, you can update the DLL and/or client application without recompiling the other. 2. Reuse - You can more easily integrate a DLL into another project, avoiding linkage issues and compile settings to support the DLL. 3. Can share a library between incompatible languages (bridge Delphi<->C++<->VB etc) Cons ==== 1. VERY tricky to handle passing of class objects between DLL and client app 2. Requires a well defined interface to ensure client code does not get affected by DLL updates 3. Calling convention issues must be handled wisely 4. Harder to debug from the client-app's point of view Erm.. feel free to add as you find more.
  13. yes, include guards should be in the header. assuming that's what you wanna achieve. but on a second note, no you CANT define a preprocessor within another preprocessor. meaning you cant: #define #ifndef WHATEVER\ #define WHATEVER\ #endif It just wont work.. or at least I neva got it to work :P
  14. CraZeE

    Sprite without glOrtho

    er.. u mentioned 'having them face the camera' but that would require rotation. So how did that work if this other rotation doesn't? anyway, it looks like either a transformation order or transform state problem. Some existing code snippet would be handy to debug though, coz right now its just a random guess.
  15. CraZeE

    Silly visual C++ 2003 problem

    unfortunately, errors are reported by the compiler with a line reference. Since the compiler does not run at realtime, the line info doesnt get updated at realtime. Its a minor annoyance, but you'll get used to it. I don't think it can be fixed (easily) because that would require constant validation of code at runtime, and VS.NEt2003 can be quite slow as it is.
  16. CraZeE

    OpenGL Particles in a 3D World

    oh.. truly sorry bout that Diablo. as deavik said, use glPushMatrix() before the tranformation in the particle render, and glPopMatrix right after you draw the particle. all this is in the render function itself. I forgot to add those lines in the sample fix i gave you, though I did use them myself *slaps forehead* anyway, about push and pop... its just a stack (read a book on data structures). Transforms in OpenGL (and most rendering API) use matrices to store the transform info. but there are time you want to 'bookmark' the current matrix so that you can do changes and not worry bout reseting it after that. for instance, u might want to do 2 transforms, then do a third, before reverting to the state prior to the 3rd. You can do the difficult way: 1. transform 1 2. transform 2 3. transform 3 4. clear transform (load identity) 5. transform 1 6. transform 2 this is long winded. wat the push/pop matrix stack does is store the current setting. the above can be done via push/pop as: 1. transform 1 2. transform 2 3. push matrix (glPushMatrix) <-- remember step 1 and 2 4. transform 3 <-- temporarily do this... 5. pop matrix (glPopMatrix) <-- reset back to original (discard transform 3) it might look like saving only one step in the above example, but when u start having complex transformations, push/pop are lifesavers.
  17. CraZeE

    OpenGL Particles in a 3D World

    ok, found ur problem. it is related to ur order of transformation.. more precisely ur reversal of transofrmation. take note of opengl tranformation order (example:) 1. translate 1 2. rotate 1 3. rotate 2 Opengl will process this in reverse order. Meaning, it'll rotate1, rotate2 then translate1. In your example, u want rotation to occur relative to ORIGIN, before u translate to the final particle position. Although your code doesn't show this, this is wat actually happened (in opengl order): 1. rev rotatey 2. rev rotatex 3. translate to position this causes all ur particles to be positioned FIRST, then rotated. Hence their rotation occurs relative to a now-offset origin. What you really want is the particles to rotate in their center BEFORE u translate. Eg: 1. translate to position 2. rev rotatex 3. rev rotatey unfortunately, the way your code is structured... u need to modify a bit. Not sure if this is the best way, but this works for me (quick hack) // LESSON10.cpp //undo rotations so particles are perpendicular to viewer // I disabled these two lines //glRotatef(-sceneroty,0,1.0f,0); //glRotatef(-lookupdown,1.0f,0,0); // Added depth mask AND i passed the inverse rotation values into // the particle itself glDepthMask(FALSE); //render particles individually myPart[0]->render(-lookupdown, -sceneroty); myPart[1]->render(-lookupdown, -sceneroty); myPart[2]->render(-lookupdown, -sceneroty); myPart[3]->render(-lookupdown, -sceneroty); myPart[4]->render(-lookupdown, -sceneroty); glDepthMask(TRUE); // JTD_Particle::render( float rotx, float roty ) // Added new transformation code here glTranslatef(x, y, z); // Moves particle to correct position glRotatef(rotx, 1.0f, 0.0f, 0.0f); // Reverses the camera rotation glRotatef(roty, 0.0f, 1.0f, 0.0f); glBegin(GL_TRIANGLE_STRIP); // NOTE: All x,y,z references have been omitted and done by transform glTexCoord2d(1,1); glVertex3f(+0.05f,+0.05f,0); // Top Right glTexCoord2d(0,1); glVertex3f(-0.05f,+0.05f,0); // Top Left glTexCoord2d(1,0); glVertex3f(+0.05f,-0.05f,0); // Bottom Right glTexCoord2d(0,0); glVertex3f(-0.05f,-0.05f,0); // Bottom Left glEnd(); thats quite a bit of change. this is just to get it to look correct, though you shud plan ur changes in the future to avoid hacks like this. order of transformation is tricky and (in your case), you cant fully do it from outside of the particle logic. And remember, always compose your objects relative to their origin. Particles are usually at their center, but other elements may have it differently. Think of it as that the origin is ALWAYS your point of operation. If something is intentionally rendered offset from origin WITHOUT translation, then there better be a reason for it.
  18. CraZeE

    OpenGL Particles in a 3D World

    btw, just fyi... enabling/disabling z-buffer is done as: glEnable(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST) this completely stops performing Z-tests altogether. For the solution above, you want to keep the existing Z-buffer data intact, but dont want to add additional changes. This way, the particles will still be occluded by nearer objects, but they wont overlap each other ;) To enable/disable Z-write, you do: glDepthMask(TRUE)/glDepthMask(FALSE) default: TRUE.
  19. CraZeE

    OpenGL Particles in a 3D World

    i can hint on the z-sorting part. actual z-sorting requires a good datastructure that automates object sorting; something i doubt you will be looking into just yet. Instead, for particles, you can follow this trick: 1. render all OPAQUE (non transparent, non-particle) objects in the scene first 2. disable Z-write (which is NOT the same as disabling Z-buffer entirely) 3. render you particles 4. re-enable Z-write For overlapping particles itself, you will need to work on the blending state. Play around with the blend_src and blend_dest flags for the alpha processing to find a combination that suits. Havent touched OGL in a while, so i cant remember the constants straight out of my head. As for your 'moving' particles, it looks like some incorrect reversal of transformation. I havent looked at the code yet, but chances are you are not rotating the particles relative to their center, instead you're doing it from some other point of reference. Will get back to you when and if i have finished looking at ur source. chiaoz.
  20. CraZeE

    Pure Virtual functions

    pure virtual functions (pvf for short.. i'm lazy) are useful for definining interfaces. Its the closest substitute C++ has to Java's 'interface' and C#'s 'abstract class' keyword. You get the following differences from a standard virtual function: 1. ONE pvf is all it takes to make a class abstract/non-instantiable 2. pvf MUST be implemented in derived classes to make them instantiable. Derived classes are also abstract classes unless an implementation is provided for all inherited pvf. in many C++ applications, object management is important. One way to track objects is to store all your objects in a list. However, if u take an array (for instance), an array is single-typed. An integer array only KEEPS integers and refuses to accept anything else. HOw then? Thats where pure virtuals come in handy. You can keep an array of pointers to the abstract class and automagically you can store ANY derived class within that array. So how is that different from a standard virtual function?... Not much, aside from the fact that it enforces that all types of a certain abstract base class WILL implement a custom behavior. Virtual functions allow you to fallback on a default implementation if you choose to do so.
  21. CraZeE

    struct within a struct question.

    your syntax for accessing the struct-in-a-struct is correct. However, when using at runtime, ensure that the struct-in-a-struct is allocated. You're using a pointer, so an allocation is required before u can use that second level of indirection.
  22. CraZeE

    C++ Validation Tools?

    afaik, if u use pure virtual functions.. a derived class MUST provide an implementation, else the compiler will give you an error. You theoretically never get to a runtime error, unless the implementation itself is erroneous. That's a whole different problem altogether :P
  23. CraZeE

    CALLBACK TimerProc

    u could try using Sleep in ur home-grown 'timer' loop, but Sleep suspends ur active thread. In a GUI application, that would mean even your GUI will not update until the Sleep duration is over. Multi-threading is needed for this to work elegantly. Another option is to use SetTimer (i think thats wat its called). Check out MSDN for a reference on setting up system level timers that work via callbacks. It might be a more elegant and compatible way to get around this issue.
  24. CraZeE

    OpenGL FireBlade Particle Engine

    i'm getting a DLL linking error in a language i can't read :P. The rar doesnt seem to include some necessary DLL's; either that or i'm sorely forgetting something. how? how?
  25. billboarding for text is probably not worth the trouble, especially if there's gonna be a lot. And working with text in 3d *may* not be wat you want because there are issues with scaling based on depth. Unless you intend text in the far background to be small and indecipherable, i believe you'd want Torment-style text that are a fixed font size irrespective of location and depth of the character. (sorry for bad example, couldnt think of a real 3D game with text right now). just unproject the character position from 3d into screen coordinates to get the x-y coordinates, and render the text as needed in (wat i assume) is ortho mode for font rendering.
  • 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!