Commit e86316b1 authored by Matthias Möller's avatar Matthias Möller

add multiple texture and more texture type support for the new renderer

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@16805 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 0b18dfef
......@@ -1213,7 +1213,7 @@ void ACG::DrawMeshT<Mesh>::addTriRenderObjects(IRenderer* _renderer, const Rende
RenderObject ro = *_baseObj;
bindBuffersToRenderObject(&ro);
if (_textureMap && _baseObj->shaderDesc.textured)
if (_textureMap && _baseObj->shaderDesc.textured())
{
// textured mode
......@@ -1226,8 +1226,10 @@ void ACG::DrawMeshT<Mesh>::addTriRenderObjects(IRenderer* _renderer, const Rende
}
else
{
// ACG::GLState::bindTexture(GL_TEXTURE_2D, (*_textureMap)[pSubset->materialID]);
ro.texture = (*_textureMap)[pSubset->materialID];
RenderObject::Texture tex;
tex.type = GL_TEXTURE_2D;
tex.id = (*_textureMap)[pSubset->materialID];
ro.addTexture(tex,0);
}
......
......@@ -334,9 +334,19 @@ void IRenderer::bindObjectUniforms( ACG::RenderObject* _obj, GLSL::Program* _pro
// texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _obj->texture);
_prog->setUniform("g_Texture0", 0);
for (std::map<unsigned,RenderObject::Texture>::const_iterator iter = _obj->textures().begin();
iter != _obj->textures().end();++iter)
{
//check for valid texture id
const unsigned texture_stage = iter->first;
const RenderObject::Texture tex = iter->second;
if (!tex.id)
continue;
glActiveTexture(GL_TEXTURE0 +texture_stage);
glBindTexture(iter->second.type, tex.id);
_prog->setUniform(QString("g_Texture%1").arg(texture_stage).toStdString().c_str(), (int)texture_stage);
}
_prog->setUniform("g_PointSize", 5.0f);
......
......@@ -40,10 +40,10 @@
* *
\*===========================================================================*/
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <QFile>
#include <QTextStream>
......@@ -120,7 +120,10 @@ void RenderObject::setupShaderGenFromDrawmode( const SceneGraph::DrawModes::Draw
if (_props)
{
shaderDesc.vertexColors = _props->colored();
shaderDesc.textured = _props->textured();
if (_props->textured())
shaderDesc.addTextureType(GL_TEXTURE_2D,false,0);
else
shaderDesc.clearTextures();
shaderDesc.numLights = _props->lighting() ? 0 : -1;
switch (_props->lightStage()) {
......@@ -176,8 +179,6 @@ RenderObject::RenderObject()
diffuse(0.6f, 0.6f, 0.6f), ambient(0.1f, 0.1f, 0.1f),
specular(0.0f, 0.0f, 0.0f), emissive(0.05f, 0.05f, 0.05f),
alpha(1.0f), shininess(100.0f),
texture(0),
debugID(0), debugName(0),
internalFlags_(0)
......
......@@ -50,6 +50,7 @@
#include <ACG/Scenegraph/SceneGraph.hh>
#include <ACG/Scenegraph/MaterialNode.hh>
#include <map>
namespace GLSL{
......@@ -220,7 +221,49 @@ struct ACGDLLEXPORT RenderObject
* - array of textures
* assumes binding slot 0 and 2D for now
*/
GLuint texture;
struct Texture
{
GLuint id;
GLenum type;
bool shadow;
Texture():
id(0),
type(GL_TEXTURE_2D),
shadow(false){}
};
/// adds a texture to stage RenderObjects::numTextures()
void addTexture(const Texture& _t)
{
addTexture(_t,numTextures());
}
/**
* adds a texture to an specific stage and enables texture support in shaderDesc
*/
void addTexture(const Texture& _t,const unsigned int _stage)
{
if (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS < numTextures())
{
std::cerr << "Texturestage " << _stage << " is too big. Allowed stages: "<< GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS << std::endl;
return;
}
textures_[_stage] = _t;
shaderDesc.addTextureType(_t.type,_t.shadow,_stage);
}
///clear all textures. Also affected on shaderDesc
void clearTextures() {textures_.clear(); shaderDesc.clearTextures();}
const std::map<unsigned,Texture>& textures(){return textures_;}
size_t numTextures() {return textures_.size();}
private:
/// holds the textures (second) and the stage id (first)
std::map<unsigned,Texture> textures_;
public:
/// used internally for renderer debugging
......
......@@ -199,7 +199,7 @@ int ACG::ShaderCache::compareShaderGenDescs( const CacheEntry* _a, const CacheEn
if (a->vertexColors != b->vertexColors)
return -1;
if (a->textured != b->textured)
if (a->textured() != b->textured())
return -1;
if (a->geometryShader != b->geometryShader)
......
......@@ -41,8 +41,8 @@
\*===========================================================================*/
#include "ShaderGenerator.hh"
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
......@@ -52,7 +52,6 @@
#include <QTextStream>
#include <QGLFormat>
namespace ACG
{
......@@ -87,7 +86,7 @@ void ShaderGenerator::initVertexShaderIO(const ShaderGenDesc* _desc)
if (_desc->shadeMode != SG_SHADE_UNLIT)
addInput("vec3 inNormal");
if (_desc->textured)
if (_desc->textured())
{
addInput("vec2 inTexCoord");
addOutput("vec2 outVertexTexCoord");
......@@ -159,7 +158,7 @@ void ShaderGenerator::initGeometryShaderIO(const ShaderGenDesc* _desc) {
addInput("vec4 outVertexPosCS[]");
addOutput("vec4 outGeometryPosCS");
if (_desc->textured) {
if (_desc->textured()) {
addInput("vec2 outVertexTexCoord[]");
addOutput("vec2 outGeometryTexCoord");
}
......@@ -204,7 +203,7 @@ void ShaderGenerator::initFragmentShaderIO(const ShaderGenDesc* _desc)
inputShader = "Geometry";
if (_desc->textured)
if (_desc->textured())
addInput("vec2 out"+inputShader+"TexCoord");
addInput("vec4 out"+inputShader+"PosCS");
......@@ -495,7 +494,7 @@ void ShaderProgGenerator::initGenDefines(ShaderGenerator* _gen)
std::cout << __FUNCTION__ << " -> unknown shade mode: " << desc_.shadeMode << std::endl;
}
if (desc_.textured)
if (desc_.textured())
_gen->addDefine("SG_TEXTURED 1");
if (desc_.vertexColors)
......@@ -631,7 +630,7 @@ void ShaderProgGenerator::addVertexBeginCode(QStringList* _code)
if (desc_.shadeMode != SG_SHADE_UNLIT)
_code->push_back("sg_vNormalVS = normalize(g_mWVIT * inNormal);");
if (desc_.textured)
if (desc_.textured())
_code->push_back("sg_vTexCoord = inTexCoord;");
if (desc_.vertexColors)
......@@ -661,7 +660,7 @@ void ShaderProgGenerator::addVertexEndCode(QStringList* _code)
_code->push_back("gl_Position = sg_vPosPS;");
_code->push_back("outVertexPosCS = sg_vPosPS;");
if (desc_.textured)
if (desc_.textured())
_code->push_back("outVertexTexCoord = sg_vTexCoord;");
if (desc_.shadeMode == SG_SHADE_GOURAUD ||
......@@ -825,7 +824,7 @@ void ShaderProgGenerator::addGeometryBeginCode(QStringList* _code)
// addLightingCode(_code);
// }
//
// if (desc_.textured)
// if (desc_.textured())
// {
// _code->push_back("vec4 sg_cTex = texture(g_Texture0, outTexCoord);");
// _code->push_back("sg_cColor *= sg_cTex;");
......@@ -869,8 +868,35 @@ void ShaderProgGenerator::buildFragmentShader()
// texture sampler id
if (desc_.textured)
fragment_->addUniform("sampler2D g_Texture0");
if (desc_.textured())
{
for (std::map<unsigned,ShaderGenDesc::TextureType>::const_iterator iter = desc_.textureTypes().begin();
iter != desc_.textureTypes().end(); ++iter)
{
QString name = QString("g_Texture%1").arg(iter->first);
QString type = "";
switch (iter->second.type)
{
case GL_TEXTURE_1D: type = "sampler1D"; break;
case GL_TEXTURE_2D: type = "sampler2D"; break;
case GL_TEXTURE_3D: type = "sampler3D"; break;
case GL_TEXTURE_RECTANGLE: type = "sampler2DRect"; break;
case GL_TEXTURE_BUFFER: type = "samplerBuffer​"; break;
case GL_TEXTURE_CUBE_MAP: type = "samplerCube​"; break;
case GL_TEXTURE_1D_ARRAY: type = "sampler1DArray"; break;
case GL_TEXTURE_2D_ARRAY: type = "sampler2DArray"; break;
case GL_TEXTURE_CUBE_MAP_ARRAY: type = "samplerCubeArray"; break;
case GL_TEXTURE_2D_MULTISAMPLE: type = "sampler2DMS"; break;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: type = "sampler2DMSArray​"; break;
default: std::cerr << "Texture Type not supported "<< iter->second.type << std::endl; break;
}
// todo: check if texture type supports shadowtype
if (iter->second.shadow)
type += "Shadow";
fragment_->addUniform(type + " " + name);
}
}
// apply i/o modifiers
for (int i = 0; i < numModifiers_; ++i)
......@@ -976,9 +1002,17 @@ void ShaderProgGenerator::addFragmentBeginCode(QStringList* _code)
addLightingCode(_code);
}
if (desc_.textured)
if (desc_.textured())
{
_code->push_back("vec4 sg_cTex = texture(g_Texture0, out" + inputShader + "TexCoord);");
std::map<unsigned,ShaderGenDesc::TextureType>::const_iterator iter = desc_.textureTypes().begin();
_code->push_back("vec4 sg_cTex = texture(g_Texture"+QString::number(iter->first)+", out" + inputShader + "TexCoord);");
for (++iter; iter != desc_.textureTypes().end(); ++iter)
_code->push_back("sg_cTex += texture(g_Texture"+QString::number(iter->first)+", out" + inputShader + "TexCoord);");
if (desc_.textureTypes().size() > 1 && desc_.normalizeTexColors)
_code->push_back("sg_cTex = sg_cTex * 1.0/" + QString::number(desc_.textureTypes().size()) +".0 ;");
_code->push_back("sg_cColor *= sg_cTex;");
}
......@@ -1185,7 +1219,30 @@ QString ShaderGenDesc::toString() const
resStrm << "\nshaderDesc.shadeMode: " << shadeModeString[shadeMode];
resStrm << "\nshaderDesc.vertexColors: " << vertexColors;
resStrm << "\nshaderDesc.textured: " << textured;
resStrm << "\nshaderDesc.textured(): " << textured();
for (std::map<unsigned,TextureType>::const_iterator iter = textureTypes_.begin(); iter != textureTypes_.end();++iter)
{
resStrm << "\nTexture stage: " << iter->first;
resStrm << "\nTexture Type: ";
switch (iter->second.type)
{
case GL_TEXTURE_1D: resStrm << "GL_TEXTURE_1D"; break;
case GL_TEXTURE_2D: resStrm << "GL_TEXTURE_2D"; break;
case GL_TEXTURE_3D: resStrm << "GL_TEXTURE_3D"; break;
case GL_TEXTURE_RECTANGLE: resStrm << "GL_TEXTURE_RECTANGLE"; break;
case GL_TEXTURE_BUFFER: resStrm << "GL_TEXTURE_BUFFER​"; break;
case GL_TEXTURE_CUBE_MAP: resStrm << "GL_TEXTURE_CUBE_MAP​"; break;
case GL_TEXTURE_1D_ARRAY: resStrm << "GL_TEXTURE_1D_ARRAY"; break;
case GL_TEXTURE_2D_ARRAY: resStrm << "GL_TEXTURE_2D_ARRAY"; break;
case GL_TEXTURE_CUBE_MAP_ARRAY: resStrm << "GL_TEXTURE_CUBE_MAP_ARRAY"; break;
case GL_TEXTURE_2D_MULTISAMPLE: resStrm << "GL_TEXTURE_2D_MULTISAMPLE"; break;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: resStrm << "GL_TEXTURE_2D_MULTISAMPLE_ARRAY​"; break;
default: std::cerr << "Texture Type with number "<< iter->second.type << " on stage "<< iter->first << " is not supported " << std::endl; break;
}
resStrm << "\nShadowTexture: " << iter->second.shadow;
}
if (!vertexTemplateFile.isEmpty())
resStrm << "\nshaderDesc.vertexTemplateFile: " << vertexTemplateFile;
......
......@@ -46,6 +46,9 @@
#include <QString>
#include <string>
#include <list>
#include <map>
#include <ACG/GL/gl.hh>
#include <ACG/Config/ACGDefines.hh>
......@@ -97,30 +100,31 @@ public:
numLights(0),
shadeMode(SG_SHADE_UNLIT),
vertexColors(false),
textured(false),
vertexTemplateFile(""),
geometryTemplateFile(""),
fragmentTemplateFile(""),
geometryShader(false),
geometryShaderInput(SG_GEOMETRY_IN_TRIANGLES),
geometryShaderOutput(SG_GEOMETRY_OUT_TRIANGLE_STRIP),
geometryShaderMaxOutputPrimitives(3)
geometryShaderMaxOutputPrimitives(3),
normalizeTexColors(true),
textureTypes_()
{
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 ;-)
//In case, something crashes with the light types, try this hammer ;-)
// const ShaderGenDesc& operator= (const ShaderGenDesc& _rhs) {
//
// numLights = _rhs.numLights;
//
// std::copy(_rhs.lightTypes,_rhs.lightTypes+SG_MAX_SHADER_LIGHTS,lightTypes);
// textureTypes_ = _rhs.textureTypes_;
//
// shadeMode = _rhs.shadeMode;
// vertexColors = _rhs.vertexColors;
// textured = _rhs.textured;
// vertexTemplateFile = _rhs.vertexTemplateFile;
// geometryTemplateFile = _rhs.geometryTemplateFile;
// fragmentTemplateFile = _rhs.fragmentTemplateFile;
......@@ -139,7 +143,6 @@ public:
ShaderGenShadeMode shadeMode;
bool vertexColors;
bool textured;
// optionally specify shader template file names
QString vertexTemplateFile;
......@@ -161,6 +164,40 @@ public:
/// Defines the maximal number of primitives generated by the geometry shader
int geometryShaderMaxOutputPrimitives;
/// Defines if the textureVariable is normalized or not, if multiple textures are used
bool normalizeTexColors;
struct TextureType
{
GLenum type;
bool shadow;
};
private:
/// holds the texture types (second) and the stage id (first). if empty, shader does not support textures
std::map<unsigned,TextureType> textureTypes_;
public:
const std::map<unsigned,TextureType>& textureTypes() {return textureTypes_;}
/** \brief adds a texture type to the shader and enables texturing.
*
*/
void addTextureType(GLenum _type, bool _shadow, unsigned _stage)
{
TextureType t;
t.type = _type;
t.shadow = _shadow;
textureTypes_[_stage] = t;
}
///disables texture support and removes all texture types
void clearTextures(){textureTypes_.clear();}
bool textured()const {return !textureTypes_.empty();}
};
......
......@@ -497,7 +497,7 @@ void CoordsysNode::getRenderObjects( IRenderer* _renderer, GLState& _state, cons
// colored by emission only
ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
ro.shaderDesc.textured = false;
ro.shaderDesc.clearTextures();
ro.shaderDesc.vertexColors = false;
......
......@@ -640,7 +640,7 @@ void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, G
default: break;
}
ro.shaderDesc.textured = true;
ro.shaderDesc.addTextureType(GL_TEXTURE_2D,false,0);
switch (props->texcoordSource())
{
......@@ -648,7 +648,7 @@ void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, G
case DrawModes::TEXCOORD_PER_HALFEDGE: drawMesh_->usePerHalfedgeTexcoords(); break;
default:
{
ro.shaderDesc.textured = false;
ro.shaderDesc.clearTextures();
}break;
}
......
......@@ -793,7 +793,7 @@ void TranslationManipulatorNode::getRenderObjects(IRenderer* _renderer,
// unlit, use emissive color only
ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
ro.shaderDesc.vertexColors = false;
ro.shaderDesc.textured = false;
ro.shaderDesc.clearTextures();
// we need the scene zbuffer for the transparent overdraw effect
// -> defer as long as possible
......
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