mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-09 20:08:31 +02:00
Attempting to remove some number magic.
This commit is contained in:
parent
24cc90c1db
commit
ee01d85b5e
5 changed files with 95 additions and 73 deletions
|
@ -333,12 +333,11 @@ void PointBuffer::render(bool cursor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
|
HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
|
||||||
const QByteArray& height, const QByteArray& color, bool clearAfterLoading) :
|
const QByteArray& height, const QByteArray& color) :
|
||||||
_translation(translation),
|
_translation(translation),
|
||||||
_scale(scale),
|
_scale(scale),
|
||||||
_height(height),
|
_height(height),
|
||||||
_color(color),
|
_color(color),
|
||||||
_clearAfterLoading(clearAfterLoading),
|
|
||||||
_heightTextureID(0),
|
_heightTextureID(0),
|
||||||
_colorTextureID(0),
|
_colorTextureID(0),
|
||||||
_heightSize(glm::sqrt(height.size())) {
|
_heightSize(glm::sqrt(height.size())) {
|
||||||
|
@ -355,6 +354,32 @@ HeightfieldBuffer::~HeightfieldBuffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray HeightfieldBuffer::getUnextendedHeight() const {
|
||||||
|
int srcSize = glm::sqrt(_height.size());
|
||||||
|
int destSize = srcSize - 3;
|
||||||
|
QByteArray unextended(destSize * destSize, 0);
|
||||||
|
const char* src = _height.constData() + srcSize + 1;
|
||||||
|
char* dest = unextended.data();
|
||||||
|
for (int z = 0; z < destSize; z++, src += srcSize, dest += destSize) {
|
||||||
|
memcpy(dest, src, destSize);
|
||||||
|
}
|
||||||
|
return unextended;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray HeightfieldBuffer::getUnextendedColor() const {
|
||||||
|
int srcSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
|
||||||
|
int destSize = srcSize - 1;
|
||||||
|
QByteArray unextended(destSize * destSize * HeightfieldData::COLOR_BYTES, 0);
|
||||||
|
const char* src = _color.constData();
|
||||||
|
int srcStride = srcSize * HeightfieldData::COLOR_BYTES;
|
||||||
|
char* dest = unextended.data();
|
||||||
|
int destStride = destSize * HeightfieldData::COLOR_BYTES;
|
||||||
|
for (int z = 0; z < destSize; z++, src += srcStride, dest += destStride) {
|
||||||
|
memcpy(dest, src, destStride);
|
||||||
|
}
|
||||||
|
return unextended;
|
||||||
|
}
|
||||||
|
|
||||||
class HeightfieldPoint {
|
class HeightfieldPoint {
|
||||||
public:
|
public:
|
||||||
glm::vec2 textureCoord;
|
glm::vec2 textureCoord;
|
||||||
|
@ -372,9 +397,6 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, _heightSize, _heightSize, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, _heightSize, _heightSize, 0,
|
||||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, _height.constData());
|
GL_LUMINANCE, GL_UNSIGNED_BYTE, _height.constData());
|
||||||
if (_clearAfterLoading) {
|
|
||||||
_height.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
glGenTextures(1, &_colorTextureID);
|
glGenTextures(1, &_colorTextureID);
|
||||||
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
||||||
|
@ -386,15 +408,12 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int colorSize = glm::sqrt(_color.size() / 3);
|
int colorSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());
|
||||||
if (_clearAfterLoading) {
|
|
||||||
_color.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create the buffer objects lazily
|
// create the buffer objects lazily
|
||||||
int innerSize = _heightSize - 2;
|
int innerSize = _heightSize - 2 * HeightfieldBuffer::HEIGHT_BORDER;
|
||||||
int vertexCount = _heightSize * _heightSize;
|
int vertexCount = _heightSize * _heightSize;
|
||||||
int rows = _heightSize - 1;
|
int rows = _heightSize - 1;
|
||||||
int indexCount = rows * rows * 4;
|
int indexCount = rows * rows * 4;
|
||||||
|
@ -682,9 +701,9 @@ int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
if (height) {
|
if (height) {
|
||||||
const QByteArray& heightContents = height->getContents();
|
const QByteArray& heightContents = height->getContents();
|
||||||
int size = glm::sqrt(heightContents.size());
|
int size = glm::sqrt(heightContents.size());
|
||||||
int extendedSize = size + 3;
|
int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;
|
||||||
QByteArray extendedHeightContents(extendedSize * extendedSize, 0);
|
QByteArray extendedHeightContents(extendedSize * extendedSize, 0);
|
||||||
char* dest = extendedHeightContents.data() + extendedSize + 1;
|
char* dest = extendedHeightContents.data() + (extendedSize + 1) * HeightfieldBuffer::HEIGHT_BORDER;
|
||||||
const char* src = heightContents.constData();
|
const char* src = heightContents.constData();
|
||||||
for (int z = 0; z < size; z++, src += size, dest += extendedSize) {
|
for (int z = 0; z < size; z++, src += size, dest += extendedSize) {
|
||||||
memcpy(dest, src, size);
|
memcpy(dest, src, size);
|
||||||
|
@ -693,14 +712,13 @@ int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
|
HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
|
||||||
if (color) {
|
if (color) {
|
||||||
const QByteArray& colorContents = color->getContents();
|
const QByteArray& colorContents = color->getContents();
|
||||||
const int BYTES_PER_PIXEL = 3;
|
int colorSize = glm::sqrt(colorContents.size() / HeightfieldData::COLOR_BYTES);
|
||||||
int colorSize = glm::sqrt(colorContents.size() / BYTES_PER_PIXEL);
|
int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
|
||||||
int extendedColorSize = colorSize + 1;
|
extendedColorContents = QByteArray(extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES, 0);
|
||||||
extendedColorContents = QByteArray(extendedColorSize * extendedColorSize * BYTES_PER_PIXEL, 0);
|
|
||||||
char* dest = extendedColorContents.data();
|
char* dest = extendedColorContents.data();
|
||||||
const char* src = colorContents.constData();
|
const char* src = colorContents.constData();
|
||||||
int srcStride = colorSize * BYTES_PER_PIXEL;
|
int srcStride = colorSize * HeightfieldData::COLOR_BYTES;
|
||||||
int destStride = extendedColorSize * BYTES_PER_PIXEL;
|
int destStride = extendedColorSize * HeightfieldData::COLOR_BYTES;
|
||||||
for (int z = 0; z < colorSize; z++, src += srcStride, dest += destStride) {
|
for (int z = 0; z < colorSize; z++, src += srcStride, dest += destStride) {
|
||||||
memcpy(dest, src, srcStride);
|
memcpy(dest, src, srcStride);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,10 +131,11 @@ private:
|
||||||
class HeightfieldBuffer : public BufferData {
|
class HeightfieldBuffer : public BufferData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Creates a new heightfield buffer.
|
static const int HEIGHT_BORDER = 1;
|
||||||
/// \param clearAfterLoading if true, clear the data arrays after we load them into textures in order to reclaim the space
|
static const int SHARED_EDGE = 1;
|
||||||
HeightfieldBuffer(const glm::vec3& translation, float scale, const QByteArray& height, const QByteArray& color,
|
static const int HEIGHT_EXTENSION = 2 * HEIGHT_BORDER + SHARED_EDGE;
|
||||||
bool clearAfterLoading = true);
|
|
||||||
|
HeightfieldBuffer(const glm::vec3& translation, float scale, const QByteArray& height, const QByteArray& color);
|
||||||
~HeightfieldBuffer();
|
~HeightfieldBuffer();
|
||||||
|
|
||||||
const glm::vec3& getTranslation() const { return _translation; }
|
const glm::vec3& getTranslation() const { return _translation; }
|
||||||
|
@ -142,6 +143,9 @@ public:
|
||||||
const QByteArray& getHeight() const { return _height; }
|
const QByteArray& getHeight() const { return _height; }
|
||||||
const QByteArray& getColor() const { return _color; }
|
const QByteArray& getColor() const { return _color; }
|
||||||
|
|
||||||
|
QByteArray getUnextendedHeight() const;
|
||||||
|
QByteArray getUnextendedColor() const;
|
||||||
|
|
||||||
virtual void render(bool cursor = false);
|
virtual void render(bool cursor = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -150,7 +154,6 @@ private:
|
||||||
float _scale;
|
float _scale;
|
||||||
QByteArray _height;
|
QByteArray _height;
|
||||||
QByteArray _color;
|
QByteArray _color;
|
||||||
bool _clearAfterLoading;
|
|
||||||
GLuint _heightTextureID;
|
GLuint _heightTextureID;
|
||||||
GLuint _colorTextureID;
|
GLuint _colorTextureID;
|
||||||
int _heightSize;
|
int _heightSize;
|
||||||
|
|
|
@ -956,11 +956,11 @@ void ImportHeightfieldTool::apply() {
|
||||||
HeightfieldBuffer* buffer = static_cast<HeightfieldBuffer*>(bufferData.data());
|
HeightfieldBuffer* buffer = static_cast<HeightfieldBuffer*>(bufferData.data());
|
||||||
MetavoxelData data;
|
MetavoxelData data;
|
||||||
data.setSize(scale);
|
data.setSize(scale);
|
||||||
HeightfieldDataPointer heightPointer(new HeightfieldData(buffer->getHeight()));
|
HeightfieldDataPointer heightPointer(new HeightfieldData(buffer->getUnextendedHeight()));
|
||||||
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldAttribute(), new MetavoxelNode(AttributeValue(
|
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldAttribute(), new MetavoxelNode(AttributeValue(
|
||||||
AttributeRegistry::getInstance()->getHeightfieldAttribute(), encodeInline(heightPointer))));
|
AttributeRegistry::getInstance()->getHeightfieldAttribute(), encodeInline(heightPointer))));
|
||||||
if (!buffer->getColor().isEmpty()) {
|
if (!buffer->getColor().isEmpty()) {
|
||||||
HeightfieldDataPointer colorPointer(new HeightfieldData(buffer->getColor()));
|
HeightfieldDataPointer colorPointer(new HeightfieldData(buffer->getUnextendedColor()));
|
||||||
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), new MetavoxelNode(AttributeValue(
|
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), new MetavoxelNode(AttributeValue(
|
||||||
AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), encodeInline(colorPointer))));
|
AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), encodeInline(colorPointer))));
|
||||||
}
|
}
|
||||||
|
@ -1003,38 +1003,38 @@ void ImportHeightfieldTool::updatePreview() {
|
||||||
if (_heightImage.width() > 0 && _heightImage.height() > 0) {
|
if (_heightImage.width() > 0 && _heightImage.height() > 0) {
|
||||||
float z = 0.0f;
|
float z = 0.0f;
|
||||||
int blockSize = pow(2.0, _blockSize->value());
|
int blockSize = pow(2.0, _blockSize->value());
|
||||||
int heightSize = blockSize + 3;
|
int heightSize = blockSize + HeightfieldBuffer::HEIGHT_EXTENSION;
|
||||||
int colorSize = blockSize + 1;
|
int colorSize = blockSize + HeightfieldBuffer::SHARED_EDGE;
|
||||||
for (int i = 0; i < _heightImage.height(); i += blockSize, z++) {
|
for (int i = 0; i < _heightImage.height(); i += blockSize, z++) {
|
||||||
float x = 0.0f;
|
float x = 0.0f;
|
||||||
for (int j = 0; j < _heightImage.width(); j += blockSize, x++) {
|
for (int j = 0; j < _heightImage.width(); j += blockSize, x++) {
|
||||||
QByteArray height(heightSize * heightSize, 0);
|
QByteArray height(heightSize * heightSize, 0);
|
||||||
int extendedI = qMax(i - 1, 0);
|
int extendedI = qMax(i - HeightfieldBuffer::HEIGHT_BORDER, 0);
|
||||||
int extendedJ = qMax(j - 1, 0);
|
int extendedJ = qMax(j - HeightfieldBuffer::HEIGHT_BORDER, 0);
|
||||||
int offsetY = extendedI - i + 1;
|
int offsetY = extendedI - i + HeightfieldBuffer::HEIGHT_BORDER;
|
||||||
int offsetX = extendedJ - j + 1;
|
int offsetX = extendedJ - j + HeightfieldBuffer::HEIGHT_BORDER;
|
||||||
int rows = qMin(heightSize - offsetY, _heightImage.height() - extendedI);
|
int rows = qMin(heightSize - offsetY, _heightImage.height() - extendedI);
|
||||||
int columns = qMin(heightSize - offsetX, _heightImage.width() - extendedJ);
|
int columns = qMin(heightSize - offsetX, _heightImage.width() - extendedJ);
|
||||||
const int BYTES_PER_COLOR = 3;
|
|
||||||
for (int y = 0; y < rows; y++) {
|
for (int y = 0; y < rows; y++) {
|
||||||
uchar* src = _heightImage.scanLine(extendedI + y) + extendedJ * BYTES_PER_COLOR;
|
uchar* src = _heightImage.scanLine(extendedI + y) + extendedJ * HeightfieldData::COLOR_BYTES;
|
||||||
char* dest = height.data() + (y + offsetY) * heightSize + offsetX;
|
char* dest = height.data() + (y + offsetY) * heightSize + offsetX;
|
||||||
for (int x = 0; x < columns; x++) {
|
for (int x = 0; x < columns; x++) {
|
||||||
*dest++ = *src;
|
*dest++ = *src;
|
||||||
src += BYTES_PER_COLOR;
|
src += HeightfieldData::COLOR_BYTES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QByteArray color;
|
QByteArray color;
|
||||||
if (!_colorImage.isNull()) {
|
if (!_colorImage.isNull()) {
|
||||||
color = QByteArray(colorSize * colorSize * BYTES_PER_COLOR, 0);
|
color = QByteArray(colorSize * colorSize * HeightfieldData::COLOR_BYTES, 0);
|
||||||
rows = qMax(0, qMin(colorSize, _colorImage.height() - i));
|
rows = qMax(0, qMin(colorSize, _colorImage.height() - i));
|
||||||
columns = qMax(0, qMin(colorSize, _colorImage.width() - j));
|
columns = qMax(0, qMin(colorSize, _colorImage.width() - j));
|
||||||
for (int y = 0; y < rows; y++) {
|
for (int y = 0; y < rows; y++) {
|
||||||
memcpy(color.data() + y * colorSize * BYTES_PER_COLOR,
|
memcpy(color.data() + y * colorSize * HeightfieldData::COLOR_BYTES,
|
||||||
_colorImage.scanLine(i + y) + j * BYTES_PER_COLOR, columns * BYTES_PER_COLOR);
|
_colorImage.scanLine(i + y) + j * HeightfieldData::COLOR_BYTES,
|
||||||
|
columns * HeightfieldData::COLOR_BYTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffers.append(BufferDataPointer(new HeightfieldBuffer(glm::vec3(x, 0.0f, z), 1.0f, height, color, false)));
|
buffers.append(BufferDataPointer(new HeightfieldBuffer(glm::vec3(x, 0.0f, z), 1.0f, height, color)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -489,9 +489,6 @@ HeightfieldData::HeightfieldData(const QByteArray& contents) :
|
||||||
_contents(contents) {
|
_contents(contents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const int BYTES_PER_PIXEL = 3;
|
|
||||||
const int ZERO_OFFSET = 128;
|
|
||||||
|
|
||||||
HeightfieldData::HeightfieldData(Bitstream& in, int bytes, bool color) {
|
HeightfieldData::HeightfieldData(Bitstream& in, int bytes, bool color) {
|
||||||
read(in, bytes, color);
|
read(in, bytes, color);
|
||||||
}
|
}
|
||||||
|
@ -515,10 +512,10 @@ HeightfieldData::HeightfieldData(Bitstream& in, int bytes, const HeightfieldData
|
||||||
int minX = offset.x() - 1;
|
int minX = offset.x() - 1;
|
||||||
int minY = offset.y() - 1;
|
int minY = offset.y() - 1;
|
||||||
if (color) {
|
if (color) {
|
||||||
int size = glm::sqrt(_contents.size() / (float)BYTES_PER_PIXEL);
|
int size = glm::sqrt(_contents.size() / (float)COLOR_BYTES);
|
||||||
char* dest = _contents.data() + (minY * size + minX) * BYTES_PER_PIXEL;
|
char* dest = _contents.data() + (minY * size + minX) * COLOR_BYTES;
|
||||||
int destStride = size * BYTES_PER_PIXEL;
|
int destStride = size * COLOR_BYTES;
|
||||||
int srcStride = image.width() * BYTES_PER_PIXEL;
|
int srcStride = image.width() * COLOR_BYTES;
|
||||||
for (int y = 0; y < image.height(); y++) {
|
for (int y = 0; y < image.height(); y++) {
|
||||||
memcpy(dest, image.constScanLine(y), srcStride);
|
memcpy(dest, image.constScanLine(y), srcStride);
|
||||||
dest += destStride;
|
dest += destStride;
|
||||||
|
@ -528,7 +525,7 @@ HeightfieldData::HeightfieldData(Bitstream& in, int bytes, const HeightfieldData
|
||||||
char* lineDest = _contents.data() + minY * size + minX;
|
char* lineDest = _contents.data() + minY * size + minX;
|
||||||
for (int y = 0; y < image.height(); y++) {
|
for (int y = 0; y < image.height(); y++) {
|
||||||
const uchar* src = image.constScanLine(y);
|
const uchar* src = image.constScanLine(y);
|
||||||
for (char* dest = lineDest, *end = dest + image.width(); dest != end; dest++, src += BYTES_PER_PIXEL) {
|
for (char* dest = lineDest, *end = dest + image.width(); dest != end; dest++, src += COLOR_BYTES) {
|
||||||
*dest = *src;
|
*dest = *src;
|
||||||
}
|
}
|
||||||
lineDest += size;
|
lineDest += size;
|
||||||
|
@ -541,7 +538,7 @@ void HeightfieldData::write(Bitstream& out, bool color) {
|
||||||
if (_encoded.isEmpty()) {
|
if (_encoded.isEmpty()) {
|
||||||
QImage image;
|
QImage image;
|
||||||
if (color) {
|
if (color) {
|
||||||
int size = glm::sqrt(_contents.size() / (float)BYTES_PER_PIXEL);
|
int size = glm::sqrt(_contents.size() / (float)COLOR_BYTES);
|
||||||
image = QImage((uchar*)_contents.data(), size, size, QImage::Format_RGB888);
|
image = QImage((uchar*)_contents.data(), size, size, QImage::Format_RGB888);
|
||||||
} else {
|
} else {
|
||||||
int size = glm::sqrt((float)_contents.size());
|
int size = glm::sqrt((float)_contents.size());
|
||||||
|
@ -571,7 +568,7 @@ void HeightfieldData::writeDelta(Bitstream& out, const HeightfieldDataPointer& r
|
||||||
QImage image;
|
QImage image;
|
||||||
int minX, minY;
|
int minX, minY;
|
||||||
if (color) {
|
if (color) {
|
||||||
int size = glm::sqrt(_contents.size() / (float)BYTES_PER_PIXEL);
|
int size = glm::sqrt(_contents.size() / (float)COLOR_BYTES);
|
||||||
minX = size;
|
minX = size;
|
||||||
minY = size;
|
minY = size;
|
||||||
int maxX = -1, maxY = -1;
|
int maxX = -1, maxY = -1;
|
||||||
|
@ -579,7 +576,7 @@ void HeightfieldData::writeDelta(Bitstream& out, const HeightfieldDataPointer& r
|
||||||
const char* ref = reference->_contents.constData();
|
const char* ref = reference->_contents.constData();
|
||||||
for (int y = 0; y < size; y++) {
|
for (int y = 0; y < size; y++) {
|
||||||
bool difference = false;
|
bool difference = false;
|
||||||
for (int x = 0; x < size; x++, src += BYTES_PER_PIXEL, ref += BYTES_PER_PIXEL) {
|
for (int x = 0; x < size; x++, src += COLOR_BYTES, ref += COLOR_BYTES) {
|
||||||
if (src[0] != ref[0] || src[1] != ref[1] || src[2] != ref[2]) {
|
if (src[0] != ref[0] || src[1] != ref[1] || src[2] != ref[2]) {
|
||||||
minX = qMin(minX, x);
|
minX = qMin(minX, x);
|
||||||
maxX = qMax(maxX, x);
|
maxX = qMax(maxX, x);
|
||||||
|
@ -594,9 +591,9 @@ void HeightfieldData::writeDelta(Bitstream& out, const HeightfieldDataPointer& r
|
||||||
int width = qMax(maxX - minX + 1, 0);
|
int width = qMax(maxX - minX + 1, 0);
|
||||||
int height = qMax(maxY - minY + 1, 0);
|
int height = qMax(maxY - minY + 1, 0);
|
||||||
image = QImage(width, height, QImage::Format_RGB888);
|
image = QImage(width, height, QImage::Format_RGB888);
|
||||||
src = _contents.constData() + (minY * size + minX) * BYTES_PER_PIXEL;
|
src = _contents.constData() + (minY * size + minX) * COLOR_BYTES;
|
||||||
int srcStride = size * BYTES_PER_PIXEL;
|
int srcStride = size * COLOR_BYTES;
|
||||||
int destStride = width * BYTES_PER_PIXEL;
|
int destStride = width * COLOR_BYTES;
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
memcpy(image.scanLine(y), src, destStride);
|
memcpy(image.scanLine(y), src, destStride);
|
||||||
src += srcStride;
|
src += srcStride;
|
||||||
|
@ -652,14 +649,14 @@ void HeightfieldData::read(Bitstream& in, int bytes, bool color) {
|
||||||
|
|
||||||
void HeightfieldData::set(const QImage& image, bool color) {
|
void HeightfieldData::set(const QImage& image, bool color) {
|
||||||
if (color) {
|
if (color) {
|
||||||
_contents.resize(image.width() * image.height() * BYTES_PER_PIXEL);
|
_contents.resize(image.width() * image.height() * COLOR_BYTES);
|
||||||
memcpy(_contents.data(), image.constBits(), _contents.size());
|
memcpy(_contents.data(), image.constBits(), _contents.size());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_contents.resize(image.width() * image.height());
|
_contents.resize(image.width() * image.height());
|
||||||
char* dest = _contents.data();
|
char* dest = _contents.data();
|
||||||
for (const uchar* src = image.constBits(), *end = src + _contents.size() * BYTES_PER_PIXEL;
|
for (const uchar* src = image.constBits(), *end = src + _contents.size() * COLOR_BYTES;
|
||||||
src != end; src += BYTES_PER_PIXEL) {
|
src != end; src += COLOR_BYTES) {
|
||||||
*dest++ = *src;
|
*dest++ = *src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -856,8 +853,8 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
|
||||||
*(HeightfieldDataPointer*)&parent = HeightfieldDataPointer();
|
*(HeightfieldDataPointer*)&parent = HeightfieldDataPointer();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int size = glm::sqrt(maxSize / (float)BYTES_PER_PIXEL);
|
int size = glm::sqrt(maxSize / (float)HeightfieldData::COLOR_BYTES);
|
||||||
QByteArray contents(size * size * BYTES_PER_PIXEL, 0);
|
QByteArray contents(size * size * HeightfieldData::COLOR_BYTES, 0);
|
||||||
int halfSize = size / 2;
|
int halfSize = size / 2;
|
||||||
for (int i = 0; i < MERGE_COUNT; i++) {
|
for (int i = 0; i < MERGE_COUNT; i++) {
|
||||||
HeightfieldDataPointer child = decodeInline<HeightfieldDataPointer>(children[i]);
|
HeightfieldDataPointer child = decodeInline<HeightfieldDataPointer>(children[i]);
|
||||||
|
@ -865,7 +862,7 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const QByteArray& childContents = child->getContents();
|
const QByteArray& childContents = child->getContents();
|
||||||
int childSize = glm::sqrt(childContents.size() / (float)BYTES_PER_PIXEL);
|
int childSize = glm::sqrt(childContents.size() / (float)HeightfieldData::COLOR_BYTES);
|
||||||
const int INDEX_MASK = 1;
|
const int INDEX_MASK = 1;
|
||||||
int xIndex = i & INDEX_MASK;
|
int xIndex = i & INDEX_MASK;
|
||||||
const int Y_SHIFT = 1;
|
const int Y_SHIFT = 1;
|
||||||
|
@ -875,24 +872,25 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
|
||||||
}
|
}
|
||||||
int Z_SHIFT = 2;
|
int Z_SHIFT = 2;
|
||||||
int zIndex = (i >> Z_SHIFT) & INDEX_MASK;
|
int zIndex = (i >> Z_SHIFT) & INDEX_MASK;
|
||||||
char* dest = contents.data() + ((zIndex * halfSize * size) + (xIndex * halfSize)) * BYTES_PER_PIXEL;
|
char* dest = contents.data() + ((zIndex * halfSize * size) + (xIndex * halfSize)) * HeightfieldData::COLOR_BYTES;
|
||||||
uchar* src = (uchar*)childContents.data();
|
uchar* src = (uchar*)childContents.data();
|
||||||
int childStride = childSize * BYTES_PER_PIXEL;
|
int childStride = childSize * HeightfieldData::COLOR_BYTES;
|
||||||
int stride = size * BYTES_PER_PIXEL;
|
int stride = size * HeightfieldData::COLOR_BYTES;
|
||||||
int halfStride = stride / 2;
|
int halfStride = stride / 2;
|
||||||
int childStep = 2 * BYTES_PER_PIXEL;
|
int childStep = 2 * HeightfieldData::COLOR_BYTES;
|
||||||
int redOffset3 = childStride + BYTES_PER_PIXEL;
|
int redOffset3 = childStride + HeightfieldData::COLOR_BYTES;
|
||||||
int greenOffset1 = BYTES_PER_PIXEL + 1;
|
int greenOffset1 = HeightfieldData::COLOR_BYTES + 1;
|
||||||
int greenOffset2 = childStride + 1;
|
int greenOffset2 = childStride + 1;
|
||||||
int greenOffset3 = childStride + BYTES_PER_PIXEL + 1;
|
int greenOffset3 = childStride + HeightfieldData::COLOR_BYTES + 1;
|
||||||
int blueOffset1 = BYTES_PER_PIXEL + 2;
|
int blueOffset1 = HeightfieldData::COLOR_BYTES + 2;
|
||||||
int blueOffset2 = childStride + 2;
|
int blueOffset2 = childStride + 2;
|
||||||
int blueOffset3 = childStride + BYTES_PER_PIXEL + 2;
|
int blueOffset3 = childStride + HeightfieldData::COLOR_BYTES + 2;
|
||||||
if (childSize == size) {
|
if (childSize == size) {
|
||||||
// simple case: one destination value for four child values
|
// simple case: one destination value for four child values
|
||||||
for (int z = 0; z < halfSize; z++) {
|
for (int z = 0; z < halfSize; z++) {
|
||||||
for (char* end = dest + halfSize * BYTES_PER_PIXEL; dest != end; src += childStep) {
|
for (char* end = dest + halfSize * HeightfieldData::COLOR_BYTES; dest != end; src += childStep) {
|
||||||
*dest++ = ((int)src[0] + (int)src[BYTES_PER_PIXEL] + (int)src[childStride] + (int)src[redOffset3]) >> 2;
|
*dest++ = ((int)src[0] + (int)src[HeightfieldData::COLOR_BYTES] +
|
||||||
|
(int)src[childStride] + (int)src[redOffset3]) >> 2;
|
||||||
*dest++ = ((int)src[1] + (int)src[greenOffset1] + (int)src[greenOffset2] + (int)src[greenOffset3]) >> 2;
|
*dest++ = ((int)src[1] + (int)src[greenOffset1] + (int)src[greenOffset2] + (int)src[greenOffset3]) >> 2;
|
||||||
*dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
|
*dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
|
||||||
}
|
}
|
||||||
|
@ -904,13 +902,14 @@ bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool post
|
||||||
int halfChildSize = childSize / 2;
|
int halfChildSize = childSize / 2;
|
||||||
int destPerSrc = size / childSize;
|
int destPerSrc = size / childSize;
|
||||||
for (int z = 0; z < halfChildSize; z++) {
|
for (int z = 0; z < halfChildSize; z++) {
|
||||||
for (uchar* end = src + childSize * BYTES_PER_PIXEL; src != end; src += childStep) {
|
for (uchar* end = src + childSize * HeightfieldData::COLOR_BYTES; src != end; src += childStep) {
|
||||||
*dest++ = ((int)src[0] + (int)src[BYTES_PER_PIXEL] + (int)src[childStride] + (int)src[redOffset3]) >> 2;
|
*dest++ = ((int)src[0] + (int)src[HeightfieldData::COLOR_BYTES] +
|
||||||
|
(int)src[childStride] + (int)src[redOffset3]) >> 2;
|
||||||
*dest++ = ((int)src[1] + (int)src[greenOffset1] + (int)src[greenOffset2] + (int)src[greenOffset3]) >> 2;
|
*dest++ = ((int)src[1] + (int)src[greenOffset1] + (int)src[greenOffset2] + (int)src[greenOffset3]) >> 2;
|
||||||
*dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
|
*dest++ = ((int)src[2] + (int)src[blueOffset1] + (int)src[blueOffset2] + (int)src[blueOffset3]) >> 2;
|
||||||
for (int j = 1; j < destPerSrc; j++) {
|
for (int j = 1; j < destPerSrc; j++) {
|
||||||
memcpy(dest, dest - BYTES_PER_PIXEL, BYTES_PER_PIXEL);
|
memcpy(dest, dest - HeightfieldData::COLOR_BYTES, HeightfieldData::COLOR_BYTES);
|
||||||
dest += BYTES_PER_PIXEL;
|
dest += HeightfieldData::COLOR_BYTES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest += halfStride;
|
dest += halfStride;
|
||||||
|
|
|
@ -428,6 +428,8 @@ typedef QExplicitlySharedDataPointer<HeightfieldData> HeightfieldDataPointer;
|
||||||
class HeightfieldData : public QSharedData {
|
class HeightfieldData : public QSharedData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static const int COLOR_BYTES = 3;
|
||||||
|
|
||||||
HeightfieldData(const QByteArray& contents);
|
HeightfieldData(const QByteArray& contents);
|
||||||
HeightfieldData(Bitstream& in, int bytes, bool color);
|
HeightfieldData(Bitstream& in, int bytes, bool color);
|
||||||
HeightfieldData(Bitstream& in, int bytes, const HeightfieldDataPointer& reference, bool color);
|
HeightfieldData(Bitstream& in, int bytes, const HeightfieldDataPointer& reference, bool color);
|
||||||
|
|
Loading…
Reference in a new issue