Browse Source

New library for OpenGL context creation using various toolkits.

Currently there is only GLUT context, pulled from magnum-examples
repository.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
5824ecfe39
  1. 3
      CMakeLists.txt
  2. 9
      doc/namespaces.dox
  3. 15
      modules/FindMagnum.cmake
  4. 1
      src/CMakeLists.txt
  5. 52
      src/Contexts/AbstractContext.h
  6. 11
      src/Contexts/CMakeLists.txt
  7. 48
      src/Contexts/GlutContext.cpp
  8. 226
      src/Contexts/GlutContext.h

3
CMakeLists.txt

@ -27,4 +27,5 @@ add_subdirectory(src)
install(DIRECTORY src/ DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}
FILES_MATCHING PATTERN "*.h"
PATTERN "*/Test" EXCLUDE)
PATTERN "*/Test" EXCLUDE
PATTERN "src/Contexts" EXCLUDE)

9
doc/namespaces.dox

@ -11,6 +11,15 @@ Contains classes needed for building meshes, setting up and rendering the
scene.
*/
/** @dir Contexts
* @brief Namespace Magnum::Contexts
*/
/** @namespace Magnum::Contexts
@brief Context creation
Base classes for creating OpenGL contexts with various toolkits.
*/
/** @dir Math
* @brief Namespace Magnum::Math
*/

15
modules/FindMagnum.cmake

@ -16,6 +16,7 @@
# Additional dependencies are specified by the components. The optional
# components are:
#
# GlutContext - GLUT context (depends on GLUT package)
# MeshTools - MeshTools library
# Physics - Physics library
# Primitives - Library with stock geometric primitives (static)
@ -63,6 +64,20 @@ foreach(component ${Magnum_FIND_COMPONENTS})
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX ${component})
# Contexts
if(${component} MATCHES .+Context)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Contexts)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${component}.h)
# GLUT context dependencies
if(${component} STREQUAL GlutContext)
find_package(GLUT)
if(NOT GLUT_FOUND)
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
endif()
# Mesh tools library
if(${component} STREQUAL MeshTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES CompressIndices.h)

1
src/CMakeLists.txt

