Gamp: GearsES2.hpp (original) (raw)

#ifndef GAMP_DEMOS_GEARSES02_HPP_

#define GAMP_DEMOS_GEARSES02_HPP_

#include

#include

#include

#include

public:

private:

int m_name;

bool m_useMappedBuffers;

bool m_picked;

private:

GLFloatArrayDataServerSRef createInterleaved(bool useMappedBuffers, GLsizei compsPerElem, bool normalized, GLsizei initialSize, GLenum vboUsage) {

if( useMappedBuffers ) {

} else {

}

}

array->addGLSLSubArray("gca_Vertex", compsPerElem, GL_ARRAY_BUFFER);

array->addGLSLSubArray("gca_Normal", compsPerElem, GL_ARRAY_BUFFER);

}

array->put3f(x, y, z);

array->put3f(n);

m_objbox.resize(x, y, z);

}

static void sincos(float x, float sin[], int sinIdx, float cos[], int cosIdx) {

sin[sinIdx] = std::sin(x);

cos[cosIdx] = std::cos(x);

}

array->enableBuffer(gl, true);

array->enableBuffer(gl, false);

}

void associate(ShaderState& st) {

m_frontFace->associate(st, true);

m_frontSide->associate(st, true);

m_backFace->associate(st, true);

m_backSide->associate(st, true);

m_outwardFace->associate(st, true);

m_insideRadiusCyl->associate(st, true);

}

if( 0 < array->vboName() ) {

array->enableBuffer(gl, true);

::glDrawArrays(mode, 0, array->elemCount());

array->enableBuffer(gl, false);

}

}

public:

float inner_radius, float outer_radius,

float width,

GLsizei teeth,

float tooth_depth,

GLUniformSyncPMVMat4f &pmvMatUni, GLUniformVec4f &colorUniform)

: m_name(name), m_st(st), m_pmvMatUni(pmvMatUni),

m_colorUniform(colorUniform), m_gearColor(gearColor), m_tx(tx),

