Fork me on GitHub

ToonChess

3D Chess game based on OpenGL and Stockfish

Installation (linux only)

Install CMake, Stockfish and OpenGL:


          sudo apt-get install cmake stockfish xorg-dev freeglut3-dev
        

Install Bullet Physics:


          wget https://github.com/bulletphysics/bullet3/archive/2.87.tar.gz
          tar -xzf 2.87.tar.gz
          cd bullet3-2.87/
          mkdir build && cd build && cmake .. -DBUILD_EXTRAS=OFF -DBUILD_BULLET2_DEMOS=OFF -DBUILD_CPU_DEMOS=OFF -DBUILD_OPENGL3_DEMOS=OFF -DBUILD_UNIT_TESTS=OFF -DBUILD_PYBULLET=OFF
          sudo make install
          cd ..
        

Download source code:


          git clone https://github.com/martinRenou/ToonChess.git
          cd ToonChess
        

Install ToonChess:


          mkdir build && cd build && cmake ..
          sudo make install
        

Run it!


          ToonChess
        

Why did I create this game?

There are already plenty of open-source chess games, so why would I develop my own? I am not even a chess gamer, I am simply interested in real time 3D rendering. Working on this project made me improve on my OpenGL and C++ skills. I also wanted the opportunity to learn tools such as GoogleTest and Cppcheck. And here is the result! Feel free to copy parts of the code for your own OpenGL projects.

How did I create this game?

Toon Style

I wanted a toon effect for my game, this effect can be performed using the cel-shading technique. Instead of using "normal" lighting, lights are computed using a threshold: if light intensity is more important than this threshold then the 3D-object will be bright and dark otherwise. In ToonChess shaders, I actually used three thresholds, meaning four levels of lighting.

I also wanted to display black borders for chess pieces. In order to explain how I did it I'll have to explain what Backface Culling is. Backface Culling is a step during rendering in which triangles of the mesh are sorted between displayed triangles (visible on the screen) and hidden triangles (not visible because of camera point of view). Hidden triangles are not rendered in order to save computation time. Now, in order to display black borders I chose to display those "hidden triangles" in black and to enlarge them. It results in a nice black border effect, without the need of a filtering step (I could have used a sobel filter for example).

Physics and particle system

I wanted chess pieces to collapse when they are taken, in order to achieve that I used Bullet Physics which is a well known C++ physics library. I used Blender for generating fragment meshes and Bullet Physics for real time collisions and physics simulation. The result was interesting but I needed a nice way to remove fragments from the view. That's why I decided to display smoke when fragments disappear. I used a simple particle system for smoke, each particle has its own size, position, speed and lifetime. I created smoke textures using Inkscape.

Shadow Mapping

For the shadows I used the well-known Shadow Mapping technique. A separate render is performed using a Render To Texture technique (RTT), in which the distance from the light is saved for each mesh in a texture. (See picture below, the nearer the mesh is from the light, the darker it is in the shadowmap). And this distance from the light can be used in the main rendering process in order to know if the currently rendered part of the mesh is hidden from the light by another object. See this tutorial if you want to learn more about it. I then used the Percentage Close Filtering technique in order to make the shadows smoother (See this nvidia article about PCF).

Color Picking

Concerning mesh picking, I used a Color Picking technique. When a click event occurs, an other render is performed using a RTT technique, in which meshes are colored according to their positions on the grid (See picture below). The color of the clicked position on the screen is then extracted in order to know which piece on the grid has been selected. This technique is never used in video games, but it perfectly fits my needs for this project. Performances are ok because the RTT is performed only when a click event occurs.

AI

Developing the AI would have been too much work, and it wasn't the purpose of this project. I chose to use Stockfish for that. Stockfish runs in a subprocess, and communicates with the GUI using the UCI protocol.

Meshes

I created meshes on Blender and exported them under ".obj" file format.

Created by Martin Renou

Github account
Linkedin account