Extensible Flight Simulator

Robert Cranston robcr829

Goals

Implement a simple flight simulator with a focus on exploring different techniques and libraries to make future extensions as simple as possible.

Technologies

Main

Modern but no further

  • OpenGL 3.3
  • C++11
  • CMake 3.14

Libraries

As boring as possible

  • GLFW
  • OpenGL Extension Wrangler (GLEW)
  • OpenGL Mathematics (GLM)

Exploration

You are in a maze of twisty little passages, all alike

  • glewinfo, glewcompat
  • glbinding-tools, glqueries

Tools

Smoke ’em if you got ’em

  • Cppcheck
  • Clang-Tidy
  • include-what-you-use
  • -pedantic -Werror -Wall -Wextra -W...
  • -fsanitize=address,leak,undefined
  • CTest

Environment

Productivity

  • Vim

Philosophy

Laying the puzzle

  • Both C++ and OpenGL are full of legacy and power
  • More than one way to do things
  • For a given version there is a best practice
  • Often very elegant but hard to reach
  • Revealing the big picture, making implicit abstractions explicit

Data structures

I will, in fact, claim that the difference between a bad programmer and a good one is whether they consider their code or their data structures more important. Bad programmers worry about the code. Good programmers worry about data structures and their relationships.

Linus Torvalds

Modularity

gltest

Example usage

#include <glproject.hpp>
#include <gltest.hpp>


GLTEST(2, 0, 640, 480, glproject)
{
    gltest_root("tests");

    GLTEST_EXPECT_VALUE(
        glIsEnabled(GL_DEPTH_TEST),
        GL_FALSE
    )

    GLTEST_EXPECT_EXCEPTION(
        true,
        file_open("nonexistent"),
        "Could not open file 'nonexistent':\n"
        // "No such file or directory"
    )

    GLTEST_EXPECT_FRAME("frame.data")
}

Example output

>>> Expression:
glIsEnabled(GL_DEPTH_TEST)
>>> Expected value:
GL_FALSE = 0
>>> Got:
1
>>> Expression:
file_open("nonexistent")
>>> Expected exception:
Could not open file 'nonexistent':
>>> Got: none
Frame did not match expected frame 'frame.data'.

glbackend
{glfw}

glshader

Uniforms

glUniform{,Matrix}{1,2,3,4}{f,i,ui}{,v}
glUniform1f
glUniform1fv
glUniform1i
glUniform1iv
glUniform1ui
glUniform1uiv
glUniform2f
glUniform2fv
glUniform2i
glUniform2iv
glUniform2ui
glUniform2uiv
glUniform3f
glUniform3fv
glUniform3i
glUniform3iv
glUniform3ui
glUniform3uiv
glUniform4f
glUniform4fv
glUniform4i
glUniform4iv
glUniform4ui
glUniform4uiv
glUniformMatrix1f
glUniformMatrix1fv
glUniformMatrix1i
glUniformMatrix1iv
glUniformMatrix1ui
glUniformMatrix1uiv
glUniformMatrix2f
glUniformMatrix2fv
glUniformMatrix2i
glUniformMatrix2iv
glUniformMatrix2ui
glUniformMatrix2uiv
glUniformMatrix3f
glUniformMatrix3fv
glUniformMatrix3i
glUniformMatrix3iv
glUniformMatrix3ui
glUniformMatrix3uiv
glUniformMatrix4f
glUniformMatrix4fv
glUniformMatrix4i
glUniformMatrix4iv
glUniformMatrix4ui
glUniformMatrix4uiv

Info log

  • glCompileShader GL_COMPILE_STATUS glGetShaderiv glGetShaderInfoLog
  • glLinkProgram GL_LINK_STATUS glGetProgramiv glGetProgramInfoLog
  • glValidateProgram GL_VALIDATE_STATUS glGetProgramiv glGetProgramInfoLog

glmodel
{obj,terrain,water}

Geometry

Vertex attributes

  • Position
  • Texture coordinates
  • Normals

Materials

Shader uniforms

  • Phong colors, coefficients and maps

glrenderer

User-defined per-instance vertex attributes

  • Model matrix
  • Color

Drawing

gl{,Multi}Draw{Arrays,{,Range}Elements,TransformFeedback{,Stream}}{,Instanced{,BaseVertex}{,BaseInstance},Indirect}
glDrawArrays
glDrawArraysInstanced
glDrawArraysInstancedBaseInstance
glDrawArraysInstancedBaseVertex
glDrawArraysInstancedBaseVertexBaseInstance
glDrawArraysIndirect
glDrawElements
glDrawElementsInstanced
glDrawElementsInstancedBaseInstance
glDrawElementsInstancedBaseVertex
glDrawElementsInstancedBaseVertexBaseInstance
glDrawElementsIndirect
glDrawRangeElements
glDrawRangeElementsInstanced
glDrawRangeElementsInstancedBaseInstance
glDrawRangeElementsInstancedBaseVertex
glDrawRangeElementsInstancedBaseVertexBaseInstance
glDrawRangeElementsIndirect
glDrawTransformFeedback
glDrawTransformFeedbackInstanced
glDrawTransformFeedbackInstancedBaseInstance
glDrawTransformFeedbackInstancedBaseVertex
glDrawTransformFeedbackInstancedBaseVertexBaseInstance
glDrawTransformFeedbackIndirect
glDrawTransformFeedbackStream
glDrawTransformFeedbackStreamInstanced
glDrawTransformFeedbackStreamInstancedBaseInstance
glDrawTransformFeedbackStreamInstancedBaseVertex
glDrawTransformFeedbackStreamInstancedBaseVertexBaseInstance
glDrawTransformFeedbackStreamIndirect
glMultiDrawArrays
glMultiDrawArraysInstanced
glMultiDrawArraysInstancedBaseInstance
glMultiDrawArraysInstancedBaseVertex
glMultiDrawArraysInstancedBaseVertexBaseInstance
glMultiDrawArraysIndirect
glMultiDrawElements
glMultiDrawElementsInstanced
glMultiDrawElementsInstancedBaseInstance
glMultiDrawElementsInstancedBaseVertex
glMultiDrawElementsInstancedBaseVertexBaseInstance
glMultiDrawElementsIndirect
glMultiDrawRangeElements
glMultiDrawRangeElementsInstanced
glMultiDrawRangeElementsInstancedBaseInstance
glMultiDrawRangeElementsInstancedBaseVertex
glMultiDrawRangeElementsInstancedBaseVertexBaseInstance
glMultiDrawRangeElementsIndirect
glMultiDrawTransformFeedback
glMultiDrawTransformFeedbackInstanced
glMultiDrawTransformFeedbackInstancedBaseInstance
glMultiDrawTransformFeedbackInstancedBaseVertex
glMultiDrawTransformFeedbackInstancedBaseVertexBaseInstance
glMultiDrawTransformFeedbackIndirect
glMultiDrawTransformFeedbackStream
glMultiDrawTransformFeedbackStreamInstanced
glMultiDrawTransformFeedbackStreamInstancedBaseInstance
glMultiDrawTransformFeedbackStreamInstancedBaseVertex
glMultiDrawTransformFeedbackStreamInstancedBaseVertexBaseInstance
glMultiDrawTransformFeedbackStreamIndirect
glDrawElementsInstancedBaseVertex

Performance

glframebuffer
{,2d,3d}

glcamera

Interoperability

Use glm::vec3 position, look_at -> glm::mat4 view

glgame

Bind everything together

Summary

Recap

  • Goal: Focus on exploring different techniques
  • Technologies: Main, Libraries, Exploration, Tools, Environment
  • Philosophy: Laying the puzzle, Data structures, Modularity