@ -46,6 +46,7 @@ add_library(Magnum SHARED
target_link_libraries(Magnum ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY} ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY})
install(TARGETS Magnum DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
add_subdirectory(Contexts)
add_subdirectory(Math)
add_subdirectory(MeshTools)
add_subdirectory(Physics)

52
src/Contexts/AbstractContext.h

@ -0,0 +1,52 @@
#ifndef Magnum_Contexts_AbstractContext_h
#define Magnum_Contexts_AbstractContext_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Contexts::GlutContext
*/
namespace Magnum { namespace Contexts {
/**
@brief Base class for context creation
See subclasses documentation for more information. Context classes subclasses
are meant to be used directly in `main()`, for example:
@code
class MyContext: public Magnum::Contexts::GlutContext {
// implement required methods...
};
int main(int argc, char** argv) {
MyContext c(argc, argv);
return c.exec();
}
@endcode
*/
class AbstractContext {
public:
virtual inline ~AbstractContext() {}
/**
* @brief Execute main loop
* @return Value for returning from `main()`.
*/
virtual int exec() = 0;
};
}}
#endif

11
src/Contexts/CMakeLists.txt

@ -0,0 +1,11 @@
install(FILES AbstractContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts)
# GLUT context
find_package(GLUT)
if(GLUT_FOUND)
add_library(MagnumGlutContext STATIC GlutContext.cpp)
install(FILES GlutContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts)
install(TARGETS MagnumGlutContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
else()
message(STATUS "GLUT library was not found. GLUT context library will not be generated.")
endif()

48
src/Contexts/GlutContext.cpp

@ -0,0 +1,48 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "GlutContext.h"
using namespace Corrade::Utility;
namespace Magnum { namespace Contexts {
GlutContext* GlutContext::instance = nullptr;
GlutContext::GlutContext(int& argc, char** argv, const std::string& title, const Math::Vector2<GLsizei>& size): argc(argc), argv(argv) {
/* Save global instance */
instance = this;
/* Init GLUT */
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
glutInitWindowSize(size.x(), size.y());
glutCreateWindow(title.c_str());
glutReshapeFunc(staticViewportEvent);
glutSpecialFunc(staticKeyEvent);
glutMouseFunc(staticMouseEvent);
glutMotionFunc(staticMouseMoveEvent);
glutDisplayFunc(staticDrawEvent);
/* Init GLEW */
GLenum err = glewInit();
if(err != GLEW_OK) {
Error() << "GlutContext: cannot initialize GLEW:" << glewGetErrorString(err);
exit(1);
}
}
}}

226
src/Contexts/GlutContext.h

@ -0,0 +1,226 @@
#ifndef Magnum_Contexts_GlutContext_h
#define Magnum_Contexts_GlutContext_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Contexts::GlutContext
*/
#include "Magnum.h"
#include <GL/freeglut.h>
#include "AbstractContext.h"
namespace Magnum { namespace Contexts {
/** @nosubgrouping
@brief GLUT context
Supports keyboard handling for limited subset of keys, mouse handling with
support for changing cursor and mouse tracking and warping.
You need to implement at least drawEvent() and viewportEvent() to be able to
draw on the screen.
*/
class GlutContext: public AbstractContext {
public:
/**
* @brief Constructor
* @param argc Count of arguments of <tt>main()</tt> function
* @param argv Arguments of <tt>main()</tt> function
* @param title Window title
* @param size Window size
*/
GlutContext(int& argc, char** argv, const std::string& title = "Magnum GLUT context", const Math::Vector2<GLsizei>& size = Math::Vector2<GLsizei>(800, 600));
inline int exec() {
glutMainLoop();
return 0;
}
/** @{ @name Drawing functions */
protected:
/**
* @brief Viewport event
*
* Called when viewport size changes. You should pass the new size to
* Camera::viewport() function of your camera.
*/
virtual void viewportEvent(const Math::Vector2<GLsizei>& size) = 0;
/**
* @brief Draw event
*
* Here implement your drawing functions, such as calling
* Camera::draw(). After drawing is finished, call swapBuffers(). If
* you want to draw immediately again, call also redraw().
*/
virtual void drawEvent() = 0;
/**
* @brief Swap buffers
*
* Paints currently rendered framebuffer on screen.
*/
inline void swapBuffers() {
glutSwapBuffers();
}
/**
* @brief Redraw immediately
*
* Marks the window for redrawing, resulting in call of drawEvent()
* in the next iteration.
*/
virtual inline void redraw() {
glutPostRedisplay();
}
/*@}*/
/** @{ @name Keyboard handling */
public:
/** @brief Key */
enum class Key: int {
Up = GLUT_KEY_UP, /**< Up arrow */
Down = GLUT_KEY_DOWN, /**< Down arrow */
Left = GLUT_KEY_LEFT, /**< Left arrow */
Right = GLUT_KEY_RIGHT, /**< Right arrow */
F1 = GLUT_KEY_F1, /**< F1 */
F2 = GLUT_KEY_F2, /**< F2 */
F3 = GLUT_KEY_F3, /**< F3 */
F4 = GLUT_KEY_F4, /**< F4 */
F5 = GLUT_KEY_F5, /**< F5 */
F6 = GLUT_KEY_F6, /**< F6 */
F7 = GLUT_KEY_F7, /**< F7 */
F8 = GLUT_KEY_F8, /**< F8 */
F9 = GLUT_KEY_F9, /**< F9 */
F10 = GLUT_KEY_F10, /**< F10 */
F11 = GLUT_KEY_F11, /**< F11 */
F12 = GLUT_KEY_F12, /**< F12 */
Home = GLUT_KEY_HOME, /**< Home */
End = GLUT_KEY_END, /**< End */
PageUp = GLUT_KEY_PAGE_UP, /**< Page up */
PageDown = GLUT_KEY_PAGE_DOWN /**< Page down */
};
protected:
/**
* @brief Key event
*
* Called when an key is pressed. Default implementation does nothing.
*/
virtual inline void keyEvent(Key key, const Math::Vector2<int>& position) {}
/*@}*/
/** @{ @name Mouse handling */
public:
/** @brief Mouse button */
enum class MouseButton: int {
Left = GLUT_LEFT_BUTTON, /**< Left button */
Middle = GLUT_MIDDLE_BUTTON, /**< Middle button */
Right = GLUT_RIGHT_BUTTON, /**< Right button */
WheelUp = 3, /**< Wheel up */
WheelDown = 4 /**< Wheel down */
};
/** @brief Mouse state */
enum class MouseState: int {
Up = GLUT_UP, /**< No button pressed */
Down = GLUT_DOWN /**< Button pressed */
};
/** @brief Mouse cursor */
enum class MouseCursor: int {
Default = GLUT_CURSOR_INHERIT, /**< Default cursor provided by parent window */
None = GLUT_CURSOR_NONE /**< No cursor */
};
/**
* @brief Enable or disable mouse tracking
*
* When mouse tracking is enabled, mouseMoveEvent() is called even
* when no button is pressed. Mouse tracking is disabled by default.
*/
inline void setMouseTracking(bool enabled) {
glutPassiveMotionFunc(enabled ? staticMouseMoveEvent : nullptr);
}
/** @brief Set mouse cursor */
inline void setMouseCursor(MouseCursor cursor) {
glutSetCursor(static_cast<int>(cursor));
}
/** @brief Warp mouse cursor to given coordinates */
inline void warpMouseCursor(const Math::Vector2<GLsizei>& position) {
glutWarpPointer(position.x(), position.y());
}
protected:
/**
* @brief Mouse event
*
* Called when mouse button is pressed or released. Default
* implementation does nothing.
*/
virtual inline void mouseEvent(MouseButton button, MouseState state, const Math::Vector2<int>& position) {}
/**
* @brief Mouse move event
*
* Called when any mouse button is pressed and mouse is moved. Default
* implementation does nothing.
*
* @see setMouseTracking()
*/
virtual inline void mouseMoveEvent(const Math::Vector2<int>& position) {}
/*@}*/
private:
inline static void staticViewportEvent(int x, int y) {
instance->viewportEvent({x, y});
}
inline static void staticKeyEvent(int key, int x, int y) {
instance->keyEvent(static_cast<Key>(key), {x, y});
}
inline static void staticMouseEvent(int button, int state, int x, int y) {
instance->mouseEvent(static_cast<MouseButton>(button), static_cast<MouseState>(state), {x, y});
}
inline static void staticMouseMoveEvent(int x, int y) {
instance->mouseMoveEvent({x, y});
}
inline static void staticDrawEvent() {
instance->drawEvent();
}
static GlutContext* instance;
int& argc;
char** argv;
};
}}
#endif
Loading…
Cancel
Save