mikel wrote:
Can I change color of renderable objects and mix it with texture (like glColor3f) ?
Somehow modifying objects material? Or model.shader?
Yes but it's not straightforward, you will need to understand Horde3D. At the moment, geometry does not have vertex colors.
You will need to setup the vertex colors in the static geometry stream and setup the shader to retrieve the vertex colors.
The jointIndices in H3DGeoRes::GeoVertStaticStream will need to be used. This data is normally used for skinning as far as I understand.
You will also need to create a model node, mesh node and material resource to render the geometry. There is a lot to understand about Horde3D and particularly about shaders and pipelines.
Setting the geometry vertex colorsThe variables posData, indData, and texData are std::vector types; vertexCount and indexCount are self explanatory.
Code:
// Create the geometry resource
H3DRes geometryResource = h3dutCreateGeometryRes( "GeometryName", vertexCount, indexCount, &posData[0], &indData[0], 0x0, 0x0, 0x0, &texData[0], 0x0 );
// Add the vertex colors to the geometry resource in RGBA format, use the jointIndices in the static stream.
float* vertexStaticStream = static_cast<float*>( h3dMapResStream( geometryResource, H3DGeoRes::GeometryElem, 0, H3DGeoRes::GeoVertStaticStream, false, true ) );
for ( int i=0; i < vertexCount; ++i )
{
vertexStaticStream += 2; // skip u1,v1
*vertexStaticStream++ = 1.0f;
*vertexStaticStream++ = 1.0f;
*vertexStaticStream++ = 1.0f;
*vertexStaticStream++ = 1.0f;
vertexStaticStream += 6; // skip joint weights and u2,v2
++sourceVertices;
}
h3dUnmapResStream( geometryResource );
ShaderHere is an example of a shader that mixes texture color with vertex color. The uniform projection matrix is orthogonal.
The vertex color is stored in the jointIndices of the H3DGeoRes::GeoVertTanStream.
Code:
[[FX]]
// Samplers
sampler2D albedoMap;
// Contexts
context TRANSLUCENT
{
VertexShader = compile GLSL VS_GENERAL;
PixelShader = compile GLSL FS_AMBIENT;
ZWriteEnable = false;
BlendMode = Blend;
}
[[VS_GENERAL]]
#include "shaders/utilityLib/vertCommon.glsl"
uniform mat4 projMat;
attribute vec3 vertPos;
attribute vec4 joints; // vertex color (r,g,b,a)
varying vec4 vColor;
#ifdef _F01_Textured
attribute vec2 texCoords0;
varying vec2 vTexCoords;
#endif
void main( void )
{
#ifdef _F01_Textured
vTexCoords = vec2( texCoords0.s, -texCoords0.t );
#endif
// The joints stream is used to store vertex color
vColor = vec4( joints.r, joints.g, joints.b, joints.a );
// Calculate world space position
vec4 pos = calcWorldPos( vec4( vertPos.x, vertPos.y, vertPos.z, 1.0 ) );
// Convert the projected position to a pixel coordinate of the window
gl_Position = projMat * pos;
}
[[FS_AMBIENT]]
#ifdef _F01_Textured
uniform sampler2D albedoMap;
varying vec2 vTexCoords;
#endif
varying vec4 vColor;
void main( void )
{
#ifdef _F01_Textured
gl_FragColor = texture2D( albedoMap, vTexCoords ) * vColor;
#else
gl_FragColor = vColor;
#endif
}
Material Resource CreationThe variable textureRes is a Horde3D texture resource that has been previously loaded.
The file location "shaders/example.shader" is the name of the shader file shown above.
Code:
// Create the material resource
H3DRes materialRes = h3dAddResource( H3DResTypes::Material, "MaterialName" , 0 );
// Setup the XML string to represent the material data
std::string materialData = std::string( "<Material>\n" );
materialData.append( "<Shader source=\"shaders/example.shader\"/>\n" ); // shader source
if ( textureRes )
{
std::string textureName = h3dGetResName( textureRes );
materialData.append( "<ShaderFlag name=\"_F01_Textured\"/>\n" ); // shader flags
materialData.append( "<Sampler name=\"albedoMap\" map=\"" ); // sampler name and attributes
materialData.append( textureName.c_str() ); // name of the texture resource to set as the <map> value
materialData.append( "\" allowCompression=\"false\" mipmaps=\"false\" />\n" );
}
materialData.append( "</Material>\n" );
// Load the material resource from the material data string
const bool loaded = h3dLoadResource( materialRes, materialData.c_str(), materialData.length() );
if ( !loaded )
{
(void)h3dRemoveResource( materialRes );
materialRes = 0x0;
}