mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:58:09 +02:00
Support for scaling splat textures in S and T, use mipmaps for them.
This commit is contained in:
parent
4f3f0989f5
commit
2dfabdfe64
9 changed files with 71 additions and 11 deletions
|
@ -11,6 +11,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// the number of splats per pass
|
||||||
const int SPLAT_COUNT = 4;
|
const int SPLAT_COUNT = 4;
|
||||||
|
|
||||||
// the splat textures
|
// the splat textures
|
||||||
|
@ -22,7 +23,7 @@ varying vec4 alphaValues;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// blend the splat textures
|
// blend the splat textures
|
||||||
gl_FragColor = gl_Color * (texture2D(diffuseMaps[0], gl_TexCoord[0].st) * alphaValues.x +
|
gl_FragColor = gl_Color * (texture2D(diffuseMaps[0], gl_TexCoord[0].st) * alphaValues.x +
|
||||||
texture2D(diffuseMaps[1], gl_TexCoord[0].st) * alphaValues.y +
|
texture2D(diffuseMaps[1], gl_TexCoord[1].st) * alphaValues.y +
|
||||||
texture2D(diffuseMaps[2], gl_TexCoord[0].st) * alphaValues.z +
|
texture2D(diffuseMaps[2], gl_TexCoord[2].st) * alphaValues.z +
|
||||||
texture2D(diffuseMaps[3], gl_TexCoord[0].st) * alphaValues.w);
|
texture2D(diffuseMaps[3], gl_TexCoord[3].st) * alphaValues.w);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,15 @@ uniform float heightScale;
|
||||||
// the scale between height and texture textures
|
// the scale between height and texture textures
|
||||||
uniform float textureScale;
|
uniform float textureScale;
|
||||||
|
|
||||||
|
// the splat texture offset
|
||||||
|
uniform vec2 splatTextureOffset;
|
||||||
|
|
||||||
|
// the splat textures scales on the S axis
|
||||||
|
uniform vec4 splatTextureScalesS;
|
||||||
|
|
||||||
|
// the splat texture scales on the T axis
|
||||||
|
uniform vec4 splatTextureScalesT;
|
||||||
|
|
||||||
// the lower bounds of the values corresponding to the splat textures
|
// the lower bounds of the values corresponding to the splat textures
|
||||||
uniform vec4 textureValueMinima;
|
uniform vec4 textureValueMinima;
|
||||||
|
|
||||||
|
@ -35,16 +44,21 @@ varying vec4 alphaValues;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// add the height to the position
|
// add the height to the position
|
||||||
float height = texture2D(heightMap, gl_MultiTexCoord0.st).r;
|
float height = texture2D(heightMap, gl_MultiTexCoord0.st).r;
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
vec4 modelSpacePosition = gl_Vertex + vec4(0.0, height, 0.0, 0.0);
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * modelSpacePosition;
|
||||||
|
|
||||||
// the zero height should be invisible
|
// the zero height should be invisible
|
||||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0 - step(height, 0.0));
|
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0 - step(height, 0.0));
|
||||||
|
|
||||||
// pass along the scaled/offset texture coordinates
|
// pass along the scaled/offset texture coordinates
|
||||||
gl_TexCoord[0] = (gl_MultiTexCoord0 - vec4(heightScale, heightScale, 0.0, 0.0)) * textureScale;
|
vec4 textureSpacePosition = vec4(modelSpacePosition.xz, 0.0, 1.0) + vec4(splatTextureOffset, 0.0, 0.0);
|
||||||
|
gl_TexCoord[0] = textureSpacePosition * vec4(splatTextureScalesS[0], splatTextureScalesT[0], 0.0, 1.0);
|
||||||
|
gl_TexCoord[1] = textureSpacePosition * vec4(splatTextureScalesS[1], splatTextureScalesT[1], 0.0, 1.0);
|
||||||
|
gl_TexCoord[2] = textureSpacePosition * vec4(splatTextureScalesS[2], splatTextureScalesT[2], 0.0, 1.0);
|
||||||
|
gl_TexCoord[3] = textureSpacePosition * vec4(splatTextureScalesS[3], splatTextureScalesT[3], 0.0, 1.0);
|
||||||
|
|
||||||
// compute the alpha values for each texture
|
// compute the alpha values for each texture
|
||||||
float value = texture2D(textureMap, gl_TexCoord[0].st).r;
|
float value = texture2D(textureMap, (gl_MultiTexCoord0.st - vec2(heightScale, heightScale)) * textureScale).r;
|
||||||
vec4 valueVector = vec4(value, value, value, value);
|
vec4 valueVector = vec4(value, value, value, value);
|
||||||
alphaValues = step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima);
|
alphaValues = step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima);
|
||||||
}
|
}
|
||||||
|
|
|
@ -822,22 +822,38 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightScaleLocation(), 1.0f / _heightSize);
|
DefaultMetavoxelRendererImplementation::getSplatHeightScaleLocation(), 1.0f / _heightSize);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureScaleLocation(), (float)_heightSize / innerSize);
|
DefaultMetavoxelRendererImplementation::getSplatTextureScaleLocation(), (float)_heightSize / innerSize);
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatTextureOffsetLocation(),
|
||||||
|
_translation.x / _scale, _translation.z / _scale);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureTextureID);
|
glBindTexture(GL_TEXTURE_2D, _textureTextureID);
|
||||||
|
|
||||||
const int TEXTURES_PER_SPLAT = 4;
|
const int TEXTURES_PER_SPLAT = 4;
|
||||||
for (int i = 0; i < _textures.size(); i += TEXTURES_PER_SPLAT) {
|
for (int i = 0; i < _textures.size(); i += TEXTURES_PER_SPLAT) {
|
||||||
|
QVector4D scalesS, scalesT;
|
||||||
|
|
||||||
for (int j = 0; j < SPLAT_COUNT; j++) {
|
for (int j = 0; j < SPLAT_COUNT; j++) {
|
||||||
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[j]);
|
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[j]);
|
||||||
int index = i + j;
|
int index = i + j;
|
||||||
if (index < _networkTextures.size()) {
|
if (index < _networkTextures.size()) {
|
||||||
const NetworkTexturePointer& texture = _networkTextures.at(index);
|
const NetworkTexturePointer& texture = _networkTextures.at(index);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture ? texture->getID() : 0);
|
if (texture) {
|
||||||
|
HeightfieldTexture* heightfieldTexture = static_cast<HeightfieldTexture*>(_textures.at(index).data());
|
||||||
|
scalesS[j] = _scale / heightfieldTexture->getScaleS();
|
||||||
|
scalesT[j] = _scale / heightfieldTexture->getScaleT();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->getID());
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL;
|
const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL;
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatTextureScalesSLocation(), scalesS);
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatTextureScalesTLocation(), scalesT);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureValueMinimaLocation(),
|
DefaultMetavoxelRendererImplementation::getSplatTextureValueMinimaLocation(),
|
||||||
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP,
|
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP,
|
||||||
|
@ -1050,6 +1066,9 @@ void DefaultMetavoxelRendererImplementation::init() {
|
||||||
_splatHeightfieldProgram.setUniformValueArray("diffuseMaps", SPLAT_TEXTURE_UNITS, SPLAT_COUNT);
|
_splatHeightfieldProgram.setUniformValueArray("diffuseMaps", SPLAT_TEXTURE_UNITS, SPLAT_COUNT);
|
||||||
_splatHeightScaleLocation = _splatHeightfieldProgram.uniformLocation("heightScale");
|
_splatHeightScaleLocation = _splatHeightfieldProgram.uniformLocation("heightScale");
|
||||||
_splatTextureScaleLocation = _splatHeightfieldProgram.uniformLocation("textureScale");
|
_splatTextureScaleLocation = _splatHeightfieldProgram.uniformLocation("textureScale");
|
||||||
|
_splatTextureOffsetLocation = _splatHeightfieldProgram.uniformLocation("splatTextureOffset");
|
||||||
|
_splatTextureScalesSLocation = _splatHeightfieldProgram.uniformLocation("splatTextureScalesS");
|
||||||
|
_splatTextureScalesTLocation = _splatHeightfieldProgram.uniformLocation("splatTextureScalesT");
|
||||||
_splatTextureValueMinimaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMinima");
|
_splatTextureValueMinimaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMinima");
|
||||||
_splatTextureValueMaximaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMaxima");
|
_splatTextureValueMaximaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMaxima");
|
||||||
_splatHeightfieldProgram.release();
|
_splatHeightfieldProgram.release();
|
||||||
|
@ -1695,6 +1714,9 @@ int DefaultMetavoxelRendererImplementation::_baseColorScaleLocation;
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_splatHeightfieldProgram;
|
ProgramObject DefaultMetavoxelRendererImplementation::_splatHeightfieldProgram;
|
||||||
int DefaultMetavoxelRendererImplementation::_splatHeightScaleLocation;
|
int DefaultMetavoxelRendererImplementation::_splatHeightScaleLocation;
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureScaleLocation;
|
int DefaultMetavoxelRendererImplementation::_splatTextureScaleLocation;
|
||||||
|
int DefaultMetavoxelRendererImplementation::_splatTextureOffsetLocation;
|
||||||
|
int DefaultMetavoxelRendererImplementation::_splatTextureScalesSLocation;
|
||||||
|
int DefaultMetavoxelRendererImplementation::_splatTextureScalesTLocation;
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureValueMinimaLocation;
|
int DefaultMetavoxelRendererImplementation::_splatTextureValueMinimaLocation;
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureValueMaximaLocation;
|
int DefaultMetavoxelRendererImplementation::_splatTextureValueMaximaLocation;
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_lightHeightfieldProgram;
|
ProgramObject DefaultMetavoxelRendererImplementation::_lightHeightfieldProgram;
|
||||||
|
|
|
@ -252,6 +252,9 @@ public:
|
||||||
static ProgramObject& getSplatHeightfieldProgram() { return _splatHeightfieldProgram; }
|
static ProgramObject& getSplatHeightfieldProgram() { return _splatHeightfieldProgram; }
|
||||||
static int getSplatHeightScaleLocation() { return _splatHeightScaleLocation; }
|
static int getSplatHeightScaleLocation() { return _splatHeightScaleLocation; }
|
||||||
static int getSplatTextureScaleLocation() { return _splatTextureScaleLocation; }
|
static int getSplatTextureScaleLocation() { return _splatTextureScaleLocation; }
|
||||||
|
static int getSplatTextureOffsetLocation() { return _splatTextureOffsetLocation; }
|
||||||
|
static int getSplatTextureScalesSLocation() { return _splatTextureScalesSLocation; }
|
||||||
|
static int getSplatTextureScalesTLocation() { return _splatTextureScalesTLocation; }
|
||||||
static int getSplatTextureValueMinimaLocation() { return _splatTextureValueMinimaLocation; }
|
static int getSplatTextureValueMinimaLocation() { return _splatTextureValueMinimaLocation; }
|
||||||
static int getSplatTextureValueMaximaLocation() { return _splatTextureValueMaximaLocation; }
|
static int getSplatTextureValueMaximaLocation() { return _splatTextureValueMaximaLocation; }
|
||||||
|
|
||||||
|
@ -297,6 +300,9 @@ private:
|
||||||
static ProgramObject _splatHeightfieldProgram;
|
static ProgramObject _splatHeightfieldProgram;
|
||||||
static int _splatHeightScaleLocation;
|
static int _splatHeightScaleLocation;
|
||||||
static int _splatTextureScaleLocation;
|
static int _splatTextureScaleLocation;
|
||||||
|
static int _splatTextureOffsetLocation;
|
||||||
|
static int _splatTextureScalesSLocation;
|
||||||
|
static int _splatTextureScalesTLocation;
|
||||||
static int _splatTextureValueMinimaLocation;
|
static int _splatTextureValueMinimaLocation;
|
||||||
static int _splatTextureValueMaximaLocation;
|
static int _splatTextureValueMaximaLocation;
|
||||||
|
|
||||||
|
|
|
@ -320,6 +320,7 @@ Texture::~Texture() {
|
||||||
|
|
||||||
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) :
|
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) :
|
||||||
Resource(url, !content.isEmpty()),
|
Resource(url, !content.isEmpty()),
|
||||||
|
_type(type),
|
||||||
_translucent(false) {
|
_translucent(false) {
|
||||||
|
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
|
@ -474,7 +475,13 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0,
|
||||||
GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
|
GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
|
||||||
}
|
}
|
||||||
|
if (_type == SPLAT_TEXTURE) {
|
||||||
|
// generate mipmaps for splat textures
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
} else {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
TextureType _type;
|
||||||
bool _translucent;
|
bool _translucent;
|
||||||
QColor _averageColor;
|
QColor _averageColor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1055,7 +1055,9 @@ void HeightfieldTextureData::read(Bitstream& in, int bytes) {
|
||||||
in >> _textures;
|
in >> _textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightfieldTexture::HeightfieldTexture() {
|
HeightfieldTexture::HeightfieldTexture() :
|
||||||
|
_scaleS(1.0f),
|
||||||
|
_scaleT(1.0f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightfieldAttribute::HeightfieldAttribute(const QString& name) :
|
HeightfieldAttribute::HeightfieldAttribute(const QString& name) :
|
||||||
|
|
|
@ -548,6 +548,8 @@ private:
|
||||||
class HeightfieldTexture : public SharedObject {
|
class HeightfieldTexture : public SharedObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QUrl url MEMBER _url)
|
Q_PROPERTY(QUrl url MEMBER _url)
|
||||||
|
Q_PROPERTY(float scaleS MEMBER _scaleS)
|
||||||
|
Q_PROPERTY(float scaleT MEMBER _scaleT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -555,9 +557,14 @@ public:
|
||||||
|
|
||||||
const QUrl& getURL() const { return _url; }
|
const QUrl& getURL() const { return _url; }
|
||||||
|
|
||||||
|
float getScaleS() const { return _scaleS; }
|
||||||
|
float getScaleT() const { return _scaleT; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
|
float _scaleS;
|
||||||
|
float _scaleT;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An attribute that stores heightfield data.
|
/// An attribute that stores heightfield data.
|
||||||
|
|
|
@ -81,7 +81,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeMetavoxelData:
|
case PacketTypeMetavoxelData:
|
||||||
return 2;
|
return 3;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue