Browse Source

Platform: ability to negotiate context in {Glut,NaCl,Sdl2}Application.

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
bda6202d42
  1. 24
      doc/platform.dox
  2. 17
      src/Platform/GlutApplication.cpp
  3. 19
      src/Platform/GlutApplication.h
  4. 27
      src/Platform/NaClApplication.cpp
  5. 3
      src/Platform/NaClApplication.h
  6. 27
      src/Platform/Sdl2Application.cpp
  7. 5
      src/Platform/Sdl2Application.h

24
doc/platform.dox

@ -169,5 +169,29 @@ MyApplication::MyApplication(int& argc, char** argv): Platform::GlutApplication(
} }
@endcode @endcode
The configuration passed to constructor and @ref GlutApplication::createContext() "createContext()"
is automaticall deleted afterwards and if the context creation fails, the
application exits. However, it is also possible to negotiate the context using
@ref GlutApplication::tryCreateContext() "tryCreateContext()". The major
difference is that this function returns `false` instead of exiting and it
doesn't delete the configuration afterwards so you can reuse it. You can for
example try enabling MSAA and if the context creation fails, fall back to
no-AA rendering:
@code
MyApplication::MyApplication(int& argc, char** argv): Platform::GlutApplication(argc, argv, nullptr) {
// ...
auto conf = new Configuration;
conf->setTitle("My Application")
->setSampleCount(16);
if(!tryCreateContext(conf))
createContext(conf->setSampleCount(0));
else delete conf;
// ...
}
@endcode
*/ */
}} }}

17
src/Platform/GlutApplication.cpp

@ -47,12 +47,20 @@ void GlutApplication::initialize(int& argc, char** argv) {
/* Init GLUT */ /* Init GLUT */
glutInit(&argc, argv); glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
} }
void GlutApplication::createContext(Configuration* configuration) { void GlutApplication::createContext(Configuration* configuration) {
CORRADE_ASSERT(!c, "GlutApplication::createContext(): context already created", ); if(!tryCreateContext(configuration)) {
Error() << "Platform::GlutApplication::createContext(): cannot create context";
delete configuration;
std::exit(1);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); } else delete configuration;
}
bool GlutApplication::tryCreateContext(Configuration* configuration) {
CORRADE_ASSERT(!c, "Platform::GlutApplication::tryCreateContext(): context already created", false);
unsigned int flags = GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL; unsigned int flags = GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL;
@ -61,7 +69,8 @@ void GlutApplication::createContext(Configuration* configuration) {
glutInitDisplayMode(flags); glutInitDisplayMode(flags);
glutInitWindowSize(configuration->size().x(), configuration->size().y()); glutInitWindowSize(configuration->size().x(), configuration->size().y());
glutCreateWindow(configuration->title().c_str()); if(!glutCreateWindow(configuration->title().c_str()))
return false;
glutReshapeFunc(staticViewportEvent); glutReshapeFunc(staticViewportEvent);
glutSpecialFunc(staticKeyEvent); glutSpecialFunc(staticKeyEvent);
glutMouseFunc(staticMouseEvent); glutMouseFunc(staticMouseEvent);
@ -71,7 +80,7 @@ void GlutApplication::createContext(Configuration* configuration) {
ExtensionWrangler::initialize(); ExtensionWrangler::initialize();
c = new Context; c = new Context;
delete configuration; return true;
} }
GlutApplication::~GlutApplication() { GlutApplication::~GlutApplication() {

19
src/Platform/GlutApplication.h

@ -81,7 +81,8 @@ class GlutApplication {
* @param arguments Application arguments * @param arguments Application arguments
* *
* Creates application with default configuration. See Configuration * Creates application with default configuration. See Configuration
* for more information. * for more information. The program exits if the context cannot be
* created, see tryCreateContext() for an alternative.
*/ */
explicit GlutApplication(const Arguments& arguments); explicit GlutApplication(const Arguments& arguments);
@ -92,7 +93,8 @@ class GlutApplication {
* *
* The @p configuration is deleted afterwards. If `nullptr` is passed * The @p configuration is deleted afterwards. If `nullptr` is passed
* as @p configuration, the context is not created and must be created * as @p configuration, the context is not created and must be created
* with createContext(). * with createContext(). The program exits if the context cannot be
* created, see tryCreateContext() for an alternative.
*/ */
explicit GlutApplication(const Arguments& arguments, Configuration* configuration); explicit GlutApplication(const Arguments& arguments, Configuration* configuration);
@ -112,10 +114,21 @@ class GlutApplication {
* @brief Create context with given configuration * @brief Create context with given configuration
* *
* The @p configuration is deleted afterwards. Must be called if and * The @p configuration is deleted afterwards. Must be called if and
* only if the context wasn't created by the constructor itself. * only if the context wasn't created by the constructor itself. The
* program exits if the context cannot be created, see tryCreateContext()
* for an alternative.
*/ */
void createContext(Configuration* configuration); void createContext(Configuration* configuration);
/**
* @brief Try to create context with given configuration
*
* Unlike createContext() the @p configuration is *not* deleted
* afterwards. Returns `false` if the context cannot be created, `true`
* otherwise.
*/
bool tryCreateContext(Configuration* configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** /**

27
src/Platform/NaClApplication.cpp

@ -36,12 +36,21 @@ NaClApplication::NaClApplication(const Arguments& arguments): Instance(arguments
createContext(new Configuration); createContext(new Configuration);
} }
NaClApplication::NaClApplication(const Arguments& arguments, Configuration* configuration): Instance(arguments), Graphics3DClient(this), MouseLock(this), c(nullptr) { NaClApplication::NaClApplication(const Arguments& arguments, Configuration* configuration): Instance(arguments), Graphics3DClient(this), MouseLock(this), graphics(nullptr), fullscreen(nullptr), c(nullptr) {
if(configuration) createContext(configuration); if(configuration) createContext(configuration);
} }
void NaClApplication::createContext(NaClApplication::Configuration* configuration) { void NaClApplication::createContext(Configuration* configuration) {
CORRADE_ASSERT(!c, "NaClApplication::createContext(): context already created", ); if(!tryCreateContext(configuration)) {
Error() << "Platform::NaClApplication::createContext(): cannot create context";
delete configuration;
std::exit(1);
} else delete configuration;
}
bool NaClApplication::tryCreateContext(Configuration* configuration) {
CORRADE_ASSERT(!c, "Platform::NaClApplication::tryCreateContext(): context already created", false);
viewportSize = configuration->size(); viewportSize = configuration->size();
@ -58,11 +67,12 @@ void NaClApplication::createContext(NaClApplication::Configuration* configuratio
graphics = new pp::Graphics3D(this, attributes); graphics = new pp::Graphics3D(this, attributes);
if(graphics->is_null()) { if(graphics->is_null()) {
Error() << "Platform::NaClApplication::NaClApplication(): cannot create graphics"; delete graphics;
std::exit(1); graphics = nullptr;
return false;
} }
if(!BindGraphics(*graphics)) { if(!BindGraphics(*graphics)) {
Error() << "Platform::NaClApplication::NaClApplication(): cannot bind graphics"; Error() << "Platform::NaClApplication::tryCreateContext(): cannot bind graphics";
std::exit(1); std::exit(1);
} }
@ -70,8 +80,6 @@ void NaClApplication::createContext(NaClApplication::Configuration* configuratio
glSetCurrentContextPPAPI(graphics->pp_resource()); glSetCurrentContextPPAPI(graphics->pp_resource());
c = new Context;
/* Enable input handling for mouse and keyboard */ /* Enable input handling for mouse and keyboard */
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE|PP_INPUTEVENT_CLASS_WHEEL); RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE|PP_INPUTEVENT_CLASS_WHEEL);
RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
@ -79,7 +87,8 @@ void NaClApplication::createContext(NaClApplication::Configuration* configuratio
/* Make sure viewportEvent() is called for first time */ /* Make sure viewportEvent() is called for first time */
flags |= Flag::ViewportUpdated; flags |= Flag::ViewportUpdated;
delete configuration; c = new Context;
return true;
} }
NaClApplication::~NaClApplication() { NaClApplication::~NaClApplication() {

3
src/Platform/NaClApplication.h

@ -121,6 +121,9 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
/** @copydoc GlutApplication::createContext() */ /** @copydoc GlutApplication::createContext() */
void createContext(Configuration* configuration); void createContext(Configuration* configuration);
/** @copydoc GlutApplication::tryCreateContext() */
bool tryCreateContext(Configuration* configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** @copydoc GlutApplication::viewportEvent() */ /** @copydoc GlutApplication::viewportEvent() */

27
src/Platform/Sdl2Application.cpp

@ -50,20 +50,33 @@ Sdl2Application::InputEvent::Modifiers fixedModifiers(Uint16 mod) {
} }
Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) { Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) {
initialize();
createContext(new Configuration); createContext(new Configuration);
} }
Sdl2Application::Sdl2Application(const Arguments&, Configuration* configuration): context(nullptr), flags(Flag::Redraw) { Sdl2Application::Sdl2Application(const Arguments&, Configuration* configuration): context(nullptr), flags(Flag::Redraw) {
initialize();
if(configuration) createContext(configuration); if(configuration) createContext(configuration);
} }
void Sdl2Application::createContext(Configuration* configuration) { void Sdl2Application::initialize() {
CORRADE_ASSERT(!context, "Sdl2Application::createContext(): context already created", );
if(SDL_Init(SDL_INIT_VIDEO) < 0) { if(SDL_Init(SDL_INIT_VIDEO) < 0) {
Error() << "Cannot initialize SDL."; Error() << "Cannot initialize SDL.";
std::exit(1); std::exit(1);
} }
}
void Sdl2Application::createContext(Configuration* configuration) {
if(!tryCreateContext(configuration)) {
Error() << "Platform::Sdl2Application::createContext(): cannot create context:" << SDL_GetError();
delete configuration;
std::exit(1);
} else delete configuration;
}
bool Sdl2Application::tryCreateContext(Configuration* configuration) {
CORRADE_ASSERT(!context, "Platform::Sdl2Application::tryCreateContext(): context already created", false);
/* Enable double buffering and 24bt depth buffer */ /* Enable double buffering and 24bt depth buffer */
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
@ -81,7 +94,11 @@ void Sdl2Application::createContext(Configuration* configuration) {
std::exit(2); std::exit(2);
} }
context = SDL_GL_CreateContext(window); if(!(context = SDL_GL_CreateContext(window))) {
SDL_DestroyWindow(window);
window = nullptr;
return false;
}
/* This must be enabled, otherwise (on my NVidia) it crashes when creating /* This must be enabled, otherwise (on my NVidia) it crashes when creating
VAO. WTF. */ VAO. WTF. */
@ -96,7 +113,7 @@ void Sdl2Application::createContext(Configuration* configuration) {
SDL_PushEvent(sizeEvent); SDL_PushEvent(sizeEvent);
c = new Context; c = new Context;
delete configuration; return true;
} }
Sdl2Application::~Sdl2Application() { Sdl2Application::~Sdl2Application() {

5
src/Platform/Sdl2Application.h

@ -95,6 +95,9 @@ class Sdl2Application {
/** @copydoc GlutApplication::createContext() */ /** @copydoc GlutApplication::createContext() */
void createContext(Configuration* configuration); void createContext(Configuration* configuration);
/** @copydoc GlutApplication::tryCreateContext() */
bool tryCreateContext(Configuration* configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** @copydoc GlutApplication::viewportEvent() */ /** @copydoc GlutApplication::viewportEvent() */
@ -167,6 +170,8 @@ class Sdl2Application {
typedef Corrade::Containers::EnumSet<Flag, UnsignedByte> Flags; typedef Corrade::Containers::EnumSet<Flag, UnsignedByte> Flags;
CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) CORRADE_ENUMSET_FRIEND_OPERATORS(Flags)
void initialize();
SDL_Window* window; SDL_Window* window;
SDL_GLContext context; SDL_GLContext context;

Loading…
Cancel
Save