m_useMappedBuffers(false), m_picked(false), m_objbox(), m_viewbox(), m_PMvi() {

const float dz = width * 0.5f;

float u, v, len;

float s[5];

float c[5];

const float r0 = inner_radius;

const float r1 = outer_radius - tooth_depth / 2.0f;

const float r2 = outer_radius + tooth_depth / 2.0f;

const float da = 2.0f * std:🔢:pi_v / float(teeth) / 4.0f;

s[4] = 0;

c[4] = 1;

const GLenum vboUsage = GL_STATIC_DRAW;

m_frontFace = createInterleaved(m_useMappedBuffers, 6, false, 4 * teeth + 2, vboUsage);

addInterleavedVertexAndNormalArrays(m_frontFace, 3);

m_backFace = createInterleaved(m_useMappedBuffers, 6, false, 4 * teeth + 2, vboUsage);

addInterleavedVertexAndNormalArrays(m_backFace, 3);

m_frontSide = createInterleaved(m_useMappedBuffers, 6, false, 6 * teeth, vboUsage);

addInterleavedVertexAndNormalArrays(m_frontSide, 3);

m_backSide = createInterleaved(m_useMappedBuffers, 6, false, 6 * teeth, vboUsage);

addInterleavedVertexAndNormalArrays(m_backSide, 3);

m_outwardFace = createInterleaved(m_useMappedBuffers, 6, false, 4 * 4 * teeth + 2, vboUsage);

addInterleavedVertexAndNormalArrays(m_outwardFace, 3);

m_insideRadiusCyl = createInterleaved(m_useMappedBuffers, 6, false, 2 * teeth + 2, vboUsage);

addInterleavedVertexAndNormalArrays(m_insideRadiusCyl, 3);

for( GLsizei i = 0; i < teeth; i++ ) {

const float angle = float(i) * 2.0f * std:🔢:pi_v / float(teeth);

sincos(angle + da * 0.0f, s, 0, c, 0);

sincos(angle + da * 1.0f, s, 1, c, 1);

sincos(angle + da * 2.0f, s, 2, c, 2);

sincos(angle + da * 3.0f, s, 3, c, 3);

vert(m_frontFace, r0 * c[0], r0 * s[0], dz, normal);

vert(m_frontFace, r1 * c[0], r1 * s[0], dz, normal);

vert(m_frontFace, r0 * c[0], r0 * s[0], dz, normal);

vert(m_frontFace, r1 * c[3], r1 * s[3], dz, normal);

vert(m_frontSide, r1 * c[0], r1 * s[0], dz, normal);

vert(m_frontSide, r2 * c[1], r2 * s[1], dz, normal);

vert(m_frontSide, r2 * c[2], r2 * s[2], dz, normal);

vert(m_frontSide, r1 * c[0], r1 * s[0], dz, normal);

vert(m_frontSide, r2 * c[2], r2 * s[2], dz, normal);

vert(m_frontSide, r1 * c[3], r1 * s[3], dz, normal);

vert(m_backFace, r1 * c[0], r1 * s[0], -dz, normal);

vert(m_backFace, r0 * c[0], r0 * s[0], -dz, normal);

vert(m_backFace, r1 * c[3], r1 * s[3], -dz, normal);

vert(m_backFace, r0 * c[0], r0 * s[0], -dz, normal);

vert(m_backSide, r1 * c[3], r1 * s[3], -dz, normal);

vert(m_backSide, r2 * c[2], r2 * s[2], -dz, normal);

vert(m_backSide, r2 * c[1], r2 * s[1], -dz, normal);

vert(m_backSide, r1 * c[3], r1 * s[3], -dz, normal);

vert(m_backSide, r2 * c[1], r2 * s[1], -dz, normal);

vert(m_backSide, r1 * c[0], r1 * s[0], -dz, normal);

u = r2 * c[1] - r1 * c[0];

v = r2 * s[1] - r1 * s[0];

len = std::sqrt(u * u + v * v);

u /= len;

v /= len;

vert(m_outwardFace, r1 * c[0], r1 * s[0], dz, normal);

vert(m_outwardFace, r1 * c[0], r1 * s[0], -dz, normal);

vert(m_outwardFace, r2 * c[1], r2 * s[1], dz, normal);

vert(m_outwardFace, r2 * c[1], r2 * s[1], -dz, normal);

normal[0] = c[0];

normal[1] = s[0];

vert(m_outwardFace, r2 * c[1], r2 * s[1], dz, normal);

vert(m_outwardFace, r2 * c[1], r2 * s[1], -dz, normal);

vert(m_outwardFace, r2 * c[2], r2 * s[2], dz, normal);

vert(m_outwardFace, r2 * c[2], r2 * s[2], -dz, normal);

normal[0] = (r1 * s[3] - r2 * s[2]);

normal[1] = (r1 * c[3] - r2 * c[2]) * -1.0f;

vert(m_outwardFace, r2 * c[2], r2 * s[2], dz, normal);

vert(m_outwardFace, r2 * c[2], r2 * s[2], -dz, normal);

vert(m_outwardFace, r1 * c[3], r1 * s[3], dz, normal);

vert(m_outwardFace, r1 * c[3], r1 * s[3], -dz, normal);

normal[0] = c[0];

normal[1] = s[0];

vert(m_outwardFace, r1 * c[3], r1 * s[3], dz, normal);

vert(m_outwardFace, r1 * c[3], r1 * s[3], -dz, normal);

vert(m_outwardFace, r1 * c[0], r1 * s[0], dz, normal);

vert(m_outwardFace, r1 * c[0], r1 * s[0], -dz, normal);

normal[0] = c[0] * -1.0f;

normal[1] = s[0] * -1.0f;

normal[2] = 0.0f;

vert(m_insideRadiusCyl, r0 * c[0], r0 * s[0], -dz, normal);

vert(m_insideRadiusCyl, r0 * c[0], r0 * s[0], dz, normal);

}

normal[0] = 0.0f;

normal[1] = 0.0f;

normal[2] = 1.0f;

vert(m_frontFace, r0 * c[4], r0 * s[4], dz, normal);

vert(m_frontFace, r1 * c[4], r1 * s[4], dz, normal);

m_frontFace->seal(true);

normal[2] = -1.0f;

vert(m_backFace, r1 * c[4], r1 * s[4], -dz, normal);

vert(m_backFace, r0 * c[4], r0 * s[4], -dz, normal);

m_backFace->seal(true);

m_backSide->seal(true);

m_frontSide->seal(true);

sincos(da * 1.0f, s, 1, c, 1);

u = r2 * c[1] - r1 * c[4];

v = r2 * s[1] - r1 * s[4];

len = std::sqrt(u * u + v * v);

u /= len;

v /= len;

normal[0] = v;

normal[1] = -u;

normal[2] = 0.0f;

vert(m_outwardFace, r1 * c[4], r1 * s[4], dz, normal);

vert(m_outwardFace, r1 * c[4], r1 * s[4], -dz, normal);

m_outwardFace->seal(true);

normal[0] = c[4] * -1.0f;

normal[1] = s[4] * -1.0f;

normal[2] = 0.0f;

vert(m_insideRadiusCyl, r0 * c[4], r0 * s[4], -dz, normal);

vert(m_insideRadiusCyl, r0 * c[4], r0 * s[4], dz, normal);

m_insideRadiusCyl->seal(true);

associate(m_st);

}

void initGL(GL& gl) {

initGL(gl, m_frontFace);

initGL(gl, m_frontSide);

initGL(gl, m_backFace);

initGL(gl, m_backSide);

initGL(gl, m_outwardFace);

initGL(gl, m_insideRadiusCyl);

}

if( m_frontFace ) {

m_frontFace->destroy(gl);

}

if( m_frontSide ) {

m_frontSide->destroy(gl);

}

if( m_backFace ) {

m_backFace->destroy(gl);

}

if( m_backSide ) {

m_backSide->destroy(gl);

}

if( m_outwardFace ) {

m_outwardFace->destroy(gl);

}

if( m_insideRadiusCyl ) {

m_insideRadiusCyl->destroy(gl);

}

m_frontFace = nullptr;

m_frontSide = nullptr;

m_backFace = nullptr;

m_backSide = nullptr;

m_outwardFace = nullptr;

m_insideRadiusCyl = nullptr;

}

void draw(GL& gl, float ang_rad) {

PMVMat4f& pmv = m_pmvMatUni.pmv();

m_objbox.transform(pmv.getMv(), m_viewbox);

pmv.rotateMv(ang_rad, 0.0f, 0.0f, 1.0f);

m_st.send(gl, m_pmvMatUni);

if( m_picked ) {

const float gray = ( m_gearColor.x + m_gearColor.y + m_gearColor.z ) / 3.0f;

m_colorUniform.vec4f() = jau::math::Vec4f(gray, gray, gray, m_gearColor.w);

} else {

m_colorUniform.vec4f() = m_gearColor;

}

m_st.send(gl, m_colorUniform);

draw(gl, m_frontFace, GL_TRIANGLE_STRIP);

draw(gl, m_frontSide, GL_TRIANGLES);

draw(gl, m_backFace, GL_TRIANGLE_STRIP);

draw(gl, m_backSide, GL_TRIANGLES);

draw(gl, m_outwardFace, GL_TRIANGLE_STRIP);

draw(gl, m_insideRadiusCyl, GL_TRIANGLE_STRIP);

}

PMVMat4f& pmv = m_pmvMatUni.pmv();

const bool done = action(e, win, *this);

return done;

}

bool& picked() noexcept { return m_picked; }

const jau::math::geom::AABBox3f& objBounds() const noexcept { return m_objbox; }

const jau::math::geom::AABBox3f& viewBounds() const noexcept { return m_viewbox; }

constexpr int name() const noexcept { return m_name; }

std::string toString() const noexcept { return std::string("GearsObjES2[").append(std::to_string(m_name).append(", view ").append(m_viewbox.toString())).append("]"); }

};

private:

constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;

ShaderState m_st;

GLUniformSyncPMVMat4f m_pmvMatUni;

GLUniformVec4f m_colorUni;

GLUniformVec3f m_lightU;

GearsObjectES2 m_gear1, m_gear2, m_gear3;

float m_teethAngle = 0.0f;

int m_swapInterval = 1;

bool m_flipVerticalInGLOrientation = false;

bool m_doRotate = true;

bool m_clearBuffers = true;

bool m_initialized = false;

float m_zNear = 5.0f;

float m_zFar = 10000.0f;

float m_zViewDist = 40.0f;

public:

m_st(),

m_pmvMatUni("gcu_PMVMatrix", mat_req),

m_colorUni("gcu_StaticColor", GearsObjectES2::red),

m_lightU("gcu_Light0Pos", lightPos),

m_gear1Color(GearsObjectES2::red),

m_gear2Color(GearsObjectES2::green),

m_gear3Color(GearsObjectES2::blue),

m_gear1(1, m_st, m_gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, Vec3f( -3.0f, -2.0f, 0.0f), m_pmvMatUni, m_colorUni),

m_gear2(2, m_st, m_gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f, Vec3f( 3.1f, -2.0f, 0.0f), m_pmvMatUni, m_colorUni),

m_gear3(3, m_st, m_gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, Vec3f( -3.1f, 4.2f, 0.0f), m_pmvMatUni, m_colorUni)

{

m_st.manage(m_pmvMatUni);

m_st.manage(m_lightU);

m_st.manage(m_colorUni);

}

constexpr bool doRotate() const noexcept { return m_doRotate; }

constexpr void setDoRotate(bool rotate) noexcept { m_doRotate = rotate; }

constexpr void setClearBuffers(bool v) noexcept { m_clearBuffers = v; }

const PMVMat4f& pmvMatrix() const noexcept { return m_pmvMatUni.pmv(); }

constexpr Vec3f& pan() noexcept { return m_pan; }

m_clearColor = clearColor;

}

m_gear1Color = gear1Color;

m_gear2Color = gear2Color;

m_gear3Color = gear3Color;

}

void setZ(float zNear, float zFar, float zViewDist) {

m_zNear = zNear;

m_zFar = zFar;

m_zViewDist = zViewDist;

}

bool init(const WindowSRef& win, const jau::fraction_timespec& when) override {

ShaderCodeSRef vp0 = ShaderCode::create(gl, GL_VERTEX_SHADER, "demos/glsl",

"demos/glsl/bin", "SingleLight0");

ShaderCodeSRef fp0 = ShaderCode::create(gl, GL_FRAGMENT_SHADER, "demos/glsl",

"demos/glsl/bin", "SingleLight0");

if( !vp0 || !fp0 ) {

win->dispose(when);

return false;

}

vp0->defaultShaderCustomization(gl);

fp0->defaultShaderCustomization(gl);

if( !sp0->add(gl, vp0, true) || !sp0->add(gl, fp0, true) ) {

sp0->destroy(gl);

win->dispose(when);

return false;

}

m_st.attachShaderProgram(gl, sp0, true);

m_gear1.initGL(gl);

m_gear2.initGL(gl);

m_gear3.initGL(gl);

m_st.send(gl, m_pmvMatUni);

m_st.send(gl, m_colorUni);

m_st.send(gl, m_lightU);

if( m_clearBuffers ) {

::glClearColor(m_clearColor.x, m_clearColor.y, m_clearColor.z, m_clearColor.w);

}

m_initialized = sp0->inUse();

m_st.useProgram(gl, false);

if( !m_initialized ) {

m_st.destroy(gl);

win->dispose(when);

}

return m_initialized;

}

void dispose(const WindowSRef& win, const jau::fraction_timespec& when) override {

jau::fprintf_td(when.to_ms(), stdout, "RL::dispose: %s\n", win->toString().c_str());

m_st.useProgram(gl, false);

m_gear1.dispose(gl);

m_gear2.dispose(gl);

m_gear3.dispose(gl);

m_st.destroy(gl);

m_initialized = false;

}

jau::fprintf_td(when.to_ms(), stdout, "RL::reshape: %s\n\t%s\n", toString().c_str(), m_pmvMatUni.pmv().toString().c_str());

if( !m_initialized ) { return; }

}

const bool msaa = false;

jau::fprintf_td(when.to_ms(), stdout, "GearsES2.reshape %s of %fx%f, swapInterval %d, msaa %d, tileRendererInUse %d\n",

viewport.toString().c_str(), imageWidth, imageHeight, m_swapInterval, msaa, false);

float left, right, bottom, top;

if( imageHeight > imageWidth ) {

const float a = imageHeight / imageWidth;

right = 1.0f;

bottom = -a;

top = a;

} else {

const float a = imageWidth / imageHeight;

right = a;

bottom = -1.0f;

top = 1.0f;

}

const float w = right - left;

const float h = top - bottom;

const float l = left + float(viewport.x()) * w / imageWidth;

const float r = l + float(viewport.width()) * w / imageWidth;

const float b = bottom + float(viewport.y()) * h / imageHeight;

const float t = b + float(viewport.height()) * h / imageHeight;

{

const float _w = r - l;

const float _h = t - b;

jau::fprintf_td(when.to_ms(), stdout, ">> GearsES2 angle %f, [l %f, r %f, b %f, t %f] %fx%f -> [l %f, r %f, b %f, t %f] %fx%f, v-flip %d",

m_teethAngle, left, right, bottom, top, w, h, l, r, b, t, _w, _h, m_flipVerticalInGLOrientation);

}

PMVMat4f& pmv = m_pmvMatUni.pmv();

if( m_flipVerticalInGLOrientation && win->isBLOriented() ) {

pmv.scaleP(1.0f, -1.0f, 1.0f);

}

pmv.frustumP(l, r, b, t, m_zNear, m_zFar);

m_st.useProgram(gl, true);

m_st.send(gl, m_pmvMatUni);

m_st.useProgram(gl, false);

}

}

}

void display(const WindowSRef& win, const jau::fraction_timespec&) override {

if( !m_initialized ) { return; }

if( m_doRotate ) {

m_teethAngle += 0.5f;

}

if( m_clearBuffers ) {

::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

}

setGLStates(win, true);

m_st.useProgram(gl, true);

PMVMat4f& pmv = m_pmvMatUni.pmv();

pmv.rotateMv(m_rotEuler.x, 1.0f, 0.0f, 0.0f);

pmv.rotateMv(m_rotEuler.y, 0.0f, 1.0f, 0.0f);

pmv.rotateMv(m_rotEuler.z, 0.0f, 0.0f, 1.0f);

m_st.useProgram(gl, false);

setGLStates(win, false);

}

std::array<GearsObjectES2*, 3> gears{ &m_gear1, &m_gear2, &m_gear3 };

struct ZDescending {

bool operator()(GearsObjectES2* a, GearsObjectES2* b) const {

}

} zDescending;

std::sort(gears.begin(), gears.end(), zDescending);

GearsObjectES2* res = nullptr;

for(size_t i=0; !res && i<gears.size(); ++i) {

if( action(e, win, *gears[i]) ) {

res = gears[i];

}

}

return res;

}

PMVMat4f& pmv = m_pmvMatUni.pmv();

pmv.rotateMv(m_rotEuler.x, 1.0f, 0.0f, 0.0f);

pmv.rotateMv(m_rotEuler.y, 0.0f, 1.0f, 0.0f);

pmv.rotateMv(m_rotEuler.z, 0.0f, 0.0f, 1.0f);

return res;

}

private:

void setGLStates(const WindowSRef& win, bool enable) {

const bool useCullFace = !(m_flipVerticalInGLOrientation && win->isBLOriented());

if( enable ) {

::glEnable(GL_DEPTH_TEST);

if( useCullFace ) {

::glEnable(GL_CULL_FACE);

}

} else {

::glDisable(GL_DEPTH_TEST);

if( useCullFace ) {

::glDisable(GL_CULL_FACE);

}

}

}

public:

std::string toStringImpl() const noexcept override {

std::string r("GearsES2[isInit ");

r.append(std::to_string(m_initialized).append(", usesShared ").append(std::to_string(false)))

.append(", 1 ")

.append(m_gear1.toString())

.append(", 2 ")

.append(m_gear2.toString())

.append(", 3 ")

.append(m_gear3.toString())

.append("]");

return r;

}

};

#endif

jau::function< bool(const PointerEvent &e, const WindowSRef &win, GearsObjectES2 &shape)> PointerShapeAction

void setZ(float zNear, float zFar, float zViewDist)

void display(const WindowSRef &win, const jau::fraction_timespec &) override

Called by the drawable to initiate rendering by the client.

void reshapeImpl(const WindowSRef &win, const jau::math::Recti &viewport, float imageWidth, float imageHeight, const jau::fraction_timespec &when)

constexpr void setClearBuffers(bool v) noexcept

constexpr Vec3f & pan() noexcept

void dispose(const WindowSRef &win, const jau::fraction_timespec &when) override

Notifies the listener to perform the release of all renderer resources per context,...

constexpr bool doRotate() const noexcept

constexpr void setDoRotate(bool rotate) noexcept

GearsObjectES2 * findPick(const PointerShapeAction &action, const PointerEvent &e, const WindowSRef &win)

Fast loop through all shapes using PointerShapeAction w/o matrix traversal using view-coordinates.

constexpr void setFlipVerticalInGLOrientation(bool v) noexcept

bool dispatchForShape(GearsObjectES2 &shape, const PointerShapeAction &action, const PointerEvent &e, const WindowSRef &win)

Dispatch PointerShapeAction to given shape w/ matrix traversal.

constexpr jau::math::Vec3f & rotEuler() noexcept

std::string toStringImpl() const noexcept override

static constexpr float getTeethRotation(int name, float adeg) noexcept

constexpr const jau::math::Recti & viewport() const noexcept

void setClearColor(const jau::math::Vec4f &clearColor) noexcept

void setGearsColors(const jau::math::Vec4f &gear1Color, const jau::math::Vec4f &gear2Color, const jau::math::Vec4f &gear3Color) noexcept

PMVMat4f & pmvMatrix() noexcept

GearsObjectES2(int name, ShaderState &st, const jau::math::Vec4f &gearColor, float inner_radius, float outer_radius, float width, GLsizei teeth, float tooth_depth, jau::math::Vec3f tx, GLUniformSyncPMVMat4f &pmvMatUni, GLUniformVec4f &colorUniform)

std::string toString() const noexcept

const jau::math::geom::AABBox3f & viewBounds() const noexcept

const jau::math::geom::AABBox3f & objBounds() const noexcept

constexpr int name() const noexcept

static constexpr jau::math::Vec4f green

bool dispatchAction(const PointerShapeAction &action, const PointerEvent &e, const WindowSRef &win)

const jau::math::Mat4f & matPMvi() const noexcept

static constexpr jau::math::Vec4f red

static constexpr jau::math::Vec4f blue

static GLContext & downcast(RenderContext *rc)

Downcast dereferenced given RenderContext* to GLContext&, throws exception if signature doesn't match...

static server_sref createGLSLInterleaved(GLsizei compsPerElement, bool normalized, GLsizei initialElementCount, GLenum vboUsage)

static server_sref createGLSLInterleavedMapped(GLsizei compsPerElement, bool normalized, GLsizei mappedElementCount, GLenum vboUsage)

ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...

constexpr RenderListener(Private) noexcept

Private ctor for shared_ptr instance method w/o public ctor.

std::string toString() const noexcept

Pointer event of type PointerType.

Class template jau::function is a general-purpose static-polymorphic function wrapper.

Axis Aligned Bounding Box.

constexpr const Point3f & high() const noexcept

Returns the maximum right-top-near (xyz) coordinate.

constexpr PMVMatrix4 & scaleP(float x, float y, float z) noexcept

Scale the projection matrix.

void frustumP(const float left, const float right, const float bottom, const float top, const float zNear, const float zFar)

Multiply the projection matrix with the frustum matrix.

constexpr PMVMatrix4 & translateMv(float x, float y, float z) noexcept

Translate the modelview matrix.

constexpr_cxx26 PMVMatrix4 & rotateMv(const float ang_rad, const float x, const float y, const float z) noexcept

Rotate the modelview matrix by the given axis and angle in radians.

constexpr_cxx20 PMVMatrix4 & popMv() noexcept

Pop the modelview matrix from its stack.

constexpr PMVMatrix4 & loadMvIdentity() noexcept

Load the modelview matrix with the values of the given Mat4.

constexpr Mat4 & getPMvi() noexcept

Returns the pre-multiplied inverse projection x modelview, if Mat4#invert(Mat4) succeeded,...

constexpr PMVMatrix4 & loadPIdentity() noexcept

Load the projection matrix with the values of the given Mat4.

constexpr Mat4 & getMv() noexcept

Returns the modelview matrix (Mv).

constexpr_cxx20 PMVMatrix4 & pushMv() noexcept

Push the modelview matrix to its stack, while preserving its values.

consteval_cxx20 std::string_view name() noexcept

constexpr T adeg_to_rad(const T arc_degree) noexcept

Converts arc-degree to radians.

GLArrayDataServerSRef< float > GLFloatArrayDataServerSRef

std::shared_ptr< ShaderCode > ShaderCodeSRef

std::shared_ptr< ShaderProgram > ShaderProgramSRef

@ msaa

MSAA based Anti-Aliasing, a two pass region rendering, slower and more resource hungry (FBO with samp...

std::shared_ptr< Window > WindowSRef

PMVData

PMVMatrix4 derived matrices and values.

PMVMatrix4< float > PMVMat4f

ssize_t fprintf_td(const uint64_t elapsed_ms, FILE *stream, std::string_view format, const Args &...args) noexcept

Convenient secure fprintf() invocation, prepending the given elapsed_ms timestamp and using jau:forma...

constexpr uint64_t to_ms() const noexcept

Returns time in milliseconds.