[osg-users] Using multiples texture for a geometry
Florian GOLESTIN
florian.golestin at gmail.com
Tue May 3 13:13:39 PDT 2016
Hi Robert,
Sorry my mistake, I wanted to put only the interesting part but this is not efficient.
No more censure!
Code:
namespace Soleil
{
LevelReader::LevelReader()
{
//supportsExtension("level", "Text map format for Donjon");
}
LevelReader::~LevelReader()
{
}
osg::ref_ptr<Level> LevelReader::readFile(const std::string &file) const
{
std::string fileName = osgDB::findDataFile(file);
if (fileName.empty()) return nullptr; // TODO throw e?
errno = 0;
std::cout << "Stream: " << fileName.c_str() << "\n";
std::ifstream stream;
stream.exceptions(std::ifstream::failbit); // | std::ifstream::badbit
stream.open(fileName.c_str(), std::ios::in);
if (!stream) return nullptr; // TODO throw e
return readStream(stream);
}
osg::ref_ptr<Level> LevelReader::readStream(std::istream &stream) const
{
char block; // current reading block
float x = 0; // Current position on x
float y = 0; // Current position on y
int wallCount = 0; // Number of cubes
float maxX = 0; // Max size of the map in X
osg::ref_ptr<Soleil::Level> level = new Soleil::Level();
std::string line;
while(std::getline(stream, line))
{
std::stringstream linestream(line);
while (linestream >> block)
{
/* TODO Configurable size for the blocks */
float posx = 1.0 * x;
float posy = 1.0 * y;
float endx = posx + 1.0;
float endy = posy + 1.0;
bool blockFound = false;
switch (block)
{
case '.':
break;
case 'D':
level->_startingPosition = osg::Vec3(posx + .5, posy + .5, .3);
blockFound = true;
break;
case 'd':
level->_startingOrientation = osg::Vec3(posx + .5, posy + .5, .3);
blockFound = true;
break;
case 'x':
if (wallCount % 2)
{
std::cout << "1" << "\n";
createCube(level.get(), *level->texcoords, *level->texcoords2, posx, posy, endx, endy);
}
else
{
std::cout << "2" << "\n";
createCube(level.get(), *level->texcoords2, *level->texcoords, posx, posy, endx, endy);
}
blockFound = true;
wallCount++;
break;
// default:
// blockFound = levelConfiguration(block);
// break;
}
if (blockFound == false)
std::cout << "Unexpected character: " << block << std::endl;
x += 1.0;
maxX = std::max(x, maxX);
}
x = 0;
y -= 1.0; // TODO Cube size
}
// TODO read failed?
// Floor -------------
level->vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
level->vertices->push_back(osg::Vec3(maxX, 0.0f, 0.0f));
level->vertices->push_back(osg::Vec3(maxX, y, 0.0f));
level->vertices->push_back(osg::Vec3(0, y, 0.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->texcoords->push_back( osg::Vec2(0.0f, 0.0f) ); // 0
level->texcoords->push_back( osg::Vec2(0.0f, 1.0f) ); // 1
level->texcoords->push_back( osg::Vec2(1.0f, 1.0f) ); // 2
level->texcoords->push_back( osg::Vec2(1.0f, 0.0f) ); // 3
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(level->vertices);
geom->setNormalArray(level->normals, osg::Array::Binding::BIND_PER_VERTEX);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 24*wallCount+4)); // +4 for the floor texture coordinates
osgUtil::SmoothingVisitor::smooth(*geom);
//
//
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom);
/* I added this in the hope to have the second texture appearing */
// osg::Material* material = new osg::Material;
// material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
// material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1));
// material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1));
// material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1));
// material->setShininess(osg::Material::FRONT_AND_BACK, 64.0f);
// level->getOrCreateStateSet()->setAttribute(material,osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
level->addChild(geode);
// Texture 1
geom->setTexCoordArray(0, level->texcoords.get());
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("media/textures/stone_3_2048x2048.jpg");
texture->setImage(image);
texture->setUnRefImageDataAfterApply(true);
level->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);
}
//Texture 2
geom->setTexCoordArray(1, level->texcoords2.get());
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("media/textures/Metal_seamless2_ch16.jpg");
texture->setImage(image);
texture->setUnRefImageDataAfterApply(true);
level->getOrCreateStateSet()->setTextureAttributeAndModes(1, texture);
}
std::cout << "done.\n";
return level;
}
/*
* @param Level Is the container of the vertices, normals and textures for the walls of our labyrinth
* @param tex Is the Vector that should receive the coordinate for the textures
* @param skip Is the second vector for texture filled with '0' to 'skip' this wall
*/
void LevelReader::createCube(Soleil::Level *level, osg::Vec2Array &tex, osg::Vec2Array &skip,
float posx, float posy, float endx, float endy) const
{
// ------ Front
level->vertices->push_back(osg::Vec3(posx, posy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, posy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, posy, 1.0f));
level->vertices->push_back(osg::Vec3(posx, posy, 1.0f));
level->normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f));
level->normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f));
level->normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f));
level->normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 0.0f));
//
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
// ------ top
level->vertices->push_back(osg::Vec3(posx, posy, 1.0f));
level->vertices->push_back(osg::Vec3(endx, posy, 1.0f));
level->vertices->push_back(osg::Vec3(endx, endy, 1.0f));
level->vertices->push_back(osg::Vec3(posx, endy, 1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
tex.push_back( osg::Vec2(0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 0.0f));
//
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
// ------ back
level->vertices->push_back(osg::Vec3(posx, endy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, endy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, endy, 1.0f));
level->vertices->push_back(osg::Vec3(posx, endy, 1.0f));
level->normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
level->normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
level->normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
level->normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 0.0f));
//
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
// ------ Bottom
level->vertices->push_back(osg::Vec3(posx, posy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, posy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, endy, 0.0f));
level->vertices->push_back(osg::Vec3(posx, endy, 0.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
level->normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
tex.push_back( osg::Vec2(0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 0.0f));
//
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
// ------ Left
level->vertices->push_back(osg::Vec3(posx, posy, 0.0f));
level->vertices->push_back(osg::Vec3(posx, endy, 0.0f));
level->vertices->push_back(osg::Vec3(posx, endy, 1.0f));
level->vertices->push_back(osg::Vec3(posx, posy, 1.0f));
level->normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));
level->normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));
level->normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));
level->normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 0.0f));
//
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
// ------ Right
level->vertices->push_back(osg::Vec3(endx, posy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, endy, 0.0f));
level->vertices->push_back(osg::Vec3(endx, endy, 1.0f));
level->vertices->push_back(osg::Vec3(endx, posy, 1.0f));
level->normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
level->normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
level->normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
level->normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 0.0f));
tex.push_back( osg::Vec2(0.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 1.0f));
tex.push_back( osg::Vec2(1.0f, 0.0f));
//
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
skip.push_back( osg::Vec2(0.0f, 0.0f));
}
}
Here is the original file: https://github.com/fulezi/soleil/blob/master/LevelReader.cpp
An idea?
Florian
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=67046#67046
More information about the osg-users
mailing list