Hi all!
Here learning about Cinder and OpenGL meshes. Would love to fully understand how them works. I’ve been doing some good readings here: deprecated-vbomesh and here how-to-create-mesh-and-draw-it-on-the-screen about VboMeshes but I’ve missed a simple and updated example showing how to build vboMesh manually without using cinder surfaces.
Then I’ve found this blog from drewish showing it and doing nice comparisons about triMesh and VboMesh so I’ve started to update it to 0.9.0. Right now I’ve a vboMesh working out but still not with triMesh. Attached visual results for vboMesh and triMesh.
Also guess I should use Batch to increase performance. Would be nice to receive some hints.
// Updated drewish demo (to Cinder 0.9.0 ) about VBOMesh vs TriMesh. Building cinder manual meshes using indices, positions and colors.
// by Carles Gutiérrez
// Original code from
// Simple demo to compare drawing 2D triangles with Cinder's VBO and TriMesh wrappers.
// https://drewish.com/2014/08/16/comparing-the-trimesh-and-vbomesh-in-cinder/
//TODO
// fix triMesh uses
// try textures coords
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Vbo.h"
#include "cinder/Trimesh.h"
#include "cinder/params/Params.h"
// sqrt(3) / 2
#define M_SQRT_3_2 0.8660254037844386
using namespace ci;
using namespace ci::app;
using namespace std;
class ComparingTriMeshAndVboMeshApp : public App {
public:
void setup() override;
void mouseDown( MouseEvent event ) override;
void update() override;
void draw() override;
//void prepareSettings(Settings *settings) override;//0.9.0 use lambda at CINDER_APP
void recalculate();
void buildVBOMesh();
void buildTriMesh();
gl::VboMeshRef mVboMesh; //gl::VboMesh mMesh;
TriMesh mTriangles;
params::InterfaceGl mParams;
int mCols = 10;
int mRows = 10;
int mScale = 30;
bool mWireframe = false;
bool useTriMesh = false;
bool bUpdateColorsFbo = false;
};
void ComparingTriMeshAndVboMeshApp::setup()
{
mParams = params::InterfaceGl("Parameters", vec2(220, 170));
mParams.addParam("Scale", &mScale)
.keyIncr("s").keyDecr("S")
.min(1).max(100).step(1)
.updateFn([this] { recalculate(); });
mParams.addParam("Columns", &mCols)
.keyIncr("d").keyDecr("D")
.min(1).max(100).step(1)
.updateFn([this] { recalculate(); });
mParams.addParam("Rows", &mRows)
.keyIncr("f").keyDecr("F")
.min(1).max(100).step(1)
.updateFn([this] { recalculate(); });
mParams.addParam("Wireframe", &mWireframe)
.key("w");
mParams.addParam("VBO/TriMesh", &useTriMesh)
.updateFn([this] { recalculate(); })
.key("t");
mParams.addParam("update VBO Colors", &bUpdateColorsFbo)
.key("c");
recalculate();
}
void ComparingTriMeshAndVboMeshApp::mouseDown( MouseEvent event )
{
}
void ComparingTriMeshAndVboMeshApp::update()
{
if(!useTriMesh && bUpdateColorsFbo){
//update colors playing with position x
float offset = getElapsedSeconds() * 4.0f;
auto mappedPosAttrib = mVboMesh->mapAttrib3f(geom::Attrib::POSITION, false);
auto mappedColorAttrib = mVboMesh->mapAttrib3f(geom::Attrib::COLOR, false);
for (int i = 0; i < mVboMesh->getNumVertices(); i++) {
vec3 &pos = *mappedPosAttrib;
vec3 &color = *mappedColorAttrib;
mappedColorAttrib->y = sinf(pos.x - offset) *0.75f;
++mappedColorAttrib;
++mappedPosAttrib;
}
mappedColorAttrib.unmap();
mappedPosAttrib.unmap();
}
}
void ComparingTriMeshAndVboMeshApp::draw()
{
gl::pushModelView();
gl::clear(Color::black());
if (mWireframe) gl::enableWireframe();
if (useTriMesh)
gl::draw(mTriangles);
else
gl::draw(mVboMesh);
if (mWireframe) gl::disableWireframe();
gl::popModelView();
mParams.draw();
}
void ComparingTriMeshAndVboMeshApp::recalculate()
{
if (useTriMesh) buildTriMesh();
else buildVBOMesh();
}
void ComparingTriMeshAndVboMeshApp::buildVBOMesh()
{
vector<gl::VboMesh::Layout> bufferLayout = {
gl::VboMesh::Layout().usage(GL_STATIC_DRAW).attrib(geom::Attrib::POSITION, 3),
gl::VboMesh::Layout().usage(GL_DYNAMIC_DRAW).attrib(geom::Attrib::COLOR, 3),
gl::VboMesh::Layout().usage(GL_STATIC_DRAW).attrib(geom::Attrib::TEX_COORD_0, 2)
};
mVboMesh = gl::VboMesh::create(mCols * mRows * 3, GL_TRIANGLES, bufferLayout);//mMesh = gl::VboMesh(mCols * mRows * 3, mCols * mRows * 3, layout, GL_TRIANGLES);
vector<uint32_t> indices;
vector<vec3> positions;
vector<Color> colors;
float w = M_SQRT_3_2 * mScale;
float h = 1.0 * mScale;
int index = -1;
Color8u color;
for (int col = 0; col < mCols; col++) {
float x = col * 2 * w;
int direction = (col % 2) ? 1 : -1;
for (int row = 0; row < mRows; row++) {
direction *= -1;
float y = row * h;
positions.push_back(vec3(x - w * direction, y - h, 0));
positions.push_back(vec3(x + w * direction, y + 0, 0));
positions.push_back(vec3(x - w * direction, y + h, 0));
// #69D2E7 and #A7DBD8
color = (direction > 0) ? Color8u(105, 210, 231) : Color8u(224, 228, 204);
colors.push_back(color);
colors.push_back(color);
colors.push_back(color);
index += 3;
indices.push_back(index - 2);
indices.push_back(index - 1);
indices.push_back(index);
}
}
mVboMesh->bufferIndices(indices.size(), &indices);//mVboMesh->bufferIndices(indices);
mVboMesh->bufferAttrib(geom::POSITION, positions.size() * sizeof(vec3), positions.data());//mMesh.bufferPositions(positions);
mVboMesh->bufferAttrib(geom::COLOR, colors.size() * sizeof(Color), colors.data());//mMesh.bufferColorsRGB(colors);
}
void ComparingTriMeshAndVboMeshApp::buildTriMesh()
{
float w = M_SQRT_3_2 * mScale;
float h = 1.0 * mScale;
int index = -1;
Color color;
mTriangles.clear();
for (int col = 0; col < mCols; col++) {
float x = col * 2 * w;
int direction = (col % 2) ? 1 : -1;
for (int row = 0; row < mRows; row++) {
direction *= -1;
float y = row * h;
mTriangles.appendPosition(vec3(x - w * direction, y - h, 0));//mTriangles.appendVertex(vec3(x - w * direction, y - h, 0));
mTriangles.appendPosition(vec3(x + w * direction, y + 0, 0));
mTriangles.appendPosition(vec3(x - w * direction, y + h, 0));
// #69D2E7 and #A7DBD8
color = (direction > 0) ? Color8u(250, 105, 0) : Color8u(105, 210, 231);
mTriangles.appendColorRgb(color);
mTriangles.appendColorRgb(color);
mTriangles.appendColorRgb(color);
index += 3;
mTriangles.appendTriangle(index - 2, index - 1, index);
}
}
}
CINDER_APP(ComparingTriMeshAndVboMeshApp, RendererGl, [](App::Settings *settings) {
settings->setHighDensityDisplayEnabled();//settings->enableHighDensityDisplay();
settings->setMultiTouchEnabled(false);//settings->enableMultiTouch(false);
})