forked from mixxxdj/mixxx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rendergraph library with opengl and scenegraph implementations
- Loading branch information
m0dB
authored and
m0dB
committed
Dec 1, 2024
1 parent
98012f3
commit c90bcad
Showing
88 changed files
with
3,052 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core) | ||
message(STATUS "Qt version ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}") | ||
|
||
if (QT_VERSION_MINOR GREATER_EQUAL 6) | ||
set(USE_QSHADER_FOR_GL ON) | ||
endif() | ||
|
||
add_subdirectory(opengl) | ||
add_subdirectory(scenegraph) | ||
add_subdirectory(../../res/shaders/rendergraph shaders) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
rendergraph is an abstraction layer that can be compiled with one of two backends: | ||
|
||
- scenegraph (QtQuick scene graph classes) | ||
- opengl (custom classes using QOpenGL) | ||
|
||
This abstraction layer follows the design of the QtQuick scene graph, with classes such as Material, Geometry, Node and GeometryNode, but it only gives access to and only uses a subset of its functionality. | ||
|
||
The scenegraph backend class the underlying QtQuick scene graph classes directly or almost directly. The opengl layer implements classes that mimic the behaviour of the | ||
Qt scene graph classes. | ||
|
||
The objective of rendergraph is to be able to write code that can be used verbatim within the context of both QWidgets applications and QML applications. This includes using the same Vulkan-style GLSL shader code for both. (The QSGMaterialShader uses the qsb files, QOpenGLShader uses the OpenGL shader code generated by qsb) | ||
|
||
Primarily, rendering with rendergraph uses a graph of Node's, typically of type GeometryNode. A GeometryNode uses a Geometry, which contains the vertex data of what the node renders (positional, texture coordinates, color information...) and a Material, which is the interface to the underlying shader. Uniform data is set through the Material. The QtQuick scene graph documentation is a good started point to understand the design. | ||
|
||
The code is organized as follows: | ||
|
||
common/rendergraph | ||
Public header files. This is the primary API, identical for both backends, and the only files that should be included to write code compatible with both backends. | ||
|
||
common | ||
Implementation of the functionality declared in the common/rendergraph headers that is identical for both backends. | ||
The general guideline is "code duplicated between the backends should be in the common layer". | ||
|
||
common/rendergraph/material | ||
Several basic 'materials' for common rendering operations (e.g. uniform or variying color, texture) | ||
|
||
scenegraph | ||
Implementation of the functionality declared in the common/rendergraph headers that is specific to call the scenegraph backend | ||
|
||
scenegraph/rendergraph | ||
Public header files specific for the opengl backend. This is the layer between QtQuick application code and the common rendergraph API. | ||
|
||
scenegraph/backend | ||
The scenegraph backend implementation, the layer between the common/rendergraph API and the underlying QtQuick scene graph classes. | ||
|
||
opengl | ||
Implementation of the functionality declared in the common/rendergraph headers that is specific to call the opengl backend | ||
|
||
opengl/rendergraph | ||
Public header files specific for the opengl backend. This is the layer between QWidgets/QOpenGL application code and the common rendergraph API. | ||
|
||
opengl/backend | ||
The opengl backend implementation, the layer between the common/rendergraph API and custom implemented classes that mimic the behaviour QtQuick scene graph classes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// rendergraph is a module but we want to include util/assert.h from Mixxx, | ||
// without adding the entire src/ dir to the include paths. | ||
#include "../../../util/assert.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#pragma once | ||
|
||
#include "rendergraph/types.h" | ||
|
||
namespace rendergraph { | ||
struct AttributeInit; | ||
} | ||
|
||
// helper to create an AttributeSet using an initializer_list | ||
struct rendergraph::AttributeInit { | ||
int m_tupleSize; | ||
PrimitiveType m_primitiveType; | ||
|
||
template<typename T> | ||
static AttributeInit create() { | ||
return AttributeInit{tupleSizeOf<T>(), primitiveTypeOf<T>()}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
|
||
#include "backend/baseattributeset.h" | ||
#include "rendergraph/attributeinit.h" | ||
|
||
namespace rendergraph { | ||
|
||
class AttributeSet : public BaseAttributeSet { | ||
public: | ||
AttributeSet(std::initializer_list<AttributeInit> list, const std::vector<QString>& names); | ||
}; | ||
|
||
template<typename... Ts, int N> | ||
AttributeSet makeAttributeSet(const QString (&names)[N]) { | ||
static_assert(sizeof...(Ts) == N, "Mismatch between number of attribute types and names"); | ||
return AttributeSet({(AttributeInit::create<Ts>())...}, | ||
std::vector<QString>(std::cbegin(names), std::cend(names))); | ||
} | ||
|
||
} // namespace rendergraph |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#pragma once | ||
|
||
#include <QVector2D> | ||
#include <QVector3D> | ||
|
||
#include "backend/basegeometry.h" | ||
#include "rendergraph/attributeset.h" | ||
|
||
namespace rendergraph { | ||
class Geometry; | ||
} // namespace rendergraph | ||
|
||
class rendergraph::Geometry : public rendergraph::BaseGeometry { | ||
public: | ||
using DrawingMode = rendergraph::DrawingMode; | ||
|
||
struct Point2D { | ||
QVector2D position2D; | ||
}; | ||
|
||
struct TexturedPoint2D { | ||
QVector2D position2D; | ||
QVector2D texcoord2D; | ||
}; | ||
|
||
struct RGBColoredPoint2D { | ||
QVector2D position2D; | ||
QVector3D color3D; | ||
}; | ||
|
||
struct RGBAColoredPoint2D { | ||
QVector2D position2D; | ||
QVector4D color4D; | ||
}; | ||
|
||
Geometry(const rendergraph::AttributeSet& attributeSet, int vertexCount); | ||
|
||
const Attribute* attributes() const { | ||
return BaseGeometry::attributes(); | ||
} | ||
|
||
void setAttributeValues(int attributePosition, const float* data, int numTuples); | ||
|
||
int attributeCount() const { | ||
return BaseGeometry::attributeCount(); | ||
} | ||
|
||
void allocate(int vertexCount) { | ||
BaseGeometry::allocate(vertexCount); | ||
} | ||
|
||
int sizeOfVertex() const { | ||
return BaseGeometry::sizeOfVertex(); | ||
} | ||
int vertexCount() const { | ||
return BaseGeometry::vertexCount(); | ||
} | ||
|
||
template<typename T> | ||
T* vertexDataAs() { | ||
return reinterpret_cast<T*>(vertexData()); | ||
} | ||
|
||
DrawingMode drawingMode() const; | ||
|
||
void setDrawingMode(DrawingMode mode); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#pragma once | ||
|
||
#include "backend/basegeometrynode.h" | ||
#include "rendergraph/geometry.h" | ||
#include "rendergraph/material.h" | ||
#include "rendergraph/nodeinterface.h" | ||
|
||
namespace rendergraph { | ||
class GeometryNode; | ||
} // namespace rendergraph | ||
|
||
class rendergraph::GeometryNode : public rendergraph::NodeInterface<rendergraph::BaseGeometryNode> { | ||
public: | ||
GeometryNode(); | ||
virtual ~GeometryNode() = default; | ||
|
||
template<class T_Material> | ||
void initForRectangles(int numRectangles) { | ||
const int verticesPerRectangle = 6; // 2 triangles | ||
setGeometry(std::make_unique<Geometry>(T_Material::attributes(), | ||
numRectangles * verticesPerRectangle)); | ||
setMaterial(std::make_unique<T_Material>()); | ||
geometry().setDrawingMode(DrawingMode::Triangles); | ||
} | ||
|
||
void setUsePreprocess(bool value); | ||
void setMaterial(std::unique_ptr<Material> material); | ||
void setGeometry(std::unique_ptr<Geometry> geometry); | ||
|
||
Geometry& geometry() const; | ||
Material& material() const; | ||
|
||
void markDirtyGeometry(); | ||
void markDirtyMaterial(); | ||
|
||
private: | ||
std::unique_ptr<Material> m_pMaterial; | ||
std::unique_ptr<Geometry> m_pGeometry; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#include "backend/basematerial.h" | ||
#include "rendergraph/assert.h" | ||
#include "rendergraph/materialshader.h" | ||
#include "rendergraph/materialtype.h" | ||
#include "rendergraph/texture.h" | ||
#include "rendergraph/uniformscache.h" | ||
#include "rendergraph/uniformset.h" | ||
|
||
namespace rendergraph { | ||
class Material; | ||
} // namespace rendergraph | ||
|
||
class rendergraph::Material : public rendergraph::BaseMaterial { | ||
public: | ||
Material(const UniformSet& uniformSet); | ||
virtual ~Material(); | ||
|
||
// see QSGMaterial::compare. | ||
// TODO decide if this should be virtual. QSGMaterial::compare is virtual | ||
// to concrete Material can implement a compare function, but in rendergraph | ||
// we can compare the uniforms cache and texture already here, which seems | ||
// sufficient. | ||
int compare(const Material* pOther) const { | ||
DEBUG_ASSERT(type() == pOther->type()); | ||
int cacheCompareResult = std::memcmp(m_uniformsCache.data(), | ||
pOther->m_uniformsCache.data(), | ||
m_uniformsCache.size()); | ||
if (cacheCompareResult != 0) { | ||
return cacheCompareResult < 0 ? -1 : 1; | ||
} | ||
// TODO multiple textures | ||
if (!texture(0) || !pOther->texture(0)) { | ||
return texture(0) ? 1 : -1; | ||
} | ||
|
||
const qint64 diff = texture(0)->comparisonKey() - pOther->texture(0)->comparisonKey(); | ||
return diff < 0 ? -1 : (diff > 0 ? 1 : 0); | ||
} | ||
|
||
virtual std::unique_ptr<MaterialShader> createShader() const = 0; | ||
|
||
template<typename T> | ||
void setUniform(int uniformIndex, const T& value) { | ||
m_uniformsCache.set(uniformIndex, value); | ||
m_uniformsCacheDirty = true; | ||
} | ||
|
||
const UniformsCache& uniformsCache() const { | ||
return m_uniformsCache; | ||
} | ||
|
||
bool clearUniformsCacheDirty() { | ||
if (m_uniformsCacheDirty) { | ||
m_uniformsCacheDirty = false; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
virtual Texture* texture(int) const { | ||
return nullptr; | ||
} | ||
|
||
private: | ||
UniformsCache m_uniformsCache; | ||
bool m_uniformsCacheDirty{}; | ||
}; |
33 changes: 33 additions & 0 deletions
33
src/rendergraph/common/rendergraph/material/endoftrackmaterial.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "endoftrackmaterial.h" | ||
|
||
#include <QVector2D> | ||
|
||
#include "rendergraph/materialshader.h" | ||
#include "rendergraph/materialtype.h" | ||
#include "rendergraph/uniformset.h" | ||
|
||
using namespace rendergraph; | ||
|
||
EndOfTrackMaterial::EndOfTrackMaterial() | ||
: Material(uniforms()) { | ||
} | ||
|
||
/* static */ const AttributeSet& EndOfTrackMaterial::attributes() { | ||
static AttributeSet set = makeAttributeSet<QVector2D, float>({"position", "gradient"}); | ||
return set; | ||
} | ||
|
||
/* static */ const UniformSet& EndOfTrackMaterial::uniforms() { | ||
static UniformSet set = makeUniformSet<QVector4D>({"ubuf.color"}); | ||
return set; | ||
} | ||
|
||
MaterialType* EndOfTrackMaterial::type() const { | ||
static MaterialType type; | ||
return &type; | ||
} | ||
|
||
std::unique_ptr<MaterialShader> EndOfTrackMaterial::createShader() const { | ||
return std::make_unique<MaterialShader>( | ||
"endoftrack.vert", "endoftrack.frag", uniforms(), attributes()); | ||
} |
19 changes: 19 additions & 0 deletions
19
src/rendergraph/common/rendergraph/material/endoftrackmaterial.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include "rendergraph/attributeset.h" | ||
#include "rendergraph/material.h" | ||
|
||
namespace rendergraph { | ||
class EndOfTrackMaterial; | ||
} | ||
|
||
class rendergraph::EndOfTrackMaterial : public rendergraph::Material { | ||
public: | ||
EndOfTrackMaterial(); | ||
|
||
static const AttributeSet& attributes(); | ||
|
||
static const UniformSet& uniforms(); | ||
|
||
MaterialType* type() const override; | ||
|
||
std::unique_ptr<MaterialShader> createShader() const override; | ||
}; |
33 changes: 33 additions & 0 deletions
33
src/rendergraph/common/rendergraph/material/patternmaterial.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "patternmaterial.h" | ||
|
||
#include <QMatrix4x4> | ||
#include <QVector2D> | ||
|
||
#include "rendergraph/materialshader.h" | ||
#include "rendergraph/materialtype.h" | ||
|
||
using namespace rendergraph; | ||
|
||
PatternMaterial::PatternMaterial() | ||
: Material(uniforms()) { | ||
} | ||
|
||
/* static */ const AttributeSet& PatternMaterial::attributes() { | ||
static AttributeSet set = makeAttributeSet<QVector2D, QVector2D>({"position", "texcoord"}); | ||
return set; | ||
} | ||
|
||
/* static */ const UniformSet& PatternMaterial::uniforms() { | ||
static UniformSet set = makeUniformSet<QMatrix4x4>({"ubuf.matrix"}); | ||
return set; | ||
} | ||
|
||
MaterialType* PatternMaterial::type() const { | ||
static MaterialType type; | ||
return &type; | ||
} | ||
|
||
std::unique_ptr<MaterialShader> PatternMaterial::createShader() const { | ||
return std::make_unique<MaterialShader>( | ||
"pattern.vert", "pattern.frag", uniforms(), attributes()); | ||
} |
32 changes: 32 additions & 0 deletions
32
src/rendergraph/common/rendergraph/material/patternmaterial.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include "rendergraph/attributeset.h" | ||
#include "rendergraph/material.h" | ||
#include "rendergraph/texture.h" | ||
#include "rendergraph/uniformset.h" | ||
|
||
namespace rendergraph { | ||
class PatternMaterial; | ||
} | ||
|
||
class rendergraph::PatternMaterial : public rendergraph::Material { | ||
public: | ||
PatternMaterial(); | ||
|
||
static const AttributeSet& attributes(); | ||
|
||
static const UniformSet& uniforms(); | ||
|
||
MaterialType* type() const override; | ||
|
||
std::unique_ptr<MaterialShader> createShader() const override; | ||
|
||
Texture* texture(int) const override { | ||
return m_pTexture.get(); | ||
} | ||
|
||
void setTexture(std::unique_ptr<Texture> texture) { | ||
m_pTexture = std::move(texture); | ||
} | ||
|
||
private: | ||
std::unique_ptr<Texture> m_pTexture; | ||
}; |
Oops, something went wrong.