I am planning on making a 3D scene editor app using c++ and open gl. And I have to keep track of the current loaded project and different scenes it contains also the user preferences and other things. The best solution I can think of is to wrap them in a context class which will be a singleton. Is there a better way of doing this?
Not a good idea, probably. One reason is technical. The actual OpenGL context's lifetime is limited and is far shorter than app itself, usually related to surface you're outputting to. You would need to initialize context after your visualizing window is ready and de-initialize it before window is gone. Trying to do so when window gone may end to undefined behaviour depending on platform. In some cases you might need several contexts.
Another reason is, it doesn't look like proper separation of responsibilities. User settings aren't part of context, but some may affect only a single render pass (out of plural). You likely would have Preferences, Renderer which would be an interface to Context manager, Geometries, Textures (or materials) separate, an Scene Manager as well (think of scene tree in Blender or DAZ studio, each item in scene can have separate user settings, regarding how to visualize them).
Related
Goal:
In my application I'm trying to implement multiple viewports to allow the user to view a scene from multiple perspectives. Each of my viewports need to be able to switch between wireframe, shaded, lighting, etc. I can currently render from different perspectives in each viewport, but I have issues.
Problem:
When I try to set various settings such as glPolygonMode() or qglClearColor() within any viewport, these settings only seem to apply to a single viewport, generally the very last viewport that was created. This isn't a signals/slots issue, since these connections are handled internally within each widget, and cannot be mixed up between widgets.
Attempts at solving the problem:
Since I'm using Qt as the library for managing all UI related things, I'm sure there are a lot of things Qt has taken care of for creating and setting up each OpenGL instance for me, so there may be things that I'm overlooking that I don't know about.
I've checked the constructors available for QGLWidgets, and seen that a QGLWidget can take in another QGLWidget as a "sharedwidget", and also a QGLContext object.
I currently use the "sharedwidget" route, because without it for some reason I can't get textures to bind for more than 1 viewport. However, this doesn't solve the problem of not being able to switch between wireframe or shaded in each QGLWidget instance.
I've also tried the QGLContext route. By default each QGLWidget
creates a new context anyways, but when trying to assign new ones or
sharing a single Context between all of them I would just get issues
with my shaders not linking (I believe the initializeGL slot is not
getting called in that case), leading to a crash every time a context is shared to another QGLWidget:
ASSERT: "QOpenGLFunctions::isInitialized(d_ptr)" in file
c:\work\build\qt5_workdir\w\s\qtbase\include\qtgui../../src/gui/opengl/qopenglfunctions.h,
line 2018
Details:
Currently, my application takes on the following hierarchy:
Application
Window
ViewportWidget [dynamic array]
QGLWidget (custom variation)
The only thing each QGLWidget needs to share is the pointer to the current "map", so that each can render the map based on whatever settings are set within that particular widget's instance.
I perform the following functions for setting up a viewport:
I create a new ViewportWidget, parent it and add it to the appropriate frame and Layout. If the viewport isn't the first one, then it also passes the very first QGLWidget to be used as a "sharedwidget"
The viewport then creates a QGLFormat with a swap interval of 1, and passes said format into the constructor of a new QGLWidget.
I then am forced to call "makeCurrent()" for the viewport, otherwise I crash with the reason:
ASSERT: "false" in file qgl.cpp, line 122
Is it even possible to have separate QGLWidgets with different "polygonMode"'s, or "clearColor"'s? I'm just worried that I'm doing something wrong that will bite me in the butt later on, which I want to avoid.
I recently asked a question about how to get around sharing issues with vertex array objects and frame buffer objects across multiple contexts, I was then convinced that using multiple contexts just caused more headaches then solutions.
I am using Qt and currently my setup is that I have one invisible QGLWidget which I then use in the constructor of my visible QGLWidget's in order to share resources, this works great accept that I cannot share certain things across the contexts.
I wish to find a solution where I am able to use a single context to render all of my different widget's, this question refers to using the QGLWidget constructor where you pass in the QGLContext you desire to be shared, however this does not seem to use one common context, but instead set the context to be used by one QGLWidget, when you try to use it on a second widget, a qWarning is called which informs you that the QGLContext must refer to the widget you are passing it to.
The goal of my application is to have 2 seperate GUI's which render different scenes, yet share the same context. Currently I have a 'World' editor which edits a scene and saves it to a file to be used in my game engine, and I also have a 'Material' editor which allows you to graphically edit a material similar to UDK's Material editor, there is a preview window which utilizes OpenGL.
Ideally I would like to keep my current design of having one unified game editor which is navigable by tabs, rather than having separate programs for each part of the editor.
The only thing that seemed like it was a decent solution was using the QGraphicsView and setting a QGLWidget as the viewport, however this does not seem to work at all. I can render basic primitives, however anything more and it falls apart.
Does anyone have experience dealing with this issue of multiple OpenGL Widgets, and if so could you explain the process you took to achieve your goal?
I don't quite understand why you are having so much trouble, I'm building a CAD-like app so share a few contexts, like this:
I use an application-wide hidden QGLWidget as a member of my main window class, this is the context shaders are loaded in.
For each document window, the window class has a hidden QGLWidget member, this is the context geometry is loaded in. The shader context is used as the 'shared' widget for it, allowing documents access to the application wide shaders.
Each of the 5 viewports in each document window is a visible QGLWidget, this is where the actual rendering takes place. The document window geometry QGLWidget is used as the 'shared' widget, so the viewports have access to the document-wide geometry data and the application-wide shaders.
The shared widget parameter allows you to create an 'inheritance' tree of contexts, every context has access to it's own and all it's ancestors data (but not it's childrens or siblings).
I've been developing a 2d RPG based on the LWJGL alongside with Java 1.6 for 3 months now. My next goal is to write all of the non-game-ish stuff. This includes menus, text input boxes, buttons and things like the inventory and character information screens. As I am a Computer Engineering student, I'm trying to write everything on my own (except, of course, for the OpenGL part of the LWJGL) so that I "test" myself on the writing of a simple 2d game engine.
I know that making such things from scratch requires basically mapping textures to quads (like the buttons), writing stuff on them and testing mouse/keyboard events which trigger other events inside the code.
The doubt I have is: should I use VBO's (as I'm using for the actual game rendering) or Immediate Mode when rendering such elements? I don't really know if Immediate Mode would be such a drop on performance. Another point is: do the interface elements have to be updated as fast as the game itself? I don't think so, because nothing is actually moving... Are actual games made like that?
Immediate Mode is more straightforward for the task, you would not need to take care about caching and controls composition/batching. Performance dropoff is not that big, unless you render a lot of text (thousands of letters) with each glyph in a separate glBegin..glEnd. If you don't use VBO anywhere else I would recommend trying it out for text output and doing everything else in easier Immediate Mode.
GUI elements might not change as often as game state does, but there's a catch - you could need to update them each time there's a cursor interaction (e.g. button gets OnMouseOver event and needs to be rendered with a highlight). These kind of events may happen very frequently, so thats why rendering may be needed at a full speed.
I am at the start of my cocos2d adventure, and have some ideological questions to ask. I am making a small space-shooter game, am I right to use the following class structure?
Scene
Background Layer
Infinite parallax background
Game Layer
Space ships
Bullets
Control Layer
Joystick
Buttons
and a followup question — what is the best practice in accessing objects from other layers? For example, when the joystick is updated, it must rotate the space ship and move the background. Both of these are in other layers. Is there some recommended way to go about this or should I simply get the desired objects by Tag and operate on them?
Cocos is a big singleton-based system, which may not appeal to some developers but is often used in Cocos apps and is the fundamental architecture of the framework. If you have one main scene and many subsequent layers added to that scene, and you want controls from one layer to affect sprites or logic on other layers, there really is nothing wrong with making your main scene a singleton and sending the information from the joystick layer back to the scene to handle for manipulating other layers or sprites. I do this all the the time and this technique is used in countless Cocos tutorials in books and online, so you can feel that you aren't breaking too many rules if you do it this way (and it's also quite easy to do).
If you instead choose to use pointers in one layer to send data to other layers, this can get you into a lot of trouble since one node should never own another node that it doesn't have a specific parent-child relationship with. Doing so can cause crashes and problems with the native Cocos cleanup methods when you remove scenes later, and potentially leak memory. You could use a weak reference in such a case instead, but that is still dependent on one layer expecting another layer to always be around, which may not be the case.
Sending data back to the main game scene to then dispatch and use accordingly is really efficient.
This seems like a perfectly reasonable way to arrange your objects, this is a method I use.
For accessing objects, I would keep an explicit reference to the object as a member variable and use it directly. (Using tags isn't a bad option, I just find it can get a little messy).
#interface Class1 : NSObject
{
CCLayer *backgroundLayer;
CCLayer *contentLayer;
CCLayer *hudLayer;
CCSprite *objectIMayNeedToUseOnBackgroundLayer;
CCNode *objectIMayNeedToUseOnContentLayer;
}
Regarding tags, one method I use to make sure the tag numbers I'm assigning are unique is define an enum as follows:
typedef enum
{
kTag_BackgroundLayer = 100,
kTag_BackgroundImage,
kTag_GameLayer = 200,
kTag_BadGuy,
kTag_GoodGuy,
kTag_Obstacle,
kTag_ControlLayer = 300
kTag_Joystick,
kTag_Buttons
};
Most times I'll also just set zOrder and tag properties of CCNodes (i.e. CCSprites, CCLabelTTFs, etc.) the same, so you can actually use the enum to define your zOrder, too.
I am about to start a text-rendering window in MFC. Given that the text-rendering window will allow fonts of differing style (and each window can have a different font), I've been thinking about the management of fonts.
Would it make sense to create some kind of a font manager? I was thinking that each time a font is required, the renderer would pass the desired LOGFONT to the manager. If a CFont existed, it would be returned and if not, created. This font manager would be global in the system.
Is this overkill? Does Windows do this kind of thing under-the-hood meaning it is totally un-necessary from an application perspective?
One could also say the same for brushes and pens of a particular colour. Is it faster to store them in a manager of some sort once one is created? E.g, if I create a solid mauve brush, should another window that wants mauve request the existing brush?
Also, I'm guessing that if I load an image on disk to blit, that if two separate windows load the same image from disk, I'll have two images - so these are good candidates to cache (by filename, perhaps?)
Different windows versions have done differing amounts of caching of these things.
My advice hinges on two things:
Don't optimize prematurely. If you can see a possible need to optimize in the future, go ahead and ensure that you architect it such that Fonts are retrieved from a font manager. But, until there is a provable performance deficit, don't bother implementing the cache.
Measure. Make a test case program that creates and destroys hundreds of differently styles fonts and measure how it scales in performance.
I once spent a long time writing a multi threaded renderer. Only to find that, because the GDI drivers serialize access to the hardware anyway, I got zero benefit.
This is an okay strategy for fonts, the Windows font mapper isn't that cheap and the number of fonts that a typical program uses is finite. But not for brushes and pens, they are dirt-cheap so just create and destroy them on the fly.
The ultimate endorsement for this strategy comes from Microsoft's own code, Winforms does this. Beware that caching creates a new problem, you have to invalidate the cache when the user changes system settings. System colors, DPI, that sort of thing. You have to listen for WM_SETTINGCHANGE in a toplevel window.
Windows has/had (it's been a while since I programmed for Windows) had various GetStockXXX functions, such as GetStockFont(). I had a quick Google but no obvious MSDN docs came up.
Edit: see GetStockObject(): http://msdn.microsoft.com/en-us/library/dd144925%28VS.85%29.aspx