mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 12:04:18 +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
|
||||
//
|
||||
|
||||
// the number of splats per pass
|
||||
const int SPLAT_COUNT = 4;
|
||||
|
||||
// the splat textures
|
||||
|
@ -22,7 +23,7 @@ varying vec4 alphaValues;
|
|||
void main(void) {
|
||||
// blend the splat textures
|
||||
gl_FragColor = gl_Color * (texture2D(diffuseMaps[0], gl_TexCoord[0].st) * alphaValues.x +
|
||||
texture2D(diffuseMaps[1], gl_TexCoord[0].st) * alphaValues.y +
|
||||
texture2D(diffuseMaps[2], gl_TexCoord[0].st) * alphaValues.z +
|
||||
texture2D(diffuseMaps[3], gl_TexCoord[0].st) * alphaValues.w);
|
||||
texture2D(diffuseMaps[1], gl_TexCoord[1].st) * alphaValues.y +
|
||||
texture2D(diffuseMaps[2], gl_TexCoord[2].st) * alphaValues.z +
|
||||
texture2D(diffuseMaps[3], gl_TexCoord[3].st) * alphaValues.w);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,15 @@ uniform float heightScale;
|
|||
// the scale between height and texture textures
|
||||
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
|
||||
uniform vec4 textureValueMinima;
|
||||
|
||||
|
@ -35,16 +44,21 @@ varying vec4 alphaValues;
|
|||
void main(void) {
|
||||
// add the height to the position
|
||||
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
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0 - step(height, 0.0));
|
||||
|
||||
// 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
|
||||
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);
|
||||
alphaValues = step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima);
|
||||
}
|
||||
|
|
|
@ -822,22 +822,38 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
DefaultMetavoxelRendererImplementation::getSplatHeightScaleLocation(), 1.0f / _heightSize);
|
||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||
DefaultMetavoxelRendererImplementation::getSplatTextureScaleLocation(), (float)_heightSize / innerSize);
|
||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||
DefaultMetavoxelRendererImplementation::getSplatTextureOffsetLocation(),
|
||||
_translation.x / _scale, _translation.z / _scale);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _textureTextureID);
|
||||
|
||||
const int TEXTURES_PER_SPLAT = 4;
|
||||
for (int i = 0; i < _textures.size(); i += TEXTURES_PER_SPLAT) {
|
||||
QVector4D scalesS, scalesT;
|
||||
|
||||
for (int j = 0; j < SPLAT_COUNT; j++) {
|
||||
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[j]);
|
||||
int index = i + j;
|
||||
if (index < _networkTextures.size()) {
|
||||
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 {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
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::getSplatTextureValueMinimaLocation(),
|
||||
(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);
|
||||
_splatHeightScaleLocation = _splatHeightfieldProgram.uniformLocation("heightScale");
|
||||
_splatTextureScaleLocation = _splatHeightfieldProgram.uniformLocation("textureScale");
|
||||
_splatTextureOffsetLocation = _splatHeightfieldProgram.uniformLocation("splatTextureOffset");
|
||||
_splatTextureScalesSLocation = _splatHeightfieldProgram.uniformLocation("splatTextureScalesS");
|
||||
_splatTextureScalesTLocation = _splatHeightfieldProgram.uniformLocation("splatTextureScalesT");
|
||||
_splatTextureValueMinimaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMinima");
|
||||
_splatTextureValueMaximaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMaxima");
|
||||
_splatHeightfieldProgram.release();
|
||||
|
@ -1695,6 +1714,9 @@ int DefaultMetavoxelRendererImplementation::_baseColorScaleLocation;
|
|||
ProgramObject DefaultMetavoxelRendererImplementation::_splatHeightfieldProgram;
|
||||
int DefaultMetavoxelRendererImplementation::_splatHeightScaleLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_splatTextureScaleLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_splatTextureOffsetLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_splatTextureScalesSLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_splatTextureScalesTLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_splatTextureValueMinimaLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_splatTextureValueMaximaLocation;
|
||||
ProgramObject DefaultMetavoxelRendererImplementation::_lightHeightfieldProgram;
|
||||
|
|
|
@ -252,6 +252,9 @@ public:
|
|||
static ProgramObject& getSplatHeightfieldProgram() { return _splatHeightfieldProgram; }
|
||||
static int getSplatHeightScaleLocation() { return _splatHeightScaleLocation; }
|
||||
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 getSplatTextureValueMaximaLocation() { return _splatTextureValueMaximaLocation; }
|
||||
|
||||
|
@ -297,6 +300,9 @@ private:
|
|||
static ProgramObject _splatHeightfieldProgram;
|
||||
static int _splatHeightScaleLocation;
|
||||
static int _splatTextureScaleLocation;
|
||||
static int _splatTextureOffsetLocation;
|
||||
static int _splatTextureScalesSLocation;
|
||||
static int _splatTextureScalesTLocation;
|
||||
static int _splatTextureValueMinimaLocation;
|
||||
static int _splatTextureValueMaximaLocation;
|
||||
|
||||
|
|
|
@ -320,6 +320,7 @@ Texture::~Texture() {
|
|||
|
||||
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) :
|
||||
Resource(url, !content.isEmpty()),
|
||||
_type(type),
|
||||
_translucent(false) {
|
||||
|
||||
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,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
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);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
TextureType _type;
|
||||
bool _translucent;
|
||||
QColor _averageColor;
|
||||
};
|
||||
|
|
|
@ -1055,7 +1055,9 @@ void HeightfieldTextureData::read(Bitstream& in, int bytes) {
|
|||
in >> _textures;
|
||||
}
|
||||
|
||||
HeightfieldTexture::HeightfieldTexture() {
|
||||
HeightfieldTexture::HeightfieldTexture() :
|
||||
_scaleS(1.0f),
|
||||
_scaleT(1.0f) {
|
||||
}
|
||||
|
||||
HeightfieldAttribute::HeightfieldAttribute(const QString& name) :
|
||||
|
|
|
@ -548,16 +548,23 @@ private:
|
|||
class HeightfieldTexture : public SharedObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUrl url MEMBER _url)
|
||||
|
||||
Q_PROPERTY(float scaleS MEMBER _scaleS)
|
||||
Q_PROPERTY(float scaleT MEMBER _scaleT)
|
||||
|
||||
public:
|
||||
|
||||
Q_INVOKABLE HeightfieldTexture();
|
||||
|
||||
const QUrl& getURL() const { return _url; }
|
||||
|
||||
float getScaleS() const { return _scaleS; }
|
||||
float getScaleT() const { return _scaleT; }
|
||||
|
||||
private:
|
||||
|
||||
QUrl _url;
|
||||
float _scaleS;
|
||||
float _scaleT;
|
||||
};
|
||||
|
||||
/// An attribute that stores heightfield data.
|
||||
|
|
|
@ -81,7 +81,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
|||
case PacketTypeAudioStreamStats:
|
||||
return 1;
|
||||
case PacketTypeMetavoxelData:
|
||||
return 2;
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue