Skip to content

Commit

Permalink
completed README with more information
Browse files Browse the repository at this point in the history
  • Loading branch information
giorgiomarcias committed Jul 18, 2016
1 parent 29989e0 commit 910a270
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 23 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -37,7 +37,7 @@ find_package(glfw3 3.2 REQUIRED)

# options:

option(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." ON)
option(WITH_MULTITHREADING "Build GLFWM with multithreading (i.e. thread-safe) or not." ON)

if(GLFWM_PARENT_DIRECTORY)
set(MAKE_SHARED OFF)
Expand Down
147 changes: 135 additions & 12 deletions README.md
Expand Up @@ -17,25 +17,148 @@ A [GLFW](http://www.glfw.org) C++ wrapper with additional OOP features.
* update notifications to whole groups
* automatic control of the loop



### Compilation
To compile this software, import it in another software through cmake.
Supposing to have your software root cmake file at
#### Dependencies
There are two mandatory dependencies.

* [GLFW](http://www.glfw.org), which must have already been installed on the system.
See [http://www.glfw.org](http://www.glfw.org) for details.
Alternatively, it is possible to get GLFW through package managers, such as apt-get (Linux) or MacPort/Homebrew (Mac OS).

* [cmake](https://cmake.org), which is used to compile and install this library, greatly simplifying this tasks.
See [https://cmake.org](https://cmake.org) for details.
Alternatively, as before, it is possible to get cmake through package managers.



#### Building
Through *cmake* it is possible to compile and eventually import this library into another software.
There are two ways to do that.

* *install* the shared library binaries somewhere on the system and then import it:

mkdir glfwm_build
cd glfwm_build
cmake <path-to-glfwm>
make
make install

Now `glfwm` is installed as a shared library depending on the value of `CMAKE_INSTALL_PREFIX` and can be linked to.
Then in the cmake list file `CMakeList.txt` of another project just add:

<path-to-your-software>/CMakeLists.txt
...
find_package(glfwm 3.2 REQUIRED)
...
add_executable(myexe myexe.cpp)
target_link_libraries(myexe glfwm)

add GLFWM as subdirectory to it:
And that's all.

# uncomment the following line if you do NOT want multi-threading support
#SET(WITH_MULTITHREADING OFF CACHE BOOL "Build GLFWM with multithreading facilities (i.e. thread-safe) or not.")
ADD_SUBDIRECTORY(<path-to-glfwm> ${CMAKE_CURRENT_BINARY_DIR}/glfwm)
* *include* the library sources in a cmake list file `CMakeList.txt` of another project:

...
add_subdirectory(<path-to-glfwm> ${${PROJECT_NAME}_BINARY_DIR}/glfwm)
...
add_executable(myexe myexe.cpp)
target_link_libraries(myexe glfwm)

In this way, `glfwm` is compiled as a static library in the build tree of the `myexe` target.

##### Build options
There are some options that affect the compilation and/or installation:

* `WITH_MULTITHREADING` enables/disables multi-threading support. This allows windows to operate and be managed in separate threads.

* `BUILD_SHARED_LIBS` makes `glfwm` be built as a shared (if `ON`) or a static (if `OFF`) library.

* `INSTALL_GLFWM` makes `glfwm` be installed (if `ON`) or not (if `OFF`).

Default values mainly depends on the way it is built as described in the **Building** section above.
`BUILD_SHARED_LIBS` and `INSTALL_GLFWM` are `OFF` when glfwm is included as a sub-directory, `ON` otherwise.
`WITH_MULTITHREADING` is always `ON`.

It is possible to change these options either as argument to the `cmake` command, e.g. `-DWITH_MULTITHREADING=OFF`, or directly in the cmake list file of another project which includes glfwm:

...
option(WITH_MULTITHREADING "Build GLFWM with multithreading (i.e. thread-safe) or not." OFF)
add_subdirectory(<path-to-glfwm> ${${PROJECT_NAME}_BINARY_DIR}/glfwm)
...
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${GLFWM_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GLFWM_LIBRARIES})

Then it can be compiled with the commands:
### Usage
The main purpose is to manage windows.
So the main objects are `Window`s and a `WindowManager` which takes care of.

First of all, include the main header:

#include <GLFWM/glfwm.hpp>

Then initialize the library resources by calling

glfwm::WindowManager::init();

at the beginning of the program execution, e.g. in the `main` function before everything.

A `Window` can receive events and draw some content.
For this purpose, special objects can bind to it.

Derive `EventHandler` and override the `getHandledEventTypes()` and `handle()` methods in order to react to events like cursor position changes and mouse button clicks.
Then bind such objects to a `Window` s.t. events directed to it may handled:

class MyHandler : public glfwm::EventHandler {
public:
glfwm::EventBaseType getHandledEventTypes() const override
{
return static_cast<glfwm::EventBaseType>(glfwm::EventType::MOUSE_BUTTON);
}

bool handle(const glfwm::EventPointer &e) override
{
if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) {
// make some action based on this event
...
return true;
}
return false;
}
};

Derive `Drawable` and override the `draw()` method.
There put the code responsible of drawing the content, e.g. OpenGL calls:

class MyDrawable : public glfwm::Drawable {
public:
void draw(const glfwm::WindowID id) override
{
// draw the content on the screen
}
};

Then create some `Window` and bind the handler and the drawable to it:

...
std::shared_ptr<MyHandler> myHandler = std::make_shared<MyHandler>();
std::shared_ptr<MyDrawable> myDrawable = std::make_shared<MyDrawable>();
glfwm::WindowPointer mainWin = glfwm::WindowManager::createWindow(800, 600, std::string(), myHandler->getHandledEventTypes());
mainWin->bindEventHandler(myHandler, 0); // 0 is the rank among all event handlers bound
mainWin->bindDrawable(myDrawable, 0); // 0 is the rank among all drawables bound

Possibly create other windows and group them.
Groups are usefull for concurrent management (i.e. multi-threaded windows) or even just for sending notifications to all the windows in the same group.
Notifications can be used to make several windows react to a single event.
To create a group and attach windows:

glfwm::WindowGroupPointer grp = glfwm::WindowGroup::newGroup();
grp->attachWindow(mainWin->getID());
grp->runLoopConcurrently(); // this is available if compiled with WITH_MULTITHREADING=ON

Finally, start the main loop, which ends when all the windows are closed, and release the library resources:

glfwm::WindowManager::mainLoop();
glfwm::WindowManager::terminate();


> cmake <path-to-your-software>
> make

It has been tested on Mac OS X 10.9 - 10.10 - 10.11

Expand Down
9 changes: 4 additions & 5 deletions examples/simple_no_install/main.cpp
Expand Up @@ -49,7 +49,7 @@
// that window specific resources (e.g. OpenGL buffers or VAOs).
class MyDrawable : public glfwm::Drawable {
public:
void draw(const glfwm::WindowID id)
void draw(const glfwm::WindowID id) override
{
// Here you can do anything you want for drawing, like glViewport(x, y, w, h).
// Note: you don't have to call any swapping render buffer function, as it is
Expand All @@ -73,7 +73,7 @@ class MyHandler : public glfwm::EventHandler {
// It is essential that this method returns a mask corresponding to
// the event types that can be handled, otherwise the handle() method won't never be called
// for the events not indicated, even if they can actually be handled.
glfwm::EventBaseType getHandledEventTypes() const
glfwm::EventBaseType getHandledEventTypes() const override
{
return static_cast<glfwm::EventBaseType>(glfwm::EventType::MOUSE_BUTTON);
}
Expand All @@ -89,7 +89,7 @@ class MyHandler : public glfwm::EventHandler {
// (see glfwm::Window::bindEventHandler()). If you want to execute more than one handler
// for the same event, you are free to return false even having actually handled it; in
// this way, the following handlers are called.
bool handle(const glfwm::EventPointer &e)
bool handle(const glfwm::EventPointer &e) override
{
if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) {

Expand Down Expand Up @@ -132,8 +132,7 @@ int main(int argc, char *argv[])
glfwm::WindowManager::init();

// You can set any GLFW hint with this method:
glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwm::WindowManager::setHint(GLFW_CLIENT_API, GLFW_NO_API);

// Remember to instantiate the handlers and the drawables to bind to the windows.
// A handler can be bound to any number of different windows, and a window can have
Expand Down
9 changes: 4 additions & 5 deletions examples/simple_with_install/main.cpp
Expand Up @@ -49,7 +49,7 @@
// that window specific resources (e.g. OpenGL buffers or VAOs).
class MyDrawable : public glfwm::Drawable {
public:
void draw(const glfwm::WindowID id)
void draw(const glfwm::WindowID id) override
{
// Here you can do anything you want for drawing, like glViewport(x, y, w, h).
// Note: you don't have to call any swapping render buffer function, as it is
Expand All @@ -73,7 +73,7 @@ class MyHandler : public glfwm::EventHandler {
// It is essential that this method returns a mask corresponding to
// the event types that can be handled, otherwise the handle() method won't never be called
// for the events not indicated, even if they can actually be handled.
glfwm::EventBaseType getHandledEventTypes() const
glfwm::EventBaseType getHandledEventTypes() const override
{
return static_cast<glfwm::EventBaseType>(glfwm::EventType::MOUSE_BUTTON);
}
Expand All @@ -89,7 +89,7 @@ class MyHandler : public glfwm::EventHandler {
// (see glfwm::Window::bindEventHandler()). If you want to execute more than one handler
// for the same event, you are free to return false even having actually handled it; in
// this way, the following handlers are called.
bool handle(const glfwm::EventPointer &e)
bool handle(const glfwm::EventPointer &e) override
{
if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) {

Expand Down Expand Up @@ -132,8 +132,7 @@ int main(int argc, char *argv[])
glfwm::WindowManager::init();

// You can set any GLFW hint with this method:
glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwm::WindowManager::setHint(GLFW_CLIENT_API, GLFW_NO_API);

// Remember to instantiate the handlers and the drawables to bind to the windows.
// A handler can be bound to any number of different windows, and a window can have
Expand Down

0 comments on commit 910a270

Please sign in to comment.