This C++ example demonstrates simple polylines using the the GLU tesselator and per-pixel-lighting.
This C++ example demonstrates simple polylines using the the GLU tesselator and per-pixel-lighting.
#include <cstdio>
#include <cmath>
#include <memory>
#include <vector>
#include "../demos/GLLauncher01.hpp"
{}
};
typedef std::shared_ptr<Shape>
ShapeRef;
private:
float m_zOffset;
bool iMatIdent = true;
bool iMatDirty = false;
struct Private{ explicit Private() = default; };
public:
Shape(Private, ShaderState &st, PMVMat4fUniform& pmvMatU)
: m_st(st), m_pmvMat(pmvMatU), m_oshape(3, 16),
{
m_array->addGLSLSubArray("mgl_Vertex", 3, GL_ARRAY_BUFFER);
m_array->addGLSLSubArray("mgl_Normal", 3, GL_ARRAY_BUFFER);
m_st.ownAttribute(m_array, true);
m_uColor = GLUniformVec4f::create(
"mgl_StaticColor",
Vec4f(0, 0, 0, 1));
m_st.ownUniform(m_uColor, true);
}
return std::make_shared<Shape>(Private(), st, pmvMatU);
}
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_segments = GLUtilTesselator::tesselate(GLUtilTesselator::FLAG_VERBOSE | GLUtilTesselator::FLAG_NORMAL, *m_array, m_oshape);
jau::INFO_PRINT(
"\n%s", GLUtilTesselator::Segment::toString(
"- ", m_segments).c_str() );
m_array->seal(gl, true);
}
m_pmvMat.m.pushMv();
applyMatToMv(m_pmvMat.m);
m_st.pushUniform(gl, m_pmvMat.u);
m_st.pushUniform(gl, m_uColor);
m_array->enableBuffer(gl, true);
for(const GLUtilTesselator::Segment& s : m_segments ) {
::glDrawArrays(s.type, s.first, s.count);
}
m_array->enableBuffer(gl, false);
m_pmvMat.m.popMv();
}
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;
ShaderState m_st;
bool m_initialized;
bool m_animating = true;
bool m_oneframe = false;
jau::fraction_timespec m_tlast;
PMVMat4fUniform m_pmvMat;
std::vector<ShapeRef> m_shapes;
public:
m_initialized(false)
{
}
const PMVMat4f&
pmv() const noexcept {
return m_pmvMat.m; }
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;
ShaderCodeRef vp0 = ShaderCode::create(gl, GL_VERTEX_SHADER,
"demos/glsl",
"demos/glsl/bin", "SingleLight0");
ShaderCodeRef fp0 = ShaderCode::create(gl, GL_FRAGMENT_SHADER,
"demos/glsl",
"demos/glsl/bin", "SingleLight0");
if( !vp0 || !fp0 ) {
win->dispose(when);
return false;
}
{
std::string custom = "#define MAX_TEXTURE_UNITS 0\n";
size_t vsPos = vp0->defaultShaderCustomization(gl, true, true);
size_t fsPos = fp0->defaultShaderCustomization(gl, true, true);
vp0->insertShaderSource(0, vsPos, custom);
fp0->insertShaderSource(0, fsPos, custom);
}
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_pmvMat.m.getP().loadIdentity();
m_pmvMat.m.getMv().loadIdentity();
m_st.ownUniform(m_pmvMat.u, true);
m_st.ownUniform(lightU, true);
m_st.pushAllUniforms(gl);
const float lineWidth = 1/2.5f;
const float dz = 0.001f;
{
const float width = 1.5f;
const float height = 1.5f;
const float x1 = -width/2.0f;
const float y1 = -height/2.0f;
const float x2 = x1 + width;
const float y2 = y1 + height;
m_shapes.push_back(frontShape);
OutlineShape& oshape = frontShape->
outlines();
{
}
{
const float dxy = lineWidth;
oshape.
moveTo(x1+dxy, y1+dxy, z);
oshape.
lineTo(x1+dxy, y2-dxy, z);
oshape.
lineTo(x2-dxy, y2-dxy, z);
oshape.
lineTo(x2-dxy, y1+dxy, z);
oshape.
lineTo(x1+dxy, y1+dxy, z);
}
m_shapes.push_back(backShape);
}
{
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);
}
::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
::glEnable(GL_DEPTH_TEST);
::glEnable(GL_CULL_FACE);
m_initialized = sp0->inUse();
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;
}
m_pmvMat.m.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_pmvMat.u);
}
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);
m_pmvMat.m.getMv().loadIdentity();
m_pmvMat.m.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 "Primitives02"; }
};
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(
"Primitives02.cpp",
std::make_shared<Example>(), argc, argv);
}
int launch(std::string_view sfile, const 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,...
std::string toStringImpl() const noexcept override
void setOneFrame() noexcept
Recti & viewport() noexcept
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
bool animating() const noexcept
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.
constexpr const float & zOffset() const noexcept
void setColor(const Vec4f &c) noexcept
Shape(Private, ShaderState &st, PMVMat4fUniform &pmvMatU, GraphRenderer &renderer)
static ShapeRef create(ShaderState &st, PMVMat4fUniform &pmvMatU, GraphRenderer &renderer)
constexpr const Quat4f & rotation() const noexcept
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
A Generic shape objects which is defined by a list of Outlines.
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...
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).
std::vector< Segment > SegmentList
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.
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
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_t bitCount() const noexcept
static constexpr const value_type one
static constexpr const uint32_t INVERSE_TRANSPOSED_MODELVIEW
SyncMats4f & getSyncPMvMviMvit()
Returns SyncMatrices4f of 4 matrices within one FloatBuffer: P, Mv, Mvi and Mvit if requested.
static constexpr const uint32_t INVERSE_PROJECTION
static constexpr const uint32_t INVERSE_MODELVIEW
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
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
std::shared_ptr< GLUniformData > GLUniformDataRef
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
std::shared_ptr< GLUniformVec3f > GLUniformVec3fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowRef
Quaternion< float > Quat4f
PMVMatrix4< float > PMVMat4f
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
void INFO_PRINT(const char *format,...) noexcept
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
constexpr uint64_t to_ms() const noexcept
Returns time in milliseconds.