This is the first C++ example demonstrating Graph resolution independent GPU curve rendering.
This is the first C++ example demonstrating Graph resolution independent GPU curve rendering.Multiple complex shapes are rotated with front- and back-face as well as per-pixel-lighting.
#include <cstdio>
#include <cmath>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "../demos/graph/testshapes/Glyph05FreeSerifBoldItalic_ae.hpp"
#include "../demos/graph/testshapes/Glyph03FreeMonoRegular_M.hpp"
#include "../demos/GLLauncher01.hpp"
public:
struct GraphRendererProps {
};
private:
GraphRendererProps m_props;
bool m_initialized;
public:
constexpr bool usesNormal()
const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
static constexpr std::string_view
GLSL_USE_LIGHT0 =
"#define USE_LIGHT0 1\n";
static constexpr std::string_view
GLSL_MAIN_BEGIN =
"void main (void)\n{\n";
static constexpr std::string_view
gcuTexture2D =
"gcuTexture2D";
static constexpr std::string_view
source_dir =
"impl/graph/glsl";
static constexpr std::string_view
bin_dir =
"impl/graph/glsl/bin";
public:
: m_st(st),
m_initialized(false)
{ }
constexpr bool initialized()
const noexcept {
return m_initialized; }
std::string vertexShaderName, fragmentShaderName;
if( m_props.m_isTwoPass ) {
vertexShaderName.append("-pass").append(m_props.m_pass1 ? "1":"2");
} else {
vertexShaderName.append("-single");
}
if( !rsVp || !rsFp ) {
return false;
}
{
size_t posVp = rsVp->defaultShaderCustomization(
gl);
size_t posFp = rsFp->defaultShaderCustomization(
gl);
if( posVp == std::string::npos || posFp == std::string::npos ) {
return false;
}
posFp = -1;
if( m_props.m_hasDiscard ) {
}
if( m_props.m_hasFrustumClipping ) {
}
}
if( m_props.m_hasLight0 ) {
}
if( m_props.m_hasColorChannel ) {
}
if( m_props.m_hasColorTexture ) {
}
if( posVp == std::string::npos ) {
return false;
}
posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/constants.glsl"));
if( posFp == std::string::npos ) {
return false;
}
posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/uniforms.glsl"));
if( posFp == std::string::npos ) {
return false;
}
posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/varyings.glsl"));
if( posFp == std::string::npos ) {
return false;
}
if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/functions.glsl"));
if( posFp == std::string::npos ) {
return false;
}
}
std::string passS = m_props.m_pass1 ? "-pass1-" : "-pass2-";
jau::PLAIN_PRINT(
true,
"RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
}
posFp = rsFp->insertShaderSourceFile(0, posFp, shaderSegment);
if( posFp == std::string::npos ) {
return false;
}
posFp = rsFp->insertShaderSource(0, posFp, "}\n");
if( posFp == std::string::npos ) {
return false;
}
if( m_props.m_hasColorTexture ) {
}
}
if( !sp0->add(
gl, rsVp,
true) || !sp0->add(
gl, rsFp,
true) ) {
return false;
}
m_initialized = sp0->inUse();
if( !m_initialized ) {
}
return m_initialized;
}
}
};
public:
private:
bool m_initialized;
int m_num_vertices, m_num_indices;
public:
: m_renderer(renderer), m_st(st),
m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
m_num_vertices(0), m_num_indices(0)
{
m_array->addGLSLSubArray("gca_Vertex", 3, GL_ARRAY_BUFFER);
m_array->addGLSLSubArray("gca_CurveParam", 3, GL_ARRAY_BUFFER);
m_array->addGLSLSubArray("gca_Normal", 3, GL_ARRAY_BUFFER);
}
}
constexpr bool initialized() const noexcept {
return m_initialized; }
void seal(
GL& gl,
bool seal_) {
if( !m_initialized ) {
return;
}
m_array->seal(gl, seal_);
m_indices->seal(gl, seal_);
m_array->enableBuffer(gl, false);
m_indices->enableBuffer(gl, false);
}
m_array->put3f(v.
coord());
if( m_renderer.usesNormal() ) {
m_array->put3f(normal);
}
++m_num_vertices;
}
m_indices->putN(i, j, k);
m_num_indices += 3;
}
void pushNewVerticesIdx(
const Vertex& vertIn1,
const Vertex& vertIn2,
const Vertex& vertIn3,
const Vec3f& normal) {
pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
}
if( Graph::DEBUG_MODE ) {
jau::PLAIN_PRINT(
true,
"add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
}
if( Graph::DEBUG_MODE ) {
}
{
m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
}
uint32_t idxOffset = m_num_vertices;
if( vertsIn.
size() >= 3 ) {
for(const Vertex& v : vertsIn) {
}
constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() / sizeof(uint32_t);
OutlineShape::size_type trisIn_sz = trisIn.
size();
for(OutlineShape::size_type i=0; i < trisIn_sz; ++i) {
Triangle::trivert_t& triInVertices = triIn->vertices();
uint32_t tv0Idx = triInVertices[0].id();
if ( max_index - idxOffset > tv0Idx ) {
triInVertices[1].id()+idxOffset,
triInVertices[2].id()+idxOffset);
} else {
}
}
}
if( Graph::DEBUG_MODE ) {
jau::PLAIN_PRINT(
true,
"add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
}
}
if( !m_initialized ) {
return;
}
m_renderer.useProgram(gl, true);
m_array->enableBuffer(gl, true);
m_indices->bindBuffer(gl, true);
::glEnable(GL_BLEND);
::glBlendEquation(GL_FUNC_ADD);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT, nullptr);
m_indices->bindBuffer(gl, false);
m_array->enableBuffer(gl, false);
}
};
typedef std::shared_ptr<Shape>
ShapeRef;
private:
ShaderState& m_st;
OutlineShape m_oshape;
float m_zOffset;
GraphRenderer& m_renderer;
GraphRegion m_region;
bool iMatIdent = true;
bool iMatDirty = false;
struct Private{ explicit Private() = default; };
public:
: m_st(st), m_pmvMatUni(
std::
move(pmvMatU)), m_oshape(3, 16),
m_renderer(renderer), m_region(m_renderer, m_st)
{
m_uColor = GLUniformVec4f::create(
"gcu_StaticColor",
Vec4f(0, 0, 0, 1));
m_st.ownUniform(m_uColor, true);
}
return std::make_shared<Shape>(Private(), st, std::move(pmvMatU), renderer);
}
constexpr const Vec3f&
position() const noexcept {
return m_position; }
constexpr Vec3f&
position() noexcept { iMatDirty=
true;
return m_position; }
constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
constexpr const Quat4f&
rotation() const noexcept {
return m_rotation; }
constexpr Quat4f&
rotation() noexcept { iMatDirty=
true;
return m_rotation; }
constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
constexpr const OutlineShape&
outlines() const noexcept {
return m_oshape; }
constexpr OutlineShape&
outlines() noexcept {
return m_oshape; }
const Vec4f&
color() const noexcept {
return m_uColor->vec4f(); }
m_region.addOutlineShape(m_oshape);
m_region.seal(gl, true);
}
applyMatToMv(pmv);
m_st.pushUniform(gl, m_pmvMatUni);
m_st.pushUniform(gl, m_uColor);
m_region.draw(gl);
}
private:
void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
if( iMatDirty ) {
updateMat();
}
if( !iMatIdent ) {
pmvMat.mulMv(iMat);
}
}
void updateMat() noexcept {
bool hasPos = !m_position.is_zero();
bool hasRotate = !m_rotation.isIdentity();
bool hasRotPivot = false;
const Vec3f& ctr = m_oshape.bounds().center();
bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
if( sameScaleRotatePivot ) {
iMatIdent = false;
iMat.setToTranslation(m_position);
iMat.translate(
Vec3f(ctr).mul(m_scale));
iMat.rotate(m_rotation);
iMat.scale(m_scale);
iMat.translate(-ctr);
} else if( hasRotate || hasScale ) {
iMatIdent = false;
iMat.setToTranslation(m_position);
if( hasRotate ) {
if( hasRotPivot ) {
iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
iMat.rotate(m_rotation);
iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
} else {
iMat.translate(
Vec3f(ctr).mul(m_scale));
iMat.rotate(m_rotation);
iMat.translate(
Vec3f(-ctr).mul(m_scale));
}
}
if( hasScale ) {
iMat.translate(
Vec3f(ctr).mul(m_scale));
iMat.scale(m_scale);
iMat.translate(
Vec3f(-ctr).mul(m_scale));
}
} else if( hasPos ) {
iMatIdent = false;
iMat.setToTranslation(m_position);
} else {
iMatIdent = true;
iMat.loadIdentity();
}
iMatDirty = false;
}
};
private:
constexpr static float zNear= 1.0f;
constexpr static float zFar =100.0f;
constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
ShaderState m_st;
bool m_initialized;
bool m_animating = true;
bool m_oneframe = false;
jau::fraction_timespec m_tlast;
GraphRenderer m_renderer;
std::vector<ShapeRef> m_shapes;
public:
m_initialized(false),
m_pmvMatUni(GLUniformSyncPMVMat4f::create("gcu_PMVMatrix", mat_req)),
m_renderer(m_st)
{
}
PMVMat4f&
pmv() noexcept {
return m_pmvMatUni->pmv(); }
const PMVMat4f&
pmv() const noexcept {
return m_pmvMatUni->pmv(); }
bool animating() const noexcept {
return m_animating; }
bool&
animating() noexcept {
return m_animating; }
void setOneFrame() noexcept { m_animating=
false; m_oneframe=
true; }
bool init(
const WindowRef& win,
const jau::fraction_timespec& when)
override {
m_tlast = when;
pmv.getP().loadIdentity();
pmv.getMv().loadIdentity();
m_st.ownUniform(m_pmvMatUni, true);
if( !m_renderer.init(gl, when) ) {
win->dispose(when);
return false;
}
m_st.ownUniform(lightU, true);
m_st.pushAllUniforms(gl);
const float lineWidth = 1/2.5f;
const float dz = 0.005f;
if( true ) {
const float width = 1.5f;
const float height = 1.5f;
float lwh = lineWidth/2.0f;
float twh = width/2.0f;
float thh = height/2.0f;
float ctrX = 0, ctrY = 0, ctrZ = dz;
m_shapes.push_back(frontShape);
OutlineShape& oshape = frontShape->
outlines();
oshape.
moveTo(ctrX-lwh, ctrY+thh, ctrZ);
oshape.
lineTo(ctrX-lwh, ctrY+lwh, ctrZ);
oshape.
lineTo(ctrX-twh, ctrY+lwh, ctrZ);
oshape.
lineTo(ctrX-twh, ctrY-lwh, ctrZ);
oshape.
lineTo(ctrX-lwh, ctrY-lwh, ctrZ);
oshape.
lineTo(ctrX-lwh, ctrY-thh, ctrZ);
oshape.
lineTo(ctrX+lwh, ctrY-thh, ctrZ);
oshape.
lineTo(ctrX+lwh, ctrY-lwh, ctrZ);
oshape.
lineTo(ctrX+twh, ctrY-lwh, ctrZ);
oshape.
lineTo(ctrX+twh, ctrY+lwh, ctrZ);
oshape.
lineTo(ctrX+lwh, ctrY+lwh, ctrZ);
oshape.
lineTo(ctrX+lwh, ctrY+thh, ctrZ);
oshape.
lineTo(ctrX-lwh, ctrY+thh, ctrZ);
m_shapes.push_back(backShape);
}
if( true) {
m_shapes.push_back(frontShape);
OutlineShape& oshape = frontShape->
outlines();
oshape.
moveTo(0.0f,-10.0f, 0);
oshape.
lineTo(15.0f,-10.0f, 0);
oshape.
quadTo(10.0f,5.0f,0, 15.0f,10.0f,0);
oshape.
cubicTo(6.0f,15.0f,0, 5.0f,8.0f,0, 0.0f,10.0f,0);
oshape.
quadTo(10.0f,-5.0f,0, 10.0f,0.0f,0);
oshape.
quadTo(5.0f,0.0f,0, 5.0f,-5.0f,0);
{
oshape.
outlines()[0].setWinding(Winding::CCW);
oshape.
outlines()[1].setWinding(Winding::CW);
}
frontShape->
scale().
x *= 0.1f;
frontShape->
scale().
y *= 0.1f;
m_shapes.push_back(backShape);
}
if ( true ) {
m_shapes.push_back(frontShape);
OutlineShape& oshape = frontShape->
outlines();
frontShape->
scale().
x *= 2.0f;
frontShape->
scale().
y *= 2.0f;
m_shapes.push_back(backShape);
}
if ( true ) {
m_shapes.push_back(frontShape);
OutlineShape& oshape = frontShape->
outlines();
frontShape->
scale().
x *= 2.0f;
frontShape->
scale().
y *= 2.0f;
m_shapes.push_back(backShape);
}
::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
::glEnable(GL_DEPTH_TEST);
::glDisable(GL_CULL_FACE);
m_initialized = true;
if( !m_initialized ) {
m_st.destroy(gl);
win->dispose(when);
}
return m_initialized;
}
void dispose(
const WindowRef& win,
const jau::fraction_timespec& when)
override {
m_initialized = false;
}
pmv.getP().loadIdentity();
const float aspect = 1.0f;
const float fovy_deg=45.0f;
const float aspect2 = ( (float) m_viewport.width() / (float) m_viewport.height() ) / aspect;
m_st.useProgram(gl, true);
m_st.pushUniform(gl, m_pmvMatUni);
}
void display(
const WindowRef& win,
const jau::fraction_timespec& when)
override {
if( !m_initialized ) {
return;
}
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_st.useProgram(gl, true);
pmv.getMv().loadIdentity();
pmv.translateMv(0, 0, -5);
constexpr double angle_per_sec = 30;
const float rad = (float) ( (when - m_tlast).to_double() * angle_per_sec );
}
s->draw(gl);
}
m_oneframe = false;
m_tlast = when;
}
std::string
toStringImpl() const noexcept
override {
return "GraphShapes01"; }
};
private:
class MyKeyListener : public KeyListener {
private:
public:
void keyPressed(KeyEvent& e, const KeyboardTracker& kt) override {
if( e.
keySym() == VKeyCode::VK_ESCAPE ) {
if( win ) {
}
}
else if( e.
keySym() == VKeyCode::VK_PAUSE || e.
keySym() == VKeyCode::VK_P ) {
m_parent.animating() = !m_parent.animating();
}
else if( e.
keySym() == VKeyCode::VK_PERIOD ) {
m_parent.setOneFrame();
}
else if( e.
keySym() == VKeyCode::VK_W ) {
}
}
void keyReleased(KeyEvent& e, const KeyboardTracker& kt) override {
}
};
typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
MyKeyListenerRef m_kl;
public:
m_kl(
std::make_shared<MyKeyListener>(*this)) { }
bool init(
const WindowRef& win,
const jau::fraction_timespec& when)
override {
return false;
}
win->addKeyListener(m_kl);
return true;
}
void dispose(
const WindowRef& win,
const jau::fraction_timespec& when)
override {
win->removeKeyListener(m_kl);
}
};
int main(
int argc,
char *argv[])
{
return launch(
"GraphShapes01.cpp",
std::make_shared<Example>(), argc, argv);
}
int launch(std::string_view sfile, GLLaunchProps props, const RenderListenerRef &demo, int argc, char *argv[])
int main(int argc, char *argv[])
std::shared_ptr< Shape > ShapeRef
std::shared_ptr< Shape > ShapeRef
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
static void addShapeToRegion(gamp::graph::OutlineShape &shape)
static void addShapeToRegion(gamp::graph::OutlineShape &shape)
constexpr bool initialized() const noexcept
void addOutlineShape(OutlineShape &shape)
void pushVertex(const Vertex &v, const Vec3f &normal)
jau::darray< uint32_t, glmemsize_t > u32buffer_t
void pushNewVerticesIdx(const Vertex &vertIn1, const Vertex &vertIn2, const Vertex &vertIn3, const Vec3f &normal)
GraphRegion(GraphRenderer &renderer, ShaderState &st)
void pushIndices(uint32_t i, uint32_t j, uint32_t k)
void seal(GL &gl, bool seal_)
static constexpr std::string_view GLSL_USE_LIGHT0
static constexpr std::string_view GLSL_MAIN_BEGIN
static constexpr std::string_view gcuTexture2D
static constexpr std::string_view GLSL_PARAM_COMMENT_START
static constexpr std::string_view GLSL_USE_DISCARD
static constexpr std::string_view colTexLookupFuncName
static constexpr std::string_view bin_dir
static constexpr std::string_view GLSL_PARAM_COMMENT_END
constexpr GLsizei arrayCompsPerElement() const noexcept
constexpr bool initialized() const noexcept
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
static constexpr std::string_view GLSL_USE_COLOR_TEXTURE
constexpr bool usesNormal() const noexcept
static constexpr std::string_view source_dir
static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING
static constexpr std::string_view GLSL_USE_COLOR_CHANNEL
static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT
GraphRenderer(ShaderState &st)
static constexpr std::string_view shader_basename
void useProgram(GL &gl, bool on)
static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
void setOneFrame() noexcept
bool animating() const noexcept
std::string toStringImpl() const noexcept override
void display(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
PMVMat4f & pmv() noexcept
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
Recti & viewport() noexcept
constexpr const float & zOffset() const noexcept
void setColor(const Vec4f &c) noexcept
constexpr const Quat4f & rotation() const noexcept
static ShapeRef create(ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer &renderer)
constexpr const Vec3f & rotationPivot() const noexcept
constexpr const Vec3f & position() const noexcept
const Vec4f & color() const noexcept
constexpr const Vec3f & scale() const noexcept
constexpr const OutlineShape & outlines() const noexcept
Shape(Private, ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer &renderer)
constexpr size_type addedVertexCount() const noexcept
Return the number of newly added vertices during getTriangles(VerticesState) while transforming the o...
const VertexList & getVertices()
Return list of concatenated vertices associated with all Outlines of this object.
void clearCache() noexcept
Clears cached triangulated data, i.e.
void cubicTo(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
Add a cubic Bézier curve segment, intersecting the last point and the second given point x3/y3 (P3).
const OutlineList & outlines() const noexcept
void quadTo(float x1, float y1, float z1, float x2, float y2, float z2)
Add a quadratic curve segment, intersecting the last point and the second given point x2/y2 (P2).
constexpr const Vec3f & normal() const noexcept
Normal vector, optionally used by tesselator to add (interleaved) normals.
void moveTo(float x, float y, float z)
Start a new position for the next line segment at given point x/y (P1).
void closePath()
Closes the current sub-path segment by drawing a straight line back to the coordinates of the last mo...
const TriangleRefList & getTriangles(VertexState destinationType=VertexState::quadratic_nurbs)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
OutlineShape flipFace(float zoffset=0) const
Returns a copy of this instance with normal() and all outlines() vertices()'s z-axis sign-flipped,...
void lineTo(float x, float y, float z)
Add a line segment, intersecting the last point and the given point x/y (P1).
constexpr const Vec3f & texCoord() const noexcept
constexpr const Vec3f & coord() const noexcept
static GLContext & downcast(RenderContext *rc)
Downcast dereferenced given RenderContext* to GLContext&, throws exception if signature doesn't match...
Specifies the OpenGL profile.
static constexpr std::string_view GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
static ShaderCodeRef create(GLenum type, size_t count, const source_list_t &sources) noexcept
static ShaderProgramRef create() noexcept
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
void destroy(GL &gl)
Calls release(gl, true, true, true).
void useProgram(GL &gl, bool on)
Turns the shader program on or off.
void pushAllUniforms(const GL &gl)
Same as pushUniform(), but for all active uniforms.
void ownAttribute(const GLArrayDataRef &attr, bool own)
Binds or unbinds the GLArrayData lifecycle to this ShaderState.
bool attachShaderProgram(GL &gl, const ShaderProgramRef &prog, bool enable)
Attach or switch a shader program.
constexpr RenderListener(Private) noexcept
Private ctor for shared_ptr<RenderListener> instance method w/o public ctor.
std::string toString() const noexcept
std::string toString() const noexcept
constexpr VKeyCode keySym() const noexcept
Returns the virtual key symbol reflecting the current keyboard layout.
virtual const PressedKeyCodes & pressedKeyCodes() const noexcept=0
constexpr const WindowWeakPtr & source() const noexcept
constexpr const jau::fraction_timespec & when() const noexcept
size_type count() const noexcept
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
constexpr size_type size() const noexcept
Like std::vector::size().
static constexpr const value_type one
constexpr_cxx20 PMVMatrix4 & popMv() noexcept
Pop the modelview matrix from its stack.
constexpr_cxx20 PMVMatrix4 & pushMv() noexcept
Push the modelview matrix to its stack, while preserving its values.
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
@ std
Denotes a func::std_target_t.
GLArrayDataServer< float > GLFloatArrayDataServer
GLsizeiptr glmemsize_t
Compatible with ssize_t.
std::shared_ptr< GLUniformSyncPMVMat4f > GLUniformSyncPMVMat4fRef
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
GLArrayDataServerRef< uint32_t > GLUIntArrayDataServerRef
std::shared_ptr< GLUniformVec3f > GLUniformVec3fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
jau::darray< Vertex, uint32_t > VertexList
std::shared_ptr< Triangle > TriangleRef
jau::darray< TriangleRef, uint32_t > TriangleRefList
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowRef
PMVData
PMVMatrix4 derived matrices and values.
Quaternion< float > Quat4f
std::string to_string(const math_error_t v) noexcept
Returns std::string representation of math_error_t.
PMVMatrix4< float > PMVMat4f
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
bool m_hasFrustumClipping
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
constexpr uint64_t to_ms() const noexcept
Returns time in milliseconds.