Welcome, Guest |
You have to register before you can post on our site.
|
Forum Statistics |
» Members: 103
» Latest member: yelruh
» Forum threads: 233
» Forum posts: 989
Full Statistics
|
Online Users |
There are currently 2 online users. » 0 Member(s) | 1 Guest(s) Google
|
Latest Threads |
Is Vulkan the future?
Forum: General Chat
Last Post: web2gamedevconvert
07-07-2024, 12:29 PM
» Replies: 8
» Views: 18,675
|
hello
Forum: Scratchpad Games
Last Post: web2gamedevconvert
05-20-2024, 04:20 PM
» Replies: 10
» Views: 31,256
|
So, you're bypassing Unit...
Forum: General Chat
Last Post: web2gamedevconvert
05-18-2024, 10:34 AM
» Replies: 3
» Views: 15,215
|
Arise dead book?
Forum: Scratchpad Games
Last Post: Brian Beuken
02-29-2024, 08:07 AM
» Replies: 0
» Views: 1,141
|
Im working on a Game..
Forum: Scratchpad Games
Last Post: Brian Beuken
08-04-2023, 10:58 AM
» Replies: 8
» Views: 18,715
|
OpenGL Error handling
Forum: Assets, Tools, Libraries and other useful things
Last Post: Brian Beuken
12-07-2022, 11:48 AM
» Replies: 0
» Views: 5,790
|
Rock Pi5B
Forum: Other SBC's
Last Post: Brian Beuken
11-12-2022, 10:14 PM
» Replies: 5
» Views: 11,910
|
Setting Up Bullet
Forum: Assets, Tools, Libraries and other useful things
Last Post: Brian Beuken
10-12-2022, 11:36 AM
» Replies: 3
» Views: 14,642
|
Building with a toolchain
Forum: General Chat
Last Post: junglie85
09-11-2022, 07:45 AM
» Replies: 3
» Views: 11,698
|
Window doesn't open on Pi
Forum: Help my code won't work??
Last Post: junglie85
09-05-2022, 01:28 PM
» Replies: 5
» Views: 10,206
|
|
|
MD2 models |
Posted by: Brian Beuken - 03-01-2018, 08:30 PM - Forum: Assets, Tools, Libraries and other useful things
- No Replies
|
|
There are a few people still making MD2 models which will let you create some cool games using the basic MD2 loaders explained in the book, one of the best is.
http://md2.sitters-electronics.nl/
You should also try to write systems for MD5's and I'll cover that on this site soon as well as a few other model types.
I did get asked by some students for FBX, but that may be aiming a bit high for an SBC, but at some point I'll give it a try, if you do it, let us know.
|
|
|
Setting Up Bullet |
Posted by: Brian Beuken - 02-26-2018, 02:42 PM - Forum: Assets, Tools, Libraries and other useful things
- Replies (3)
|
|
Code: #include <bullet/btBulletDynamicsCommon.h>
class PhysicsObj
{
public:
PhysicsObj(btCollisionShape* Shape, // to create a new object it needs shape
float mass, // and mass data
const btVector3 &Position, // these have defaults(0,0,0), but best to be replaced
const btQuaternion &Rotation ); // here be dragons...but glm and bt, can handle it
~PhysicsObj();
// best to allow our Object to set and return use things in accessors
inline btCollisionShape* GetShape(){return m_Shape;}
inline void SetShape(btCollisionShape* S) {m_Shape = S; }
inline btRigidBody* GetRigidBody(){return m_Body; }
inline void SetRighidBody(btRigidBody* RB) { m_Body = RB; }
inline btMotionState* GetMotionState() {return m_Status;}
// couple of useful utility functions to simplify the rotate and position of our physics objects
// these act on the Rigid body and therefore will reposition/orient an object while it is
// in the physics world, useful for restarting or teleporting.
inline void SetOrientation(btQuaternion Rotation)
{
// could just m_body->setXXX but there's a slim chance you might add multiple rigid bodies to an object
// and you would make GetRigidBody return the active one, so this is a safer method to allow for later expansion
GetRigidBody()->setWorldTransform(btTransform(Rotation, m_Body->getWorldTransform().getOrigin()));
}
inline void SetPosition(btVector3 Position)
{
GetRigidBody()->setWorldTransform(btTransform(m_Body->getOrientation(), Position));
}
// This gets the Motionstate transform, which is useful variables made available after the step
// as these are generated by the step system, they should be used as read only, as writing to them
// has no effect and sending them back to the motionstate is not useful,
void GetTransform(btScalar* transform)
{
if (m_Status)
m_Status->GetWorldTransform(transform); //this is the important part
}
protected:
btRigidBody* m_Body;
btCollisionShape* m_Shape;
GameValues* m_Status; // the general position, orientation and scale of our object to return back
};
For me Bullet Physics is the best overall physics engine available for an SBC, its not by any means the best system, it just works well and is light enough not to overload a small machine. On most cases on a single core, I can control 100-150 rigid bodies quite well with it, and that's usually enough. With some care and planning more is possible.
It is possible to build the source code for Bullet, but really thats just too much effort... best to install it on your target with
sudo apt-get install libbullet-dev
Bullet itself makes use of 4 main sub libraries
BulletCollision, BulletSoftBody, BulletDynamics, LinearMath
These need to be included in your VisualGDB/Studio library list and of course you need to include your library directory for the header files /usr/include/bullet
Once done its all pretty much self contained and then its up to you to make the physics world.
Bullet works by creating a physics based world, populated with objects which represent your objects and providing a set of base classes which you can attach to your own objects and keep track of their position, and orientation so that you can render them. And in doing so it provides physical property concepts of velocity, mass, orientation, shape and other real world properties you can expect a 300metre long spacecraft to have, as well as a 5’2” overweight but surprisingly athletic plumber. Once these representative physical objects are set up, Bullet then updates their motion and forces acting on or against them and keeps track of all the positional and orientation information in its own class members, allowing you to use them in your own position and rendering systems.
In the simplest terms, Bullet has all these objects in this unseen physics world, and then works out what happens to them when they all get thrown up into the air bouncing off each other and then landing and bouncing on the ground. Rotational effects, friction, material properties, momentum retention and absorption as well as many other things are taken care of for us.
In order for this magic to work, we must allow Bullet to create and maintain this world which will mainly contain mathematical concepts of our terrain and of any moving or static objects we deem important enough to be part that dynamic world. The objects are added to the world, given some physical properties, and a suitable “solver” function is then called which then does the work to move them around. With a few optimisations added to the mix for efficiency and speed, such as a choice of method for a broad phase collision to reduce unwanted tests.
We can have quite some variety of basic object shapes which are based on our previous ideas of Primitive collision types, and of course every object can have it’s own physical properties and different solvers can be used for different kinds of motion and interaction.
By using Bullets methods to implement motion, we effectively can let it take care of all the movement, collision, response and reactions we should expect our objects to have. That lets us focus more on logic and decision making. Bullet will create events we can detect and objects we can test, when something important happens, like a collision, allowing us to make the right kind of sound, or destruction of a relevant object, and then Bullet can be asked to continue to work on the motion of the interacting objects according to standard rules of how we think the universe should work.
We should bear in mind though it’s not exact, physics in the real universe works on a quantum level, everything checked and tested at all times. Computers work on a sequential, one at time, at a given point in time, level. But it does work quite effectively, at the cost of quite a lot of processing!
Bullet needs a few things set up before it can work...
btBroadphaseInterface* BroadPhase;
btDefaultCollisionConfiguration* CollisionConfiguration;
btCollisionDispatcher* Dispatcher;
btSequentialImpulseConstraintSolver* ConstraintSolver;
btDiscreteDynamicsWorld* DynamicPhysicsWorld;
each in turn need to be initialised
// create the main physics systems
BroadPhase = new btDbvtBroadphase();
CollisionConfiguration = new btDefaultCollisionConfiguration();
Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
ConstraintSolver = new btSequentialImpulseConstraintSolver;
DynamicPhysicsWorld = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, ConstraintSolver, CollisionConfiguration);
// set a "normal" gravity level
DynamicPhysicsWorld->setGravity(btVector3(0, -9.81f, 0));
Once done, we will now have a physics world that simply needs to be updated in steps,
DynamicPhysicsWorld->stepSimulation(1 / 60.0f);
but we still have to populate the physics world, and that requires us to create our rigid bodies from a list of possible types
In my book I create a class called a PhysicsObj, which any render object can have an instance of, the header is in the code snippet above. The rest of the code can be downloaded from my site.
Once you have a PhysicObj created, you can focus on moving that object around, or allowing it to be moved around by the physics simulation. Then its a (fairly) simple step to acquire orientation and position data that will allow you to render your object and if you choose, its physics boundings.
You will find a good example of setting up Bullet in the V2MD2ModelDemo example code.
|
|
|
Asus Tinkerboard |
Posted by: Brian Beuken - 02-26-2018, 02:06 AM - Forum: Other SBC's
- Replies (10)
|
|
I soooo want to love the Tinkerboard, I really do, and I suspect I will, but I need to wait just a little bit longer for the software to be just right. But for sure its been improving with each release, its almost at this point usable.
It does have graphics, now (it didn't when it was first released) it does have X11 video GL2.0 and GL3.0 drivers, and therefore it will build the current maze demo, but the GPU does not yet seem to be accelerated, so for the moment at least it chugs like me in a 10m sprint to the donut counter, ie it does the job, but not fast.
It has the potential to be a monster machine with ES3.1 (maybe 3.2) and it does report that 3.1 is possible, so it may be we can play with some 3.1 shaders, but until the acceleration is switched on, its not going to be quite good enough.
Soon though, very soon.
|
|
|
Banana Pi zero |
Posted by: Brian Beuken - 02-26-2018, 01:28 AM - Forum: Other SBC's
- Replies (4)
|
|
A very interesting board indeed, its a zero in its layout, but this time a quad core.. Sadly only a Mali 400Mp2 but it should out perform or at least match the Raspberry Zero in graphic terms, and blow it away in full computing mode.
As always though the software isn't here yet, Armbian does a fair attempt at getting it up and running but terrible graphic glitching makes it useless for any kind of graphic systems, and its GLMark2-es seemed to think it had OpenGLES3.0 GPU on board, the Mali 400's are strictly ES2.0 which probably explains why it wasn't able to complete the tests,though it did get quite far into them, though very slow
I'll do an update/upgrade cycle on it from time to time to see if there's any improvement, but for now this is a non starter for our gaming purposes.
Also interesting to note it gets bloody hot, I put a heat sink on it, wouldn't want to run without.
edit... ok I found a slightly older verison of the Armbian/ubuntu test build which installed at 720p and it is much more stable, after update and upgrade it is still quite stable, no glitching and GLMark2-es2 worked better, showed as Mali400 and ran all the tests, but it reported a really crap score of 52, which is feeble compared to a Raspberry zero which averages 100. I suspect its not fully accelerated even though it got through all tests.
Not sure what to make of this, its quad cores make it a great unit, its crap graphics make it pretty useless, but functional barely. I guess as with all maker boards it depends what you want to do with it, if you need a small cpu system, its amazing.
I can't really tell if the GPU is accelerated, but given its an Allwinner it probably is/will be, so that score might go up as the Armbian guys get things moving on it.
Maybe Banana Pi themselves might get round to putting a decent OS with acceleration (don't hold your breath there though)
|
|
|
Raspberry Screen shots |
Posted by: Brian Beuken - 02-25-2018, 10:21 PM - Forum: Assets, Tools, Libraries and other useful things
- No Replies
|
|
My students are working on a Raspberry Pi project and one of them was looking for a nice screen grab program. Its not as easy to do as it might seem since the Raspberry does not use X11 to display its screens, instead it uses Broadcom's Dispman system.
but there is a great package I used for all my raspberry screen shots. fast, effective and once set up, very reliable.
Use Raspi2png
you can get it here
https://github.com/AndrewFromMelbourne/raspi2png
clone the rep, compile it, and its there when you need it, its especially useful to activate it from an SSH console.
|
|
|
C++ Coding Magpi #67 |
Posted by: Brian Beuken - 02-24-2018, 01:17 PM - Forum: General Chat
- No Replies
|
|
67 introduces some graphics into the mix which will see us begin to create basic systems that we can build on.
We still have some tech stuff to deal with, and its glossed over a little for the beginners, but once we can put our own graphics on screen we're nearly at the point of being able to place and scale them to create game environments.
|
|
|
Preview error number 1 (gulp) |
Posted by: Brian Beuken - 02-24-2018, 12:29 PM - Forum: Fundamentals Errata/Questions
- No Replies
|
|
oh damn, what a horrible feeling, there is a tiny error on the Amazon preview which I assume will also be in the book, (I've not seen the finished book yet)
in the "From Hello World to Halo-It's just code" section
the line on the 2nd paragraph says,
"so even the most code wary the beginner, should pick things up as they go."
should read.
"so even the most code wary beginner, should pick things up as they go."
I'm sure there's a lot of errors in the final book, it was proofed by various different people, but things get missed. If there is ever a 2nd edition, I'll fix things like that, but nothing I can do at the moment as the book us currently at the printers (or just been printed)
|
|
|
Loading OBJ's |
Posted by: Brian Beuken - 02-22-2018, 01:46 PM - Forum: Scratchpad Games
- No Replies
|
|
Getting OBJ files to load isn’t the hardest thing in the world, but it does present a few challenges.
OBJ is a fairly standard format, but it’s been around long enough for it to have had a lot of additions and updates to make variations a problem. So if you write a reader for your own very specific types of OBJ’s you may find it lacks the flexibility to load other supposedly standard OBJ’s.
OBJ’s are important though, they represent the simplest kind of multi face model you are likely to load into your project, once you get to the realization that typing in anything more than a cube is a major pain.
Key to the OBJ standard is that it is text based and readable meaning you can check in an editor what kind of data your OBJ file has, make sure it has no strange extra features and get a reasonable assessment of how many sub objects it has and what their names are, which can be useful if you want to do work on specific sub objects, like a car wheel for example.
OBJ files are also usually (but not always) associated with a MTL or material file, which provides additional information that relates to textures and lighting features your renderer has to accommodate.
I use a software library to load OBJ’s, TinyOBJLoader, and I do that for 2 reasons
1 it works almost 100%
2 it gets updated to cope with additions to OBJ standard.
Getting TinyOBJLoader installed and working, is not in itself very hard, but understanding what it provides can be a bit of a leap. TinyOBJLoader is a parser for data, it reads the text and stores the resulting numerical data….somewhere.
It’s important to note that not all the data is parsed, only the data it currently understands, and also it’s stored in data structures which are supposed to be passed to it, and supplied by the users app. But for us, just wanting info on the vertices/uv and textures we can extract all we need, if we also need normal and lighting info it’s there too.
So to help in understanding what TinyOBJLoader does, we need to look at what it provides. Data…but in what format? Fortunately for us there is a very nice example of its use in the github repos which proves a very simple loader and viewer. The viewer itself is old OpenGL1.0 format so not much use to us, but it does give us a good guide how to use TinyOBJLoader
The Viewer.cc file is a simple C++ system that loads and renders a model. The key part we want is the LoadObjAndConvert function which has these input values
static bool LoadObjAndConvert(float bmin[3], float bmax[3],
std::vector<DrawObject>* drawObjects,
std::vector<tinyobj::material_t>& materials,
std::map<std:: string, GLuint>& textures,
const char* filename)
For coders that should be all we need to know about… the bmin[3] and bmax[3] are simple arrays we can pass that will provide box min and max xyz values to allow us to have bounding boxes.
Then we have 2 vectors containing pointers to DrawObjects which is a simple data structure defined beforehand, and the other is the location vector of a material structures, also defined in TinyOBJLoader.
Next up is the location of a std::map, which will associate texture names with texture handles.. allowing us to load a texture one time (per model)
All these things are defined in the example for us to use in our own code.
float bmin[3], bmax[3];
std::vector<tinyobj::material_t> materials;
std::map<std:: string, GLuint> textures;
and DrawObject is a structure and looks like this
typedef struct {
GLuint vb_id; // vertex buffer id
int numTriangles;
size_t material_id;
} DrawObject;
So a vector of DrawObject’s looks like
std::vector<DrawObject> gDrawObjects;
Finally of course the file name, as long as the file is correctly referenced LoadOBJAndConvert, will do exactly what it has been named to do and can be called.
Each DrawObject is essentially a sub object of an OBJ Model, some models may only have 1 sub object, but more complex models will often consist of several, A car model for example may have a body and 4 wheels, making 5 sub objects. So the vector’s size will tell us how many objects there are.
Now, when we call this function, we load the model, in all its parts, its material info goes into the material vector, the gDrawObject vector contains all the sub objects needed (with a VB(O) rather than a vertex list) and there it’s a simple process to render the object.
We will have to change the location of the vectors and map, so that our individual object can access its own data, but overall that’s not making any changes to the function itself.
The Key point is to think about what the function needs to work and what it returns.
When it comes to rendering, the old OpenGL1.0 draw function isn't something we can plug in directly, but we should be able to read the draw function and take note that it is working out how many shapes (sub objects) to draw, each with their own material ID to get access to the texture,(and other lighting info), and the number of triangles needed to draw,
In its raw form, the conversion produced VBO's (with id's held in the DrawObject structures) with 3 floats for verts, 3 for normals, 3 for colours(RGBA) and 2 for UV's You may not need or want to use all these attributes, so you can adapt the function if memory is tight, but you can certainly work out your stride pattern to enable your attribute buffers and send the required attributes to your shaders.
Once you set up your attributes, a simple draw call for triangles gets your models on screen.
have fun.
|
|
|
Optimizations |
Posted by: Brian Beuken - 02-20-2018, 10:59 AM - Forum: Scratchpad Games
- Replies (3)
|
|
Readers of the book will have noted that many times I pointed out that there were better ways to do many of the concepts raised.
In fact the way most of the code was written it is very obvious that there are better ways, but I took a decision not to go into much detail on that, simply to allow new users the chance to get totally comfortable with getting their code to work. Forcing people to optimize code before they have fully understood what they are doing is a recipe for disaster, so for me it made sense not to get into that in the book, just show the basic code, get it working and once its working, then is the time to explore how to make it work better.
It would be nice to have a discussion here on how we can improve the performance of our projects (by quite some amount) if we were to use a more effective render system, and implement some multi core work. I'd love to hear your thoughts on how you can improve things, and show some results to inspire others to really get that code moving.
|
|
|
First time here, hello from Thijs. |
Posted by: McKon - 02-17-2018, 08:33 PM - Forum: General Chat
- Replies (7)
|
|
Hello everyone,
It seems like I'm one of the first members here. I'm known as Thijs van Boesschoten, I've studied networking and am doing a study on programming at the moment. In my networking classes we were thought how to use the pi as a networking tool/system. As such at the time I bought a Raspberry 0 and Arduino uno and I'd like to see what they will be able to do game wise(hopefully without melting).
As such I'm seeing myself as a near complete rookie and would love to learn more about using SBC's and game programming.
|
|
|
|