I’m trying to figure out how to tint a TriMesh
, and this has led me down a bit of an opengl rabbithole and I’m hoping the community here can help me sort a few things out.
The very first thing I tried was to just bind a stock shader, set the color, and tint my TriMesh
:
auto shaderDef = ci::gl::ShaderDef().lambert().color();
ci::gl::ScopedGlslProg scopedShader(ci::gl::getStockShader(shaderDef));
ci::gl::ScopedColor color(ci::Color(1, 0, 0));
gl::draw(mCachedTriMesh);
Now this, may have worked if my TriMesh was textured, but upon further inspection, it doesn’t use a texture – it looks like the model has per-vertex data embedded into it with the colors.
I did a bit of digging and found that draw( const TriMesh &mesh )
calls draw( const geom::Source &source )
. This looks fairly straightforward – it checks for a bound shader, determines attributes needed by the shader, and sets those attributes. It calls ctx->setDefaultShaderVars()
which has this snippet:
const auto &attribs = glslProg->getActiveAttributes();
for( const auto &attrib : attribs ) {
switch( attrib.getSemantic() ) {
case geom::Attrib::COLOR: {
ColorA c = ctx->getCurrentColor();
gl::vertexAttrib4f( attrib.getLocation(), c.r, c.g, c.b, c.a );
}
break;
default:
;
}
}
Okay, got it – colors from the 3d model are being loaded directly into the vertex attributes, and this is why none of my calls to ci::gl::color()
will affect it – whatever I do outside of this scope will get overwritten when the vertex attributes are assigned.
It seems to me that the solution is to write my own custom vertex shader that tints the vertex color on a per-vertex basis:
uniform mat4 ciModelViewProjection;
in vec4 ciPosition;
in vec4 ciColor;
in vec4 tintColor;
out vec4 outColor;
void main( void ) {
gl_Position = ciModelViewProjection * ciPosition;
outColor = mix(ciColor, tintColor, 0.5);
}
and a corresponding fragment shader that uses outColor
.
So I can just create a vec4 uniform to provide the tint color, and… what a minute, can’t I do that with ci::gl::color()
? If the vertex attributes are loaded into the vertex shader using the ciColor
uniform, where is the context’s current color set by `gl::color’? Is that already being loaded as a uniform somewhere that I can access?
Going down this rabbithole has made me realize that while I know there is a difference between the color vertex attribute and the context’s color, I’m not actually exactly sure how they’re different and how they work with opengl. So this is where I send up the signal flare and hope that someone can help me wrap my head around this!
thanks all!