Calculating uv coordinates to be used for sampling from tiled textures.

This commit is contained in:
Kalle Bladin
2016-04-18 19:52:01 -04:00
parent 6758f79d91
commit 0c33e2a2b6
7 changed files with 230 additions and 23 deletions

View File

@@ -57,6 +57,7 @@ namespace openspace {
//////////////////////////////////////////////////////////////////////////////////////
PatchRenderer::PatchRenderer(shared_ptr<Geometry> geometry)
: _geometry(geometry)
, _tileSet(LatLon(M_PI, M_PI * 2), LatLon(M_PI / 2, - M_PI), 0)
{
}
@@ -104,16 +105,18 @@ namespace openspace {
* viewTransform * modelTransform;
// Get the textures that should be used for rendering
glm::ivec3 tileIndex = tileSet.getTileIndex(patch);
LatLonPatch tilePatch = tileSet.getTilePositionAndScale(tileIndex);
std::shared_ptr<ghoul::opengl::Texture> tile00 = tileSet.getTile(tileIndex);
glm::ivec3 tileIndex = _tileSet.getTileIndex(patch);
LatLonPatch tilePatch = _tileSet.getTilePositionAndScale(tileIndex);
std::shared_ptr<ghoul::opengl::Texture> tile00 = _tileSet.getTile(tileIndex);
glm::mat3 uvTransform = _tileSet.getUvTransformationPatchToTile(patch, tileIndex);
// Bind and use the texture
ghoul::opengl::TextureUnit texUnit;
texUnit.activate();
tile00->bind();
_programObject->setUniform("textureSampler", texUnit);
_programObject->setUniform("uvTransformPatchToTile", uvTransform);
LatLon swCorner = patch.southWestCorner();
_programObject->setUniform("modelViewProjectionTransform", modelViewProjectionTransform);
_programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2()));
@@ -171,9 +174,10 @@ namespace openspace {
ivec2 intSnapCoord = ivec2(
patch.center().lat / (M_PI * 2) * segmentsPerPatch * patchesToCoverGlobe.y,
patch.center().lon / (M_PI) * segmentsPerPatch * patchesToCoverGlobe.x);
LatLon swCorner = LatLon(
stepSize.lat * intSnapCoord.x - halfSize.lat,
stepSize.lon * intSnapCoord.y - halfSize.lon);
LatLon newPatchCenter = LatLon(
stepSize.lat * intSnapCoord.x,
stepSize.lon * intSnapCoord.y);
LatLonPatch newPatch(newPatchCenter, patch.halfSize());
ivec2 contraction = ivec2(intSnapCoord.y % 2, intSnapCoord.x % 2);
@@ -183,18 +187,20 @@ namespace openspace {
// Get the textures that should be used for rendering
glm::ivec3 tileIndex = tileSet.getTileIndex(patch);
LatLonPatch tilePatch = tileSet.getTilePositionAndScale(tileIndex);
std::shared_ptr<ghoul::opengl::Texture> tile00 = tileSet.getTile(tileIndex);
glm::ivec3 tileIndex = _tileSet.getTileIndex(patch);
LatLonPatch tilePatch = _tileSet.getTilePositionAndScale(tileIndex);
std::shared_ptr<ghoul::opengl::Texture> tile00 = _tileSet.getTile(tileIndex);
glm::mat3 uvTransform = _tileSet.getUvTransformationPatchToTile(newPatch, tileIndex);
// Bind and use the texture
ghoul::opengl::TextureUnit texUnit;
texUnit.activate();
tile00->bind();
_programObject->setUniform("textureSampler", texUnit);
_programObject->setUniform("uvTransformPatchToTile", mat3(uvTransform));
_programObject->setUniform("modelViewProjectionTransform", data.camera.projectionMatrix() * viewTransform * modelTransform);
_programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2()));
_programObject->setUniform("minLatLon", vec2(newPatch.southWestCorner().toLonLatVec2()));
_programObject->setUniform("lonLatScalingFactor", 2.0f * vec2(halfSize.toLonLatVec2()));
_programObject->setUniform("globeRadius", float(radius));
_programObject->setUniform("contraction", contraction);

View File

@@ -67,7 +67,7 @@ namespace openspace {
unique_ptr<ProgramObject> _programObject;
shared_ptr<Geometry> _geometry;
TextureTileSet tileSet;
TextureTileSet _tileSet;
};

View File

