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
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 */
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
}
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;
@ -61,7 +69,8 @@ void GlutApplication::createContext(Configuration* configuration) {
glutInitDisplayMode(flags);
glutInitWindowSize(configuration->size().x(), configuration->size().y());
glutCreateWindow(configuration->title().c_str());
if(!glutCreateWindow(configuration->title().c_str()))
return false;
glutReshapeFunc(staticViewportEvent);
glutSpecialFunc(staticKeyEvent);
glutMouseFunc(staticMouseEvent);
@ -71,7 +80,7 @@ void GlutApplication::createContext(Configuration* configuration) {
ExtensionWrangler::initialize();
c = new Context;
delete configuration;
return true;
}
GlutApplication::~GlutApplication() {

19
src/Platform/GlutApplication.h

@ -81,7 +81,8 @@ class GlutApplication {
* @param arguments Application arguments
*
* 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);
@ -92,7 +93,8 @@ class GlutApplication {
*
* The @p configuration is deleted afterwards. If `nullptr` is passed
* 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);
@ -112,10 +114,21 @@ class GlutApplication {
* @brief Create context with given configuration
*
* 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);
/**
* @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 */
/**

27
src/Platform/NaClApplication.cpp

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

3
src/Platform/NaClApplication.h

@ -121,6 +121,9 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
/** @copydoc GlutApplication::createContext() */
void createContext(Configuration* configuration);
/** @copydoc GlutApplication::tryCreateContext() */
bool tryCreateContext(Configuration* configuration);
/** @{ @name Drawing functions */
/** @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) {
initialize();
createContext(new Configuration);
}
Sdl2Application::Sdl2Application(const Arguments&, Configuration* configuration): context(nullptr), flags(Flag::Redraw) {
initialize();
if(configuration) createContext(configuration);
}
void Sdl2Application::createContext(Configuration* configuration) {
CORRADE_ASSERT(!context, "Sdl2Application::createContext(): context already created", );
void Sdl2Application::initialize() {
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
Error() << "Cannot initialize SDL.";
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 */
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
@ -81,7 +94,11 @@ void Sdl2Application::createContext(Configuration* configuration) {
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
VAO. WTF. */
@ -96,7 +113,7 @@ void Sdl2Application::createContext(Configuration* configuration) {
SDL_PushEvent(sizeEvent);
c = new Context;
delete configuration;
return true;
}
Sdl2Application::~Sdl2Application() {

5
src/Platform/Sdl2Application.h

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

Loading…
Cancel
Save