Commit dfcd8304 authored by Jan Möbius's avatar Jan Möbius

Merge branch 'EnvMapRendering' into 'master'

Fix Environment Mapping

fix for issue #1 

See merge request !12
parents 4a684cf6 629c88e5
......@@ -441,7 +441,7 @@ void IRenderer::traverseRenderableNodes( ACG::GLState* _glState, ACG::SceneGraph
{
if ( _node->status() != ACG::SceneGraph::BaseNode::HideNode )
_node->enter(*_glState, _drawMode);
_node->enter(*_glState, nodeDM);
// fetch material (Node itself can be a material node, so we have to
......
......@@ -91,6 +91,7 @@ void RenderObject::initFromState( GLState* _glState )
alpha = 1.0f;
if (_glState)
{
modelview = _glState->modelview();
......@@ -120,6 +121,24 @@ void RenderObject::initFromState( GLState* _glState )
}
shininess = _glState->shininess();
}
// get texcoord generation params
if (glIsEnabled(GL_TEXTURE_GEN_Q))
shaderDesc.texGenDim = 4;
else if (glIsEnabled(GL_TEXTURE_GEN_R))
shaderDesc.texGenDim = 3;
else if (glIsEnabled(GL_TEXTURE_GEN_T))
shaderDesc.texGenDim = 2;
else if (glIsEnabled(GL_TEXTURE_GEN_S))
shaderDesc.texGenDim = 1;
if (shaderDesc.texGenDim)
{
GLint genMode = 0;
glGetTexGeniv(GL_S, GL_TEXTURE_GEN_MODE, &genMode);
shaderDesc.texGenMode = genMode;
}
}
void RenderObject::setupShaderGenFromDrawmode( const SceneGraph::DrawModes::DrawModeProperties* _props )
......
......@@ -196,9 +196,19 @@ void ShaderGenerator::initVertexShaderIO(const ShaderGenDesc* _desc, const Defau
if (_iodesc->passTexCoord_ && !_desc->textured())
{
// assume 2d texcoords
addInput("vec2 inTexCoord");
addOutput("vec2 outVertexTexCoord");
// assume 2d texcoords as default
int texdim = 2;
if (_desc->texGenMode && _desc->texGenDim > 0 && _desc->texGenDim <= 4)
texdim = _desc->texGenDim;
QString inTexCoordString, outTexCoordString;
inTexCoordString.sprintf("vec%i inTexCoord", texdim);
outTexCoordString.sprintf("vec%i outVertexTexCoord", texdim);
addInput(inTexCoordString);
addOutput(outTexCoordString);
}
......@@ -1177,6 +1187,7 @@ void ShaderProgGenerator::addVertexBeginCode(QStringList* _code)
}
}
if (desc_.vertexColors && (desc_.colorMaterialMode == GL_AMBIENT || desc_.colorMaterialMode == GL_AMBIENT_AND_DIFFUSE))
_code->push_back("vec4 sg_cColor = vec4(g_cEmissive + g_cLightModelAmbient * " SG_INPUT_VERTEXCOLOR ".xyz, SG_ALPHA);");
else
......@@ -1192,6 +1203,84 @@ void ShaderProgGenerator::addVertexBeginCode(QStringList* _code)
_code->push_back("sg_cColor = " SG_INPUT_VERTEXCOLOR ";");
// texcoord generation
if (desc_.texGenDim && desc_.texGenMode)
{
// https://www.opengl.org/wiki/Mathematics_of_glTexGen
if (!ioDesc_.inputTexCoord_)
{
// declare variable if it has not been allocated yet
QString texGenString;
texGenString.sprintf("vec%i sg_vTexCoord; // glTexGen emulation", desc_.texGenDim);
_code->push_back(texGenString);
}
const char* texGenCoordString[] = { "x", "y", "z", "w" };
switch (desc_.texGenMode)
{
case GL_OBJECT_LINEAR:
{
for (int i = 0; i < desc_.texGenDim; ++i)
{
QString assignmentInstrString;
assignmentInstrString.sprintf("sg_vTexCoord.%s = dot(inPosition, g_vTexGenPlane[%i]);", texGenCoordString[i], i);
_code->push_back(assignmentInstrString);
}
} break;
case GL_EYE_LINEAR:
{
for (int i = 0; i < desc_.texGenDim; ++i)
{
QString assignmentInstrString;
assignmentInstrString.sprintf("sg_vTexCoord.%s = dot(sg_vPosVS, g_vTexGenPlane[%i]);", texGenCoordString[i], i);
_code->push_back(assignmentInstrString);
}
} break;
case GL_SPHERE_MAP:
{
_code->push_back("vec3 sg_vPosVS_unit = normalize(sg_vPosVS.xyz);");
_code->push_back("vec3 sg_TexGenRefl = reflect(sg_vPosVS_unit, sg_vNormalVS);");
_code->push_back("vec3 sg_TexGenRefl2 = sg_TexGenRefl; sg_TexGenRefl2.z += 1.0;");
_code->push_back("float sg_TexGenMRcp = 0.5 * inversesqrt(dot(sg_TexGenRefl2, sg_TexGenRefl2));");
for (int i = 0; i < desc_.texGenDim; ++i)
{
QString assignmentInstrString;
assignmentInstrString.sprintf("sg_vTexCoord.%s = sg_TexGenRefl.%s * sg_TexGenMRcp + 0.5;", texGenCoordString[i], texGenCoordString[i]);
_code->push_back(assignmentInstrString);
}
} break;
case GL_NORMAL_MAP:
{
for (int i = 0; i < desc_.texGenDim; ++i)
{
QString assignmentInstrString;
assignmentInstrString.sprintf("sg_vTexCoord.%s = sg_vNormalVS.%s;", texGenCoordString[i], texGenCoordString[i]);
_code->push_back(assignmentInstrString);
}
} break;
case GL_REFLECTION_MAP:
{
_code->push_back("vec3 sg_vPosVS_unit = normalize(sg_vPosVS.xyz);");
_code->push_back("vec3 sg_TexGenRefl = reflect(sg_vPosVS_unit, sg_vNormalVS);");
for (int i = 0; i < desc_.texGenDim; ++i)
{
QString assignmentInstrString;
assignmentInstrString.sprintf("sg_vTexCoord.%s = sg_TexGenRefl.%s;", texGenCoordString[i], texGenCoordString[i]);
_code->push_back(assignmentInstrString);
}
} break;
default: break;
}
}
// apply modifiers
for (size_t i = 0; i < activeMods_.size(); ++i)
activeMods_[i]->modifyVertexBeginCode(_code);
......@@ -1943,6 +2032,31 @@ void ShaderProgGenerator::generateShaders()
ioDesc_.passTexCoord_ = true;
}
// clamp generated texcoord dimension
int maxTexGenDim = 4;
switch (desc_.texGenMode)
{
case GL_EYE_LINEAR:
case GL_OBJECT_LINEAR: maxTexGenDim = 4; break;
case GL_SPHERE_MAP: maxTexGenDim = 2; break;
case GL_NORMAL_MAP:
case GL_REFLECTION_MAP: maxTexGenDim = 3; break;
default: maxTexGenDim = 0; break;
}
desc_.texGenDim = std::max(std::min(desc_.texGenDim, maxTexGenDim), 0);
if (desc_.texGenMode == GL_REFLECTION_MAP || desc_.texGenMode == GL_SPHERE_MAP || desc_.texGenMode == GL_NORMAL_MAP)
ioDesc_.inputNormal_ = true;
if (desc_.texGenDim && desc_.texGenMode)
ioDesc_.passTexCoord_ = true; // no input, but texcoords are generated
if (desc_.vertexColors)
ioDesc_.inputColor_ = true;
......@@ -2574,6 +2688,19 @@ QString ShaderGenDesc::toString() const
resStrm << "\nShadowTexture: " << iter->second.shadow;
}
resStrm << "\nshaderDesc.texGenDim: " << texGenDim;
switch (texGenMode)
{
case GL_OBJECT_LINEAR: resStrm << "\nshaderDesc.texGenMode: GL_OBJECT_LINEAR"; break;
case GL_EYE_LINEAR: resStrm << "\nshaderDesc.texGenMode: GL_EYE_LINEAR"; break;
case GL_SPHERE_MAP: resStrm << "\nshaderDesc.texGenMode: GL_SPHERE_MAP"; break;
case GL_NORMAL_MAP: resStrm << "\nshaderDesc.texGenMode: GL_NORMAL_MAP"; break;
case GL_REFLECTION_MAP: resStrm << "\nshaderDesc.texGenMode: GL_REFLECTION_MAP"; break;
default: resStrm << "\nshaderDesc.texGenMode: unknown"; break;
}
if (!vertexTemplateFile.isEmpty())
resStrm << "\nshaderDesc.vertexTemplateFile: " << vertexTemplateFile;
......
......@@ -102,11 +102,12 @@ public:
fragmentTemplateFile(""),
normalizeTexColors(true),
colorMaterialMode(GL_AMBIENT_AND_DIFFUSE),
textureTypes_()
textureTypes_(),
texGenDim(0),
texGenMode(GL_EYE_LINEAR)
{
for ( unsigned int i = 0 ; i < SG_MAX_SHADER_LIGHTS ; ++i)
lightTypes[i] = SG_LIGHT_DIRECTIONAL;
}
//In case, something crashes with the light types, try this hammer ;-)
......@@ -201,6 +202,48 @@ public:
// automatic texture coordinate generation, emulation of glTexGen
// this takes priority over any texcoords provided via addTextureType
// dimension of generated texture coordinate: 0,1,2,3,4 (default: 0 - disabled)
int texGenDim;
// texture generation mode: GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP, GL_NORMAL_MAP, GL_REFLECTION_MAP
GLenum texGenMode;
void enableTexGenObjectLinear(int _dim = 2)
{
texGenDim = std::max(std::min(_dim, 4), 0);
texGenMode = GL_OBJECT_LINEAR;
}
void enableTexGenEyeLinear(int _dim = 2)
{
texGenDim = std::max(std::min(_dim, 4), 0);
texGenMode = GL_EYE_LINEAR;
}
void enableTexGenSphericalMap(int _dim = 2)
{
texGenDim = std::max(std::min(_dim, 2), 0);
texGenMode = GL_SPHERE_MAP;
}
void enableTexGenNormalMap(int _dim = 3)
{
texGenDim = std::max(std::min(_dim, 3), 0);
texGenMode = GL_NORMAL_MAP;
}
void enableTexGenReflectionMap(int _dim = 3)
{
texGenDim = std::max(std::min(_dim, 3), 0);
texGenMode = GL_REFLECTION_MAP;
}
void disableTexGen() { texGenDim = 0; }
// comparison operator
bool operator == (const ShaderGenDesc& _rhs) const
{
......@@ -243,6 +286,15 @@ public:
if (macros != _rhs.macros)
return false;
if (texGenDim != _rhs.texGenDim)
return false;
if (texGenDim)
{
if (texGenMode != _rhs.texGenMode)
return false;
}
if (numLights)
return memcmp(lightTypes, _rhs.lightTypes, numLights * sizeof(ShaderGenLightType)) == 0;
......
......@@ -553,8 +553,29 @@ draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
if ( ( _drawMode & DrawModes::SOLID_TEXTURED ) && mesh_.has_vertex_texcoords2D())
{
///\todo enableTexCoords_
// enable_arrays(VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY );
ACG::GLState::enable(GL_TEXTURE_2D);
ACG::GLState::disable(GL_LIGHTING);
ACG::GLState::shadeModel(GL_FLAT);
ACG::GLState::depthRange(0.01, 1.0);
drawMesh_->disableColors();
drawMesh_->usePerVertexTexcoords();
// texture environment: fragment color = texture sample
GLint prevTexEnvMode = 0;
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &prevTexEnvMode);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
draw_faces();
ACG::GLState::depthRange(0.0, 1.0);
ACG::GLState::disable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, prevTexEnvMode);
}
if ((_drawMode & DrawModes::SOLID_ENV_MAPPED) && mesh_.has_vertex_normals())
{
ACG::GLState::enable(GL_TEXTURE_2D);
ACG::GLState::disable(GL_LIGHTING);
ACG::GLState::shadeModel(GL_FLAT);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment