How to build standalone application using OpenGLWindow?

Post Reply
CesD
Posts: 6
Joined: Sun Jun 10, 2018 4:59 pm

How to build standalone application using OpenGLWindow?

Post by CesD »

Hi there!

I'm trying to make a stand-alone app with OpenGL as it is mentioned here: http://bulletphysics.org/mediawiki-1.5. ... _framework. I don' want to integrate my example in the Example Browser;

My main.cpp looks like this :

Code: Select all

#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../Utils/b3Clock.h"

#include "../OpenGLWindow/SimpleOpenGL3App.h"
#include <stdio.h>
#include "../ExampleBrowser/OpenGLGuiHelper.h"

#include <iostream>
#include "SimpleCollision.h"

using namespace std;

CommonExampleInterface*    example;
int gSharedMemoryKey=-1;

b3MouseMoveCallback prevMouseMoveCallback = 0;
static void OnMouseMove( float x, float y)
{
	bool handled = false;
	handled = example->mouseMoveCallback(x,y);
	if (!handled)
	{
		if (prevMouseMoveCallback)
			prevMouseMoveCallback (x,y);
	}
}

b3MouseButtonCallback prevMouseButtonCallback  = 0;
static void OnMouseDown(int button, int state, float x, float y) {
	bool handled = false;

	handled = example->mouseButtonCallback(button, state, x,y);
	if (!handled)
	{
		if (prevMouseButtonCallback )
			prevMouseButtonCallback (button,state,x,y);
	}
}

class LessDummyGuiHelper : public DummyGUIHelper
{
	CommonGraphicsApp* m_app;
public:
	virtual CommonGraphicsApp* getAppInterface()
	{
		return m_app;
	}

	LessDummyGuiHelper(CommonGraphicsApp* app)
		:m_app(app)
	{
	}
};

int main(int argc, char* argv[])
{

	SimpleOpenGL3App* app = new SimpleOpenGL3App("Bullet Standalone Example",1024,768,true);

	prevMouseButtonCallback = app->m_window->getMouseButtonCallback();
	prevMouseMoveCallback = app->m_window->getMouseMoveCallback();

	app->m_window->setMouseButtonCallback((b3MouseButtonCallback)OnMouseDown);
	app->m_window->setMouseMoveCallback((b3MouseMoveCallback)OnMouseMove);

	OpenGLGuiHelper gui(app,false);
	//LessDummyGuiHelper gui(app);
	//DummyGUIHelper gui;

	CommonExampleOptions options(&gui);


	example = ET_SimpleCollisionCreateFunc(options);
	example->processCommandLineArgs(argc, argv);

	example->initPhysics();
	example->resetCamera();

	b3Clock clock;

	do
	{
		app->m_instancingRenderer->init();
    app->m_instancingRenderer->updateCamera(app->getUpAxis());

		btScalar dtSec = btScalar(clock.getTimeInSeconds());
		if (dtSec<0.1)
			dtSec = 0.1;
	
		example->stepSimulation(dtSec);
	  clock.reset();

		example->renderScene();

		DrawGridData dg;
        dg.upAxis = app->getUpAxis();
		app->drawGrid(dg);

		app->swapBuffer();
	} while (!app->m_window->requestedExit());

	example->exitPhysics();
	delete example;
	delete app;
	return 0;
}

As you guessed, my interface is implemented in "SimpleCollision.h/cpp" and is called with the ET_SimpleCollisionCreateFunc function.

For compilation, I linked the following libraries : Bullet3Common, BulletDynamics, BulletCollision, LinearMath, GL, pthread, dl.

But when compiling, I get the following error :

Code: Select all

Linking CXX executable bulletcollision
CMakeFiles/bulletcollision.dir/srcGUI/main.cpp.o: In function `main':
/users/me/workspace/bullet-collision/srcGUI/main.cpp:59: undefined reference to `SimpleOpenGL3App::SimpleOpenGL3App(char const*, int, int, bool)'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:67: undefined reference to `OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp*, bool)'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:80: undefined reference to `b3Clock::b3Clock()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:87: undefined reference to `b3Clock::getTimeInSeconds()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:92: undefined reference to `b3Clock::reset(bool)'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:80: undefined reference to `b3Clock::~b3Clock()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:106: undefined reference to `OpenGLGuiHelper::~OpenGLGuiHelper()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:80: undefined reference to `b3Clock::~b3Clock()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:106: undefined reference to `OpenGLGuiHelper::~OpenGLGuiHelper()'
collect2: error: ld returned 1 exit status
CMakeFiles/bulletcollision.dir/build.make:110: recipe for target 'bulletcollision' failed
make[2]: *** [bulletcollision] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/bulletcollision.dir/all' failed
make[1]: *** [CMakeFiles/bulletcollision.dir/all] Error 2
Makefile:107: recipe for target 'all' failed
make: *** [all] Error 2
Indeed, there is no link made with the OpenGLWindow library (that didn't appear in /usr/local/lib when I made the install, by the way, don't know if this is normal...). Thus I tried to force-link the library built for the examples: bullet3-2.87/build_cmake/examples/OpenGLWindow/libOpenGLWindow.so, but I still have errors :

Code: Select all

Linking CXX executable bulletcollision
CMakeFiles/bulletcollision.dir/srcGUI/main.cpp.o: In function `main':
/users/me/workspace/bullet-collision/srcGUI/main.cpp:67: undefined reference to `OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp*, bool)'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:80: undefined reference to `b3Clock::b3Clock()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:87: undefined reference to `b3Clock::getTimeInSeconds()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:92: undefined reference to `b3Clock::reset(bool)'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:80: undefined reference to `b3Clock::~b3Clock()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:106: undefined reference to `OpenGLGuiHelper::~OpenGLGuiHelper()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:80: undefined reference to `b3Clock::~b3Clock()'
/users/me/workspace/bullet-collision/srcGUI/main.cpp:106: undefined reference to `OpenGLGuiHelper::~OpenGLGuiHelper()'
collect2: error: ld returned 1 exit status
CMakeFiles/bulletcollision.dir/build.make:111: recipe for target 'bulletcollision' failed
make[2]: *** [bulletcollision] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/bulletcollision.dir/all' failed
make[1]: *** [CMakeFiles/bulletcollision.dir/all] Error 2
Makefile:107: recipe for target 'all' failed
make: *** [all] Error 2
I think I'm definitely missing something; do you have any idea how to make this work? Or am I totally going in the wrong way?

Thanks in advance!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: How to build standalone application using OpenGLWindow?

Post by drleviathan »

When it comes to link errors it isn't enough to supply your code. You need to include your cmake files as well, and it would help to mention which OS and compiler you're using, although based on the full paths in the link errors I would guess: OSX and clang. You should supply a link to a github repository or supply a full tarfile of your project. I don't have access to OSX but perhaps someone who does would be interested in helping out.
CesD
Posts: 6
Joined: Sun Jun 10, 2018 4:59 pm

Re: How to build standalone application using OpenGLWindow?

Post by CesD »

Hi drleviathan, thank you for your answer!

I'm on Debian 8.8, compiling with g++, using Bullet 2.87, here is my CMakeLists.txt :

Code: Select all

project(bulletcollision)
cmake_minimum_required(VERSION 3.0)

INCLUDE_DIRECTORIES(
	"${PROJECT_SOURCE_DIR}"
	"${PROJECT_SOURCE_DIR}/srcGUI"
	"/usr/local/include/bullet"
	#Missing dependencies:
	"/users/me/workspace/bullet3-2.87/examples/ThirdPartyLibs"
)

LINK_DIRECTORIES("/usr/local/lib")


LINK_LIBRARIES(
	#Bullet libs
	Bullet3Common BulletDynamics BulletCollision LinearMath 
#	/users/me/workspace/bullet3-2.87/build_cmake/examples/OpenGLWindow/libOpenGLWindow.so
	#Others
	GL pthread pugixml dl
	)

ADD_EXECUTABLE(bulletcollision
		srcGUI/SimpleCollision.cpp
		srcGUI/main.cpp
	)
Unfortunately, I can't give away my whole project since it belongs to my company, but I don't think that the code itself (SimpleCollision.cpp) has to do with these errors.

Maybe I will reformulate: In the main function of this snippet: http://bulletphysics.org/mediawiki-1.5. ... ith_OpenGL, how can you link the implementation of "SimpleOpenGL3App" (among others) which apparently doesn't figure in the shared libraries built when installing Bullet (or am I writing nonsense?) ?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: How to build standalone application using OpenGLWindow?

Post by drleviathan »

On Xubuntu 18.04 I copied your main.cpp file, stubbed out your SimpleCollision code, and tried it myself inside my own checkout of the Bullet repository. I got the same link errors as you.

I was able to make some progress, but did not finish. See my modified CmakeLists.txt file below. For each missing symbol I would find the file that implements it and then explicitly add it to the cmake config file. A few missing symbols would be found but a dozen more would show up.

Your issues are about "how to write a working cmake config" Alas, I am not good at wrangling cmake. You are building on top of a lot of the example util code. All of that code needs to be part of your project. Another way to go might be to add your example like the others and then remove all examples except your own. And yet another way to go might be to bundle all the example utils on which you rely, turn them into their own lib, and then build and link that lib.

Code: Select all

project(bulletcollision)
cmake_minimum_required(VERSION 3.0)

INCLUDE_DIRECTORIES(
    #"${PROJECT_SOURCE_DIR}"
    "${PROJECT_SOURCE_DIR}/srcGUI"
    #"/usr/local/include/bullet"
    #Missing dependencies:
    "${PROJECT_SOURCE_DIR}/../ThirdPartyLibs"
    "${PROJECT_SOURCE_DIR}/../ThirdPartyLibs/glad"
    "${PROJECT_SOURCE_DIR}/../../src"
)

LINK_DIRECTORIES("/usr/local/lib")


LINK_LIBRARIES(
    #Bullet libs
    Bullet3Common BulletDynamics BulletCollision LinearMath 
#    /users/me/workspace/bullet3-2.87/build_cmake/examples/OpenGLWindow/libOpenGLWindow.so
    #Others
    GL pthread pugixml dl
)

ADD_EXECUTABLE(bulletcollision
        srcGUI/SimpleCollision.cpp
        srcGUI/main.cpp
        "../OpenGLWindow/SimpleOpenGL3App.cpp"
        "../Utils/b3Clock.cpp"
        "../ExampleBrowser/OpenGLGuiHelper.cpp"
        "../OpenGLWindow/GLPrimitiveRenderer.cpp"
)

CesD
Posts: 6
Joined: Sun Jun 10, 2018 4:59 pm

Re: How to build standalone application using OpenGLWindow?

Post by CesD »

Thank you so much for your answer drleviathan!

So, according to you, there is no other option than adding everything by hand? It's a pity that bullet does'nt generate it on its own, so that we can debug-draw without having to go through the ExampleBrowser or making our own debug drawer... Anyway, I made it work! Most of the missing dependencies were located in the /examples/OpenGLWindow directory.
I followed the last option you gave by trying to build the library. Here is the CMakeLists.txt for this :

Code: Select all

PROJECT(OpenGLWindow)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)

SET(BULLET_ROOT_DIR "/users/me/workspace/bullet3-2.87")

INCLUDE_DIRECTORIES(
	"/usr/local/include/bullet"
	"/users/me/workspace/bullet3-2.87/examples/ThirdPartyLibs"
)

LINK_LIBRARIES(
	GL pthread
)

FILE(GLOB OPENGL_WINDOW_EXEC
    "${BULLET_ROOT_DIR}/examples/OpenGLWindow/*.cpp"
)

ADD_LIBRARY(OpenGLWindow SHARED
    ${OPENGL_WINDOW_EXEC}
    ${BULLET_ROOT_DIR}/examples/Utils/b3Clock.cpp	
    ${BULLET_ROOT_DIR}/examples/ExampleBrowser/OpenGLGuiHelper.cpp
    ${BULLET_ROOT_DIR}/examples/ExampleBrowser/CollisionShape2TriangleMesh.cpp
    ${BULLET_ROOT_DIR}/examples/ThirdPartyLibs/Glew/glew.c
)

SET_TARGET_PROPERTIES(OpenGLWindow PROPERTIES 
	PUBLIC_HEADER OpenGLWindow.h
)

INSTALL(TARGETS OpenGLWindow
   	LIBRARY DESTINATION /usr/local/lib
)
After running

Code: Select all

$ cmake ..
$ make -j4
$ sudo make install
, the library normally installed (in /usr/local/lib).

I just had to link it in the initial CMakeLists.txt :

Code: Select all

...

LINK_DIRECTORIES("/usr/local/lib")

LINK_LIBRARIES(
	#Bullet libraries
	Bullet3Common BulletDynamics BulletCollision LinearMath 
	#Others
	GL pthread pugixml dl
	OpenGLWindow
)
...	
	 
One cool thing here is that I linked the GuiHelper form the ExampleBrowser (examples/ExampleBrowser/OpenGLGuiHelper.cpp), that implements the GUIHelperInterface (examples/CommonInterfaces/CommonGUIHelperInterface.h), which means that you can make your own GUI helper from there!

If someone is using this, you may probably need to add some executable in order to make your project work (from examples/Utils for example).

Thank you again drleviathan!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: How to build standalone application using OpenGLWindow?

Post by drleviathan »

I'm sure cmake has a way to write a rule that would find the necessary files, instead of adding them individually by hand. I'm just not very good at wrangling cmake and not very motivated to hone my skills in that direction. I would summarize my previous post as: progress toward your goal could be made by explicitly listing files in the cmake config, and we can conclude: you need to configure cmake to find all of the code you want to use, either as files to compile or as a library to link.

If you manage to organize the example util code into a library then maybe it would be a good idea to submit it as a pull request into Bullet proper. It would be nice to have a "Hello world!" example on how to build a standalone demo in the codebase.
Post Reply