@@ -36,8 +36,13 @@ namespace {
}
namespace openspace {
TextureTileSet::TextureTileSet()
{
TextureTileSet::TextureTileSet(LatLon sizeLevel0, LatLon offsetLevel0, int depth)
: _sizeLevel0(sizeLevel0)
, _offsetLevel0(offsetLevel0)
, _depth(depth)
{
// Set e texture to test
_testTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath("textures/earth_bluemarble.jpg")));
if (_testTexture) {
LDEBUG("Loaded texture from '" << "textures/earth_bluemarble.jpg" << "'");
@@ -48,6 +53,16 @@ namespace openspace {
//_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
/*
int dataSize = _testTexture->width() * _testTexture->height() * _testTexture->bytesPerPixel();
GLubyte* data = new GLubyte[dataSize];
for (size_t i = 0; i < dataSize; i++)
{
data[i] = unsigned char(i / float(dataSize) * 255);
}
_testTexture->setPixelData(data);
_testTexture->uploadTexture();
*/
}
@@ -58,10 +73,16 @@ namespace openspace {
glm::ivec3 TextureTileSet::getTileIndex(LatLonPatch patch)
{
int level = log2(static_cast<int>(glm::max(
_sizeLevel0.lat / patch.halfSize().lat * 2,
_sizeLevel0.lon / patch.halfSize().lon * 2)));
Vec2 TileSize = _sizeLevel0.toLonLatVec2() / pow(2, level);
glm::ivec2 tileIndex = -(patch.northWestCorner().toLonLatVec2() + _offsetLevel0.toLonLatVec2()) / TileSize;
_sizeLevel0.lat / (patch.halfSize().lat * 2),
_sizeLevel0.lon / (patch.halfSize().lon * 2))));
level = glm::min(level, _depth);
Vec2 tileSize = _sizeLevel0.toLonLatVec2() / pow(2, level);
Vec2 nw = patch.northWestCorner().toLonLatVec2();
Vec2 offset = _offsetLevel0.toLonLatVec2();
glm::ivec2 tileIndex = (nw - offset) / tileSize;
// Flip y since indices increase from top to bottom
tileIndex.y *= -1;
return glm::ivec3(tileIndex, level);
}
@@ -86,8 +107,35 @@ namespace openspace {
_offsetLevel0.lon + tileIndex.x * tileSize.lon);
return LatLonPatch(
LatLon(northWest.lat + tileSize.lat / 2, northWest.lon + tileSize.lon / 2),
LatLon(northWest.lat - tileSize.lat / 2, northWest.lon + tileSize.lon / 2),
LatLon(tileSize.lat / 2, tileSize.lon / 2));
}
glm::mat3 TextureTileSet::getUvTransformationPatchToTile(
LatLonPatch patch,
glm::ivec3 tileIndex)
{
LatLonPatch tile = getTilePositionAndScale(tileIndex);
Vec2 posDiff =
patch.southWestCorner().toLonLatVec2() -
tile.southWestCorner().toLonLatVec2();
glm::mat3 invTileScale = glm::mat3(
{1 / (tile.halfSize().lon * 2), 0, 0,
0, 1 / (tile.halfSize().lat * 2), 0,
0, 0, 1});
glm::mat3 globalTranslation = glm::mat3(
{ 1, 0, 0,
0, 1, 0,
posDiff.x, posDiff.y, 1 });
glm::mat3 patchScale = glm::mat3(
{ (patch.halfSize().lon * 2), 0, 0,
0, (patch.halfSize().lat * 2), 0,
0, 0, 1 });
return invTileScale * globalTranslation * patchScale;
}
} // namespace openspace

View File

@@ -38,7 +38,7 @@ namespace openspace {
class TextureTileSet
{
public:
TextureTileSet();
TextureTileSet(LatLon sizeLevel0, LatLon offsetLevel0, int depth);
~TextureTileSet();
/// Returns the index of the tile at an appropriate level.
@@ -49,9 +49,11 @@ namespace openspace {
std::shared_ptr<Texture> getTile(LatLonPatch patch);
std::shared_ptr<Texture> getTile(glm::ivec3 tileIndex);
LatLonPatch getTilePositionAndScale(glm::ivec3 tileIndex);
glm::mat3 getUvTransformationPatchToTile(LatLonPatch patch, glm::ivec3 tileIndex);
private:
LatLon _sizeLevel0;
LatLon _offsetLevel0;
int _depth;
std::shared_ptr<Texture> _testTexture;
};

View File

@@ -36,6 +36,7 @@ uniform sampler2D texture1;
uniform sampler2D nightTex;
uniform sampler2D textureSampler;
uniform mat3 uvTransformPatchToTile;
in vec4 vs_position;
in vec2 vs_uv;
@@ -47,7 +48,8 @@ in vec2 vs_uv;
Fragment getFragment() {
Fragment frag;
frag.color = texture2D(textureSampler, vs_uv);// vec4(fract(vs_uv * 1), 0.4,1);
frag.color = texture2D(textureSampler, vec2(uvTransformPatchToTile * vec3(vs_uv.s, vs_uv.t, 1)));
frag.color = frag.color * 1.0 + vec4(fract(vs_uv * 1), 0.4,1) * 0.2;
frag.depth = pscDepth(vs_position);
return frag;