Game Maker's Garage Forum

Game Creation => C/C++/Objective-C/D/C#/F/R => Topic started by: Gan on April 23, 2015, 09:14:38 PM

Title: [D] The Ultra Mesh (Work in Progress)
Post by: Gan on April 23, 2015, 09:14:38 PM
I'm working on a Mesh object that's completely customizable and can support 2 million+ triangles at 60 frames per second(on my laptop).

Source Code: https://github.com/MatthewFrench/UltraMesh (https://github.com/MatthewFrench/UltraMesh)

Feature Completion List (Crossed out is completed):
• Add ability to make a sky box
• Add ability to make fog
• Add loading Obj meshes from file.
• Ability to remove vertices from UltraMesh
• Rotation and translation of entire UltraMesh
Add Rectangle and box shape
• Add ability to texture shapes with images
• Make pulsating landscape demo with sound analysis using only the simplest UltraMesh commands
Add fancy camera movement functions- so the camera can fly around like a space ship
Move or change color of vertices
•  Basic UltraMesh class setup (create mesh, add vertices, render)
addTriangle method in UltraMesh for easy adding triangles
VertexGroup class for easy manipulation of shapes and groups of distinct vertices
More shape functions, square, cube, polygon, sphere, pyramid
Switch to using Point or Point3 for vectors for easier manipulation instead of float arrays
Make it stable for having multiple UltraMeshes
Optimizations in UltraMesh for little CPU mesh modifications

Render speed on laptop:
2 million non-moving triangles: 60fps, 3% CPU
20,000 moving triangles: 60fps, 10% CPU
2 million moving triangles: 10fps, 100% CPU

Here is an example:

Code: [Select]
UltraMesh mesh = new UltraMesh();

ShapeGroup myCube = ShapeCreator.makeCube(mesh , Vec3(5, 2, 1), 1.0);
myCube.rotateX(5);

ShapeGroup myCube2 = ShapeCreator.makeCube(mesh, Vec3(-3, -2, 2), 2.0);
myCube2.rotateY(-10);
myCube2.setColor(0.0, 0.0, 1.0, 1.0);

mesh.render(camera);

Under the hood the Mesh object contains giant float arrays of numbers that the Mesh and VertexGroups modify directly.
The draw call only draws a single Mesh which allows it to have so many triangles.

Other shape methods:
createSquare
createTriangle
createPolygon
createCone
createSphere

My reason for wanting to create this is so I can make a giant ground mesh of vertices that move up and down to the beat of music.

In the future I could probably make a second version that instead of colors, you can apply images. That would mean you could render 2 million images to the screen, would be great for a very large 2D tile map. Or even a very large 3D map.

Very much work in progress, still learning 3D and better ways to do stuff


Update 2
Did a bunch of optimizations, constantly adding thousands of triangles to the Ultra Mesh. It works fine up until 700,000 triangles. Without constantly adding triangles, it runs fine at 2 million triangles.
From some research it seems for games, you don't want a polygon count over 300,000. I suppose we're doing pretty good then.
I can't wait until the Vulkan API. I bet I could get a lot more performance.

Update 3
Added the VertexGroup class and added a lot more mesh optimizations. You can now change any part of the mesh no matter how big it is and it won't impact performance.

Update 4
Bunch of VertexGroup bug fixes. You can see a few of my cool looking failures down below. But now it works well, lots of triangles rotating and changing colors randomly at only 2.8% CPU.

Update 5
Another performance test and bug fixes. 1,275 moving, spinning, color changing triangles run at 13% CPU.

Update 6
Tried to add the addSquare function, results were really buggy. I am quite tired. I'll continue after some sleep.

Update 7
Squares are still messed up but I asked for optimization help online and now rendering 2 million triangles only uses 3% CPU.

Update 8
I made a help post to figure out the square bug: http://www.reddit.com/r/opengl/comments/33rbim/weird_square_drawing_bug_4_vertices_d_language/

Update 9
Upgraded it to use OpenGL 3.3 and Vertex Array Objects. It might have increased performance, not entirely sure.

Update 10
Fixed the vertex bug! Turned out I was setting up my indices wrong.
Fun fact: 1,225 spinning, moving, color changing squares takes only 13% CPU.
However since I updated to Vertex Array Objects, my color has been resetting back to white after a frame of being colored. That sounded suspiciously racist.

Update 11
Fixed the color issue! 20,000 moving, spinning, color changing triangles and squares runs super smoothly at 60fps.

Update 12
Working on an addCube function.

Update 13
I'm not cube expert but that cube seems a tad long.

Update 14
That's one messed up cube. Working on fixing.

Update 15
3D shapes are looking a bit weird. I'll have to test more. Might just be the camera.

Update 16
Now that is what I call a cube.

Update 17
My next step is to make a giant fluctuating fancy colored ground. I'm thinking Tron styled.
I really do need to stop and simplify things a bit more though. After each bit of progress I should clean up the class so it's a little simpler.

Update 18
Cleaning up and adding more functions.
On a side note it is a bad idea to try to scale 100,000 cubes at 60fps. Maxed out my GPU, CPU and froze my laptop.
Turns out I have a bug in my scaling code. The crash happened because I scaled all 100,000 cubes beyond the highest float value. Oops.

Update 19
Fixed scaling. 100,000 pulsing cubes no longer crashes my laptop. Very slow though. Like 10fps slow.
1,000 pulsing cubes uses 10% CPU though. Vertex math is expensive people.

Update 20
I cleaned it up a lot. Made a cube tornado. It's easier to use and much cleaner. Still gonna be better though.

Update 21
I made a circle algorithm! But realized it's actually a polygon algorithm depending on how many segments you choose. From triangles to circles. Now I want to make a sphere and pyramid algorithm.

Update 22
Went to make a pyramid and ended up making a cone generator. Can make pyramids with all sorts of bases. Now I get to make an icosphere. Which is a little above my ability so I'm gonna look up algorithms.

Update 23
Made a buckyball. Now I need to make a subdivision algorithm that can not only awesomely subdivide the buckball but also any mesh.

Update 24
My subdivision algorithm is slightly broken.

Update 25
We have spheres! Took me literally 7 hours. Got the subdivision algorithm to work and normalization to smooth out the sphere. Next step is to do another friendliness sweep to make sure the necessary functions are available for easy manipulation.

Update 26
3D math - specifically vector movement and rotation is incredibly confusing. Don't get me started on matrices. Gah.
I'm just trying to make the camera fly around like a space ship when you press arrow keys.
It half works.
I need to find a 3D math library with all the functions pre-built.

Update 27
Lets see if I can revamp the camera system, make the camera incredibly easy to use.


Update 28
New camera works marvelously. The new math library is wonderful. I need to set my sight on the next feature now.

Update 29
Made a ground mesh. 20,000 vertices moving up and down uses only 18% CPU. Now I need to synchronize it to music.

Update 30
Still looking for a good audio library. Meanwhile I have been looking at texturing tutorials. How to apply an image to a mesh. You bind the active texture and have to rendered in the shader via UV coordinates. Sounds easy enough. Unfortunately you can only have up to 16 active textures on a single mesh. So I need to come up with a solution. I'm thinking maybe I can add an Image loading piece to the UltraMesh that puts all your images into a single giant image tileset. 1024x1024 is a good size. Though I'll have to make it return an error if you have too many images to fit in 1024x1024. Or I suppose I could do some clever programming and make it support multitexturing for 16 1024x1024 textures. If you had a tile game that had tiles at 64x64, you could have a max of 4,096 different tile images. So far I'm fairly pleased with my planning. No major roadbumps. A very fast and simple 2D/3D game engine is on it's way.
I'm thinking add texturing and then add dynamic lighting and you can make some really cool things. Really fancy 2D games or nifty 3D games.
Though low level graphic programming really is something important to learn. I can see myself being able to make so much more, stuff I've seen in games and tried to make but ended up being too slow or not looking right.
I might have to make a few different UltraMesh classes for specific uses. You can't really just make a single class that does everything without sacrificing performance or really cool looking effects.
Also checked out particles and instancing. It seems that particles would probably be best to have it's own class. UltraParticle or something. Instancing seems like it could be useful in UltraMesh though. Instancing allows a mesh to be rendered multiple times in different places without much more bandwidth or processing power. So instancing is very good for tiling things like if you wanted your world to appear to go on forever.
Title: Re: [D] The Ultra Mesh (Work in Progress)
Post by: Silverwind on April 25, 2015, 06:15:43 AM
Looks awesome! What's Mesh then?
Title: Re: [D] The Ultra Mesh (Work in Progress)
Post by: Gan on April 25, 2015, 06:28:51 AM
A mesh is a shape. It can be anything, triangle, square, picture, cube, landscape, building, even a 3D person.

My UltraMesh is going to simplify drawing so you can add all sorts of shapes for both 2D and 3D games or projects.

For (hypothetical)example if you were to use it in Legendary Sword and you needed to draw a rectangle health bar, you could call addRectangle(x, y, z, width, height). Then you'd have a rectangle that you can scale depending on a character's health and also change color.

The best feature of the UltraMesh isn't that it can draw 2D and 3D stuff, the best feature is that it can draw a lot of stuff really fast. If you want to draw a 2 million tile map for your RPG game, UltraMesh will do it easily.

But it's still very much work in progress.

You could make your own version of Minecraft with the UltraMesh.
Title: Re: [D] The Ultra Mesh (Work in Progress)
Post by: Silverwind on April 25, 2015, 09:35:41 AM
Sounds super sweet :D
Title: Re: [D] The Ultra Mesh (Work in Progress)
Post by: Gan on April 27, 2015, 08:09:05 PM
My heart is beating faster, my pupils are dilating, my saliva is excreting at an increased rate, the suprarenal glands in my kidneys are outputting adrenal hormones...


https://github.com/Dav1dde/gl3n

THAT IS WHAT I CALL A MATH LIBRARY. HECKZ YEAH.  ;D
Title: Re: [D] The Ultra Mesh (Work in Progress)
Post by: WarHampster on April 28, 2015, 02:44:02 AM
So you're making an OpenGL mesh library? Is the idea to make a new model format or to simplify rendering? Either way you should add support for loading an open format like OBJ.

Interesting that you didn't notice any performance increase when you switched to vertex buffer objects. Theoretically retained mode should be way faster since the GPU won't get bottlenecked by the program code, but in my experience it often doesn't make a difference. I guess it really comes down to the drivers.

At the lowest level of rendering my voxel engine uses glDrawArrays in immediate mode to draw lots of vertical lines on a framebuffer object. I should profile using a VBO instead, but I suspect I would get better performance if I left the OpenGL rendering to the CPU and did the raycasting on the GPU with CUDA. I think x told me this years ago, but I didn't really understand him at the time xD

Also if you can't wait for Vulkan there's always Mantle. If you don't mind programming on Windows ;)

EDIT -

Also, what do you think of D? My friend is doing his thesis on the different successors to C++, namely D and Rust. I hate functional programming so Rust is a no-go for me, but D basically seems like C++ with a garbage collector, in which case why not use a more mature language like Java or C#?
Title: Re: [D] The Ultra Mesh (Work in Progress)
Post by: Gan on April 28, 2015, 04:13:22 AM
So you're making an OpenGL mesh library? Is the idea to make a new model format or to simplify rendering? Either way you should add support for loading an open format like OBJ.
Simplification is the goal. I want people to be able to make interactive 3D or 2D art. Blender is great for making videos and images but the art isn't real-time interactive or malleable.
Adding Obj format support is a fantastic idea. Make a model in blender, import into your D program and use that in your interactive art. I'll add that to the feature list.

Interesting that you didn't notice any performance increase when you switched to vertex buffer objects. Theoretically retained mode should be way faster since the GPU won't get bottlenecked by the program code, but in my experience it often doesn't make a difference. I guess it really comes down to the drivers.
Actually there was a fairly massive CPU performance increase. 3% CPU to render 2 million triangles. As long as no vertex math is happening.

At the lowest level of rendering my voxel engine uses glDrawArrays in immediate mode to draw lots of vertical lines on a framebuffer object. I should profile using a VBO instead, but I suspect I would get better performance if I left the OpenGL rendering to the CPU and did the raycasting on the GPU with CUDA. I think x told me this years ago, but I didn't really understand him at the time xD
That's a fascinating idea and way higher than my knowledge set. I can't give an opinion.

Also if you can't wait for Vulkan there's always Mantle. If you don't mind programming on Windows ;)
I've looked into it but I'll just wait. Mantle is dead on arrival and Vulkan should be widely supported at the end of the year. I just hope Vulkan won't require a completely different mindset.

Also, what do you think of D? My friend is doing his thesis on the different successors to C++, namely D and Rust. I hate functional programming so Rust is a no-go for me, but D basically seems like C++ with a garbage collector, in which case why not use a more mature language like Java or C#?
Java - I don't like the idea of a VM but it's a fine language. I use it for work. Maybe that's why I prefer to stay away from it.
C# - Fantastic language, I would have definitely gone with this if it were cross platform. And Visual Studio were cross platform.
D - Identical to C# pretty much. Tons of libraries. You can bind to C++ or C code if you want to use one of their libraries. Cross platform.

D is the friendliest cross platform language I have had the pleasure to use. It has a fantastic package manager/compiler/running thingy. Cross platform command line application called DUB. Install it, then to run D programs just cd into the source and run the command "dub". No ridiculous compiler flags to set up. Use any IDE you want but there's a VisualD plugin for Microsoft Visual Studio which I hear is fantastic. I use Xamarin with the D language plugin on Mac.
Everything just works. On all platforms. With the speed of C++. But not the complexity. The language has all the features I could want.
Dlanguage website is well setup, easy to find documentation and they even have a constantly updated package section where you can look at packages. Lots of packages, 3D, window, math, animation, fluid dynamics, game libraries, physics libraries, and so on. To install a package it's as easy as opening your source project's dub.json file and adding the package name to the dependencies. The package gets downloaded when it compiles your application.