Lecrapouille/OpenGLCppWrapper

WIP

Opened this issue · 7 comments

Progress bar:

  • Update README: tutorial on Scene Graph: explanation on virtual update()
  • Version 0.6: add a framebuffer. Rethink examples. finalize moving headers in include/ and write in README a small Makefile for using this lib.
  • Version 0.7: check VBO size + add primitives + finish draw() (method with an implicit number of vertices, inheritance, dirty element for texture, hide private classes like GLLocation, VBO sizes checked)
  • Version 0.8:
  • Version 0.9: reworking folders of workspace
  • [WIP] Version 0.10: simplifying API, reworking/adding basic classes: Materials/Geometry, Fog, make Camera, Light as nodes of SceneGraph, Renderer. Access to attributes and location even if shaders have not yet been compiled. Renderer(Scene, Camera). Add BoundingBox for scene nodes.
  • Version 0.11: cleaning API. Add TrueType Fonts, float textures (update Mesa?), add more materials: bump mapping textures, GLSL includes, inside texture, working back to FrameBuffer
  • Version 0.12: UniformCollection, FloatTextures.
  • Version 1.0: Add GPUonlyTexture, GPUonlyVAO (no storage on CPU), Rethink how GLProgram stores Attributes and Uniforms

High:

  • [API] draw batch of elements
  • [API] Replace prog.draw(vao, ...) by vao.draw()
  • [CRITICAL] aa = VBO[i] makes pending the ith element while we are just reading it (= get()). No solution on how distinguish between set and get. To be tested: https://stackoverflow.com/questions/19217813/operator-c-get-set
  • WIP [API] Rework SceneGraph, Camera. Implement Light class. All are SceneGraph nodes.
  • [API] Create a Mesh class (Geometry class holding shaders). Make hide code vao.bind(); prog.draw(vao);
  • [API] Implement Renderer for SceneGraph.
  • [API] Replace GLProgram::setInitVBOSize(x) by bind(vao, x=0) ?
  • [FEATURE] Manage #include inside GLShaders https://github.com/tntmeijs/GLSL-Shader-Includes/blob/master/Shadinclude.hpp
  • [IMPROV] glBindBuffer(GL_ARRAY_BUFFER) + glEnableVertexAttribArray seems not necessary to be called every time this can save important OpenGL calls.
  • [FEATURE] GLumpy collection to be implemented
  • [CRITICAL] cannot attach local variables of shaders to GLProg because prog will hold pointers of local variables and be compiled outside this fonction and therefore using wrong references.
  • [MATHS] Check if *= does the product vector and no longer do componentProduct.
  • https://learnopengl.com/Advanced-OpenGL/Instancing
  • [BUG] Matrix transformation are transposed. Wrong results obtained in 07_AlphaTest.cpp
  • [TODO] Refresh Projection/view matrix on the scene tree for camera nodes when window resized/mouse moved.
  • [TODO] move vao->texture() to material->texture(). Fix DepthMaterial needs a loaded texture while not needed it.

Medium:

  • [FEATURE] GLWindow fullscreen mode. Add mask for glwindows and events: mouse move ... avoid calling dummy callbacks.
  • [FEATURE] GLWindow: create the callback onKeyPressed and onKeyReleased Update examples.
  • [FEATURE] Adapt GLWindow to manage multiple windows. See https://gist.github.com/SnopyDogy/a9a22497a893ec86aa3e
  • [API] Add iterator with a stack for iterating on SceneGraph nodes (see HeadFirst Design Pattern) (wont do)
  • [API] SceneGraph => visitor (like done in three_cpp)
  • [API] Load *.obj files
  • [API] BumpMapping textures.
  • [QUALITY] In example1 let suppose we forget to load a texture, a warning message occurred ERROR:GLTextures.hpp:246 Cannot setup texture with width or height set to 0 but this is not enough explicit: we need the VAO name ...
  • [QUALITY] Check number of VBOs (<= 16) inside VAO ? Idem for max number of framebuffers, uniforms.
  • [BUG] Wrong error message: Failed OpenGL program has not been bound to a VAO + Failed setting-up graphics => terminate called after throwing an instance of 'std::runtime_error' what(): The GLFW library is not initialized
  • [TUTO] Redo and simplify tutorials: Split README into several tutorial files. Separate OpenGL wrapper examples from finale API (hiding OpenGL wrapper).

Low:

  • Rename SceneGraph to Scene. Make a class 3DObject a SceneNode holding Material and Geometry. Do not let the user to have to write the recursivity for rendering or updating matrices.
  • [API] Reload Shaders? https://github.com/tntmeijs/GLSL-Shader-Includes
  • [API] release() as public or private ?
  • [API] Complete FrameBuffer class.
  • [BUG] FrameBuffer: resize window => image is broken.
  • [API] Not possible to do: m_vao_floor.texture2D("texID").interpolation(xx).load(...) because missing of virtual load() method in IGLTexture.
  • [API] Implement Node3D_SP operator[](std::string const& name) but fucked up by shared_from_this.
  • [FEATURE] PendingContainer modifies GPUMemory() but this container may be used without OpenGL and no data transferred to GPU. Change GPUMemory() only way data are transferred to GPU.
  • [FEATURE] Texture1D, Texture2DDepth, Texture3D (WIP: make an Example of texture3D http://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/code_v2/Texture3D/glut/Texture3D.cpp), TextureCube, Texture2DFloat to be implemented (for float check if the mesa has the good version supporting it https://www.mesa3d.org/index.html).
  • [FEATURE] Implement in IGLTexture::update() conversion to pending data to texture x,y,w,h (FIXME: OpenGL does not like it).
  • [FEATURE] VAO.VBOs and VAO.Textures holding data on CPU may be consuming too much RAM ie for a game. PendingContainer is only used for loading data during the startup of the project not anymore. Do a VBO and texture without pending container (maybe an identifier to pass in constructor and GLProgram knows how to interpret it and have an alternative of createVBO. Idea: VAO uses pointers for textures, VBOs and index ?
  • [MAKEFILE] Update Makefile to compile with OS X (see dev branch but the code is messy)
  • [API] Make this project to be a header-only project. (won't do)
  • [API] Wrapper for VectorXf and MatrixXXf for choosing the desired matrix library (glm, Armadillo, Eigen ...). And rename glwrap::Vector3f to glwrap::vec3f or glwrap::fvec3. Idea
#if MATRIX_LIB == USE_GLM
#include <glm>
using glwrap::Vector3f = glm::vec3f; 
#elif MATRIX_LIB == USE_ARMADILLO
#include <armadillo>
using glwrap::Vector3f = arma::fvec3; 
#elif MATRIX_LIB == USE_EIGEN
#include <egein>
using glwrap::Vector3f = egein::Vector3f; 
#else // Builtin
#include "Math/Matrix.hpp"
#endif

Armadillo:

// g++ -W -Wall armad.cpp -o prog -larmadillo -llapack -lblas
#include <armadillo>

int main()
{
  arma::fmat44 A; A.ones();
  std::cout << A * A << std::endl;
  std::cout << A * 4.0 << std::endl;
  std::cout << A.eye() * 4.0 << std::endl;

  arma::fvec3 x({1.0f, 0.0f, 0.0f});
  arma::fvec3 y({0.0f, 1.0f, 0.0f});
  std::cout << arma::dot(x, y) << std::endl;
  std::cout << arma::cross(x, y) << std::endl;
  return 0;
}
  • [API] Hide unnecessary classes to the developer (GLLocations, GLUniforms, Sampler ...)

  • [UNIT-TESTS] Check if OpenGL context is not yet created no segfault occurs by calling OpenGL functions

  • [UNIT-TESTS] Add more unit tests as checks on robustness when OpenGL context is not created or for example bind VAO to uncompiled program (or defining attributes before compiling a GLProgram).

  • [UNIT-TESTS] Complete unit tests and add Travis-CI

  • [UNIT-TESTS] Check destructor for every class (especially texture2D, Location)

  • [UNIT-TESTS] Add unit test: attrib and uniform with the same name. Is this possible?

  • [UNIT-TESTS] Can we do: m_prog.vector3f("textColor") = Vector3f({r, g, b}); when m_prog is not compiled ?

  • [LICENSE] Change to MIT ?

  • is possible to use sttruct => VBO:

struct Vertex { Vector3f Position; Vector4f Color; Vector2f TexCoords; };
attrib1.set<Vertex, Position>();
attrib2.set<Vertex, Color>();
attrib3.set<Vertex, TexCoords>(); 

Done:

  • Compute GPU memory. (TODO: also compute shader memory)
  • Pour compiler les exemples on utilise explicitemement le nom libopenglcppwrapper.a-0.6
  • Reserve an GLIndexBuffer inside VAO ? See Example 07
  • [API] Texture: Add new constructor(width, height) . Use pendingContainer for storing SOIL data instead of C array.
  • [API] Texture: Conflict between SOIL_LOAD_RGBA vs TextureOptions::cpuPixelFormat = PixelFormat::RGBA; (dev-textures branch)
  • [URGENT FEATURE] Move hpp files into include/. Install them through Makefile and generate and install a pkg-config .pc file for using my lib in another project.
  • [URGENT FEATURE] be sure that prog.attribute<>("foo") = xx; is the same thing than vao.attribute<>("foo") = xx; ==> make VAO::attribute() { return m_binded_prog.bind(this); m_binded_prog.attribute<>("foo"); }
  • [URGENT FEATURE] Maybe because of previous point we can simply:
    1. forbid prog.attribute("foo") ==> vao.T("foo") = ... ;
    2. replace prog.uniform<T>("foo") = ...; by prog.T("foo") = ...;
    3. I don't understand why vao1.VBO<Vector3f>("a_position") = { ... }; does not work when adding operator= in PendingContainer => I have to place this operator in GLVBO
  • [URGENT FEATURE] Implement a GLProgram method checking if all VBOs and uniforms have been set and VBOs have the same size. (WIP FIXME: cannot compile)
  • [API] missing GLProgram with a constructor with a reserved number of elements.
  • [URGENT FEATURE] Implement a GLProgram method checking if the VAO we want to bind with is compatible with the program (2 GLProgram creating each 1 VAO, the user bind a VAO to the wrong program)
  • ~~[URGENT FEATURE] Texture sampler has to follow the bound VAO (currently in Example1 texture is destroyed and created again at each cycle of the render loop). Add unit tests+ regression unit test: Example2 VAO not bound ~~
  • [URGENT FEATURE] Finish draw() methods: test and give an example with index buffer. Finish draw with an implicit number of vertices. Pass VAO as param to draw() methods.
  • [URGENT FEATURE] Remove unnecessary private classes like Logger, File, Maths, Singleton
  • [FEATURE] Framebuffer class to be implemented. (WIP still buggy)
  • [FEATURE] Rethink inheritance for Texture. Rename Texture3D as TextureCube and implement Texture3D.
  • [IMPROV] PendingContainer: std::valarray is not the best container (todo: add unit tests)
  • [IMPROV] Replace raw pointers by smart pointers in SceneGraph
  • [API] add namespace.
  • [API] Make GLBuffer and GLTexture2D have a common class ancestor (PendingContainer)
  • [API] throw OpenGL exceptions instead of std::exception
  • [API] Do not compile imgui into the lib but inside examples. Let compile the imgui wrapper. (wont do)
  • [API] Convert OpenGL constant into C++ enum when they are required into public API.
  • [API] Pass number of elements to reserved when creating VBOs
  • [API] Make opengl::createContext() more generic (initially made for gtkmm)
  • [API] Add SimTaDyn logger
  • [API] Fix license in headers
  • [API] Proper installation: move header code into include dir. Compile static and dynamic lib.
  • [API] use shaders 330 in examples.
  • [MATHS] Updating Vector.hpp and Matrix.hpp: uses method names from https://stanford.edu/class/ee103/julia_slides/julia_vectors_slides.pdf
    1. define template functions one() and zero(). See Lecrapouille/BacASable#1
    2. make alias method for magnitude() and norm(), length()
    3. add: addScaledVector(Vect, scal)
    4. change code operator*() for doing scalar product. Rename old code to: componentProduct()
    5. can be nice to add deviation, rms ...
  • [TUTO] Rewrite the SimTaDyn SceneGraph tutorial with this API (in debug)
  • [TUTO] Add the imgui SceneGraph as example.
  • [TUTO] Add an example with draw + index (EBO)
  • [TUTO] Framebuffer example
  • [TUTO] Multi-textures example
  • [TUTO] With some examples (ie 13), when resizing the window, the projection matrix is not correctly applied while others are ok (ie 04, 06).
  • [DOC] Missing document differences with glumpy and opengl4csharp
  • [CRASH] Fix in Example02 if we invert the position of m_cube and m_prog. This will produce a crash: the program wants to use a GPU released object.
  • [QUALITY] GLProgram output error when shaders failed to compile is totally messy with carriage returns!
  • [QUALITY] Init Makefile and directory for unit tests.

New API:

@startuml

class Canvas
class Renderer
class Camera
class Scene
class Light
class Mesh
class Material
class Color
class Texture
class Image
class Geometry
class Vertex
class Triangle

Canvas <-- Renderer
Renderer <-- Camera
Renderer <-- Scene
Camera -> Scene
Scene <-- Light
Scene <-- Mesh
Mesh <-- Material
Mesh <-- Geometry
Material <-- Color
Material <-- Texture
Texture <-- Image
Geometry <-- Vertex
Geometry <-- Triangle
Vertex <- Triangle

@enduml

  • Shape3D needs to starts the OpenGL program but when instances are member variables of GLWindow they are called before OpenGL context creation called inside GLWindow constructor.
  • SceneGraph: reused idea of OpenInventor: NodeSeparator, SwitchNode, LevelOfDetail, Separator ...
  • Make GLProgram check what uniform has not been set. Fix the regression (comment) GLProgram does not check Attribute sizes.
  • Replace BufferUsage::DYNAMIC_DRAW by BufferUsage::STATIC_DRAW
  • Shape3D: creer Material, passer option: GL_TRIANGLE, index8, ne pas heriter de Transformable mais a un Transform, add static create(), static GLProgram, compute face and vertice normals
  • add a factory Geometry3D::create(CUBE) => example 07.hpp replace m_cylinder by m_shape
  • add nbTriangle() depending on mode GL_TRIANGLE, STRIP, LOOP https://github.com/vahlers/scg3/blob/master/scg3/src/GeometryCore.cpp#L109
  • add classes Color, AABB,
  • make SkyBox a TextureCube with SepareNode3D
  • GLProgram returns list of failed textures
  • Remove all setup() { ... matrix44f("projection") = xxx; } because we are no sure than init fromonWindowSizeChanged()
  • Find nice solution concerning: OnWindowChange => update all projection matrices
  • Implement PendingContainer as https://github.com/seed93/vector/blob/master/vector.hpp or https://bitbucket.org/bitsquid/foundation/src/default/array.h remove unnecessary methods and define LNI_VECTOR_MAX_SZ = VBO_MAX_SIZE
  • Ex15: commuting shape not changed + fix transformation not applied
  • VBO add method applyMatrix. Shape3D apply on Position and normals
  • Add Frustum (culling)
  • Implement GLProgram::color3(string& name) as well for color4, uv, vertex
  • Shader/Camera: modelViewMatrix or viewMatrix * modelMatrix
  • Replace dynamic cast by Any structure for holding uniforms, attributes in Prog. Same idea for VBO and texture for VAO
  • Fucked up: ScenGraph: Currently Node3D::m_parent* would be better to be a weak_ptr in the aim to have uniform API: Node3D_SP getRoot() or finishing getNode() but enable_from_this suxx. Solution: Replace Node3D by uint32_t ?
  • URGENT: cannot access to uniforms while program is not compiled
  • Material::init() smashes values set by the user
  • TBD: Material: texture is linked to VAO: was made to avoid to define multiple materials but we want to write material.texture().load("xxx.jpg") instead of vao.texture().load("xxx.jpg")
  • URGENT: rework GLProgram for managing uniforms and attributes nicely: use https://gieseanw.wordpress.com/2017/05/03/a-true-heterogeneous-container-in-c/ but find a solution to be C++11 or maybe https://stackoverflow.com/questions/44105058/how-does-unitys-getcomponent-work
  • Geometry: simplify: remove all methods such as normals() use directly m_normals as public. Remove materials() because the material should not be changed ?
  • Fog is not working and how to set it up in the scene (root node only ? or fog by node ?) Cannot be placed on no-renderable nodes.
  • FlyWeight for duplicating mesh in scene nodes
  • Missing value for ALPHATEST
  • Add imgui in example with basic material for changing values (ie fog color, near, far ...)
  • Bug: onKeyboardEvent() is always called (07_AlphaTest)
  • Matrix transformation: I do not remember why glm matrix is transposed but seems that rotation and translation are buggy (07_AlphaTest)
  • Camera/Transformation: inheritance from a class Axis { m_front, m_right, m_up; };
  • Implement https://learnopengl.com/Advanced-OpenGL/Instancing pass an additional param to draw() (duplicated: see draw batch)
  • Allow to create Uniform Buffer Objects (UBO https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL) instead of uniform. Use it for camera and view/projection matrix . Hack for the developper to indicate if he wants uniform or UBO: use in GLSL #define UBO uniform + in shaders scan for UBO indicates it to prog which will instanciate the UBO inside the VAO.

Profiling performance to optimize:

  • Texture loading: 2.1ms for Texture2D::doLoad(): 2ms for SOIL and 0.062ms for copying SOIL data to vector.
  • 00_MisxLookAt (1000 cones to render) : draw() 12,9 ms = update 0.943 ms + render = 5.9 ms + clear buffers = 6.3 ms
struct appdata {
  float4 vertex : POSITION;
  float2 uv : TEXCOORD0;
};

struct v2f {
  float2 uv : TEXCOORD0;
  UNITY_FOG_COORDS(1)
  float4 vertex : SV_POSITION;
};

  sampler2D _MainTex;
  float4 _MainTex_ST;
  float4 _ColorA;
  float4 _ColorB;
  float4 _ColorC;

  v2f vert (appdata v) {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
  }

  float4 frag (v2f i) {
    float t = 1-i.uv.y;
    if (t < 0.5) {
      return lerp(_ColorA, _ColorB,t*2);
    }
    return lerp(_ColorB, _ColorC,(t-0.5)*2);
  }

Bug Mac OS X:

/Users/quentin/GitHub/OpenGLCppWrapper/src/UI/Window.cpp:194:8: warning: use of old-style cast [-Wold-style-cast]
if (!GLEW_VERSION_3_2)
^~~~~~~~~~~~~~~~
/usr/local/include/GL/glew.h:2372:26: note: expanded from macro 'GLEW_VERSION_3_2'
#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/GL/glew.h:23652:27: note: expanded from macro 'GLEW_GET_VAR'
#define GLEW_GET_VAR(x) ((const GLboolean)&x)

Bug:
GLERR: Attribute.hpp: 126: Failed executing 'glDisableVertexAttribArray(m_index)'. Reason is 'GL_INVALID_OPERATION'
GLERR: Attribute.hpp: 126: Failed executing 'glDisableVertexAttribArray(m_index)'. Reason is 'GL_INVALID_OPERATION'

Bug:
image ration not correctly set when windows is created

TODO: