History

Yet more texture bits.

Andrzej Kapolka committed 12 years ago

Commit 7cf7f181 parent 540d0743 files · +106 −15Browse files

Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 3 files). Show all

Unified · Split

interface/src/MetavoxelSystem.cpp+88−11
@@ -449,9 +449,10 @@ void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float r · 448 unmodified lines
449 glDepthFunc(GL_LESS);449 glDepthFunc(GL_LESS);
450}450}
451 451
452void MetavoxelSystem::deleteTextures(int heightID, int colorID) {452void MetavoxelSystem::deleteTextures(int heightID, int colorID, int textureID) {
453 glDeleteTextures(1, (GLuint*)&heightID);453 glDeleteTextures(1, (GLuint*)&heightID);
454 glDeleteTextures(1, (GLuint*)&colorID);454 glDeleteTextures(1, (GLuint*)&colorID);
455 glDeleteTextures(1, (GLuint*)&textureID);
455}456}
456 457
457MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {458MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
@@ -601,19 +602,24 @@ const int HeightfieldBuffer::SHARED_EDGE = 1; · 143 unmodified lines
601const int HeightfieldBuffer::HEIGHT_EXTENSION = 2 * HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE;602const int HeightfieldBuffer::HEIGHT_EXTENSION = 2 * HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE;
602 603
603HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,604HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
604 const QByteArray& height, const QByteArray& color) :605 const QByteArray& height, const QByteArray& color, const QByteArray& texture) :
605 _translation(translation),606 _translation(translation),
606 _scale(scale),607 _scale(scale),
607 _heightBounds(translation, translation + glm::vec3(scale, scale, scale)),608 _heightBounds(translation, translation + glm::vec3(scale, scale, scale)),
608 _colorBounds(_heightBounds),609 _colorBounds(_heightBounds),
610 _textureBounds(_heightBounds),
609 _height(height),611 _height(height),
610 _color(color),612 _color(color),
613 _texture(texture),
611 _heightTextureID(0),614 _heightTextureID(0),
612 _colorTextureID(0),615 _colorTextureID(0),
616 _textureTextureID(0),
613 _heightSize(glm::sqrt(height.size())),617 _heightSize(glm::sqrt(height.size())),
614 _heightIncrement(scale / (_heightSize - HEIGHT_EXTENSION)),618 _heightIncrement(scale / (_heightSize - HEIGHT_EXTENSION)),
615 _colorSize(glm::sqrt(color.size() / HeightfieldData::COLOR_BYTES)),619 _colorSize(glm::sqrt(color.size() / HeightfieldData::COLOR_BYTES)),
616 _colorIncrement(scale / (_colorSize - SHARED_EDGE)) {620 _colorIncrement(scale / (_colorSize - SHARED_EDGE)),
621 _textureSize(glm::sqrt(texture.size())),
622 _textureIncrement(scale / (_textureSize - SHARED_EDGE)) {
617 623
618 _heightBounds.minimum.x -= _heightIncrement * HEIGHT_BORDER;624 _heightBounds.minimum.x -= _heightIncrement * HEIGHT_BORDER;
619 _heightBounds.minimum.z -= _heightIncrement * HEIGHT_BORDER;625 _heightBounds.minimum.z -= _heightIncrement * HEIGHT_BORDER;
@@ -622,16 +628,20 @@ HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale, · 2 unmodified lines
622 628
623 _colorBounds.maximum.x += _colorIncrement * SHARED_EDGE;629 _colorBounds.maximum.x += _colorIncrement * SHARED_EDGE;
624 _colorBounds.maximum.z += _colorIncrement * SHARED_EDGE;630 _colorBounds.maximum.z += _colorIncrement * SHARED_EDGE;
631
632 _textureBounds.maximum.x += _textureIncrement * SHARED_EDGE;
633 _textureBounds.maximum.z += _textureIncrement * SHARED_EDGE;
625}634}
626 635
627HeightfieldBuffer::~HeightfieldBuffer() {636HeightfieldBuffer::~HeightfieldBuffer() {
628 // the textures have to be deleted on the main thread (for its opengl context)637 // the textures have to be deleted on the main thread (for its opengl context)
629 if (QThread::currentThread() != Application::getInstance()->thread()) {638 if (QThread::currentThread() != Application::getInstance()->thread()) {
630 QMetaObject::invokeMethod(Application::getInstance()->getMetavoxels(), "deleteTextures",639 QMetaObject::invokeMethod(Application::getInstance()->getMetavoxels(), "deleteTextures",
631 Q_ARG(int, _heightTextureID), Q_ARG(int, _colorTextureID));640 Q_ARG(int, _heightTextureID), Q_ARG(int, _colorTextureID), Q_ARG(int, _textureTextureID));
632 } else {641 } else {
633 glDeleteTextures(1, &_heightTextureID);642 glDeleteTextures(1, &_heightTextureID);
634 glDeleteTextures(1, &_colorTextureID);643 glDeleteTextures(1, &_colorTextureID);
644 glDeleteTextures(1, &_textureTextureID);
635 }645 }
636}646}
637 647
@@ -692,6 +702,17 @@ void HeightfieldBuffer::render(bool cursor) { · 54 unmodified lines
692 int colorSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES); 702 int colorSize = glm::sqrt(_color.size() / HeightfieldData::COLOR_BYTES);
693 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());703 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());
694 }704 }
705
706 if (!_texture.isEmpty()) {
707 glGenTextures(1, &_textureTextureID);
708 glBindTexture(GL_TEXTURE_2D, _textureTextureID);
709 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
710 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
711 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
712 int textureSize = glm::sqrt(_texture.size());
713 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, textureSize, textureSize, 0,
714 GL_LUMINANCE, GL_UNSIGNED_BYTE, _texture.constData());
715 }
695 }716 }
696 // create the buffer objects lazily717 // create the buffer objects lazily
697 int innerSize = _heightSize - 2 * HeightfieldBuffer::HEIGHT_BORDER;718 int innerSize = _heightSize - 2 * HeightfieldBuffer::HEIGHT_BORDER;
@@ -998,7 +1019,8 @@ private: · 300 unmodified lines
998 1019
999HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) :1020HeightfieldFetchVisitor::HeightfieldFetchVisitor(const MetavoxelLOD& lod, const QVector<Box>& intersections) :
1000 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<1021 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
1001 AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>(), lod),1022 AttributeRegistry::getInstance()->getHeightfieldColorAttribute() <<
1023 AttributeRegistry::getInstance()->getHeightfieldTextureAttribute(), QVector<AttributePointer>(), lod),
1002 _intersections(intersections) {1024 _intersections(intersections) {
1003}1025}
1004 1026
@@ -1065,11 +1087,11 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) { · 60 unmodified lines
1065 1087
1066 int colorSize = _buffer->getColorSize();1088 int colorSize = _buffer->getColorSize();
1067 if (colorSize == 0) {1089 if (colorSize == 0) {
1068 return STOP_RECURSION;1090 continue;
1069 }1091 }
1070 HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();1092 HeightfieldColorDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
1071 if (!color) {1093 if (!color) {
1072 return STOP_RECURSION;1094 continue;
1073 }1095 }
1074 const Box& colorBounds = _buffer->getColorBounds();1096 const Box& colorBounds = _buffer->getColorBounds();
1075 overlap = colorBounds.getIntersection(overlap);1097 overlap = colorBounds.getIntersection(overlap);
@@ -1113,6 +1135,50 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) { · 37 unmodified lines
1113 }1135 }
1114 }1136 }
1115 }1137 }
1138
1139 int textureSize = _buffer->getTextureSize();
1140 if (textureSize == 0) {
1141 continue;
1142 }
1143 HeightfieldTextureDataPointer texture = info.inputValues.at(2).getInlineValue<HeightfieldTextureDataPointer>();
1144 if (!texture) {
1145 continue;
1146 }
1147 const Box& textureBounds = _buffer->getTextureBounds();
1148 overlap = textureBounds.getIntersection(overlap);
1149 float textureIncrement = _buffer->getTextureIncrement();
1150 destX = (overlap.minimum.x - textureBounds.minimum.x) / textureIncrement;
1151 destY = (overlap.minimum.z - textureBounds.minimum.z) / textureIncrement;
1152 destWidth = glm::ceil((overlap.maximum.x - overlap.minimum.x) / textureIncrement);
1153 destHeight = glm::ceil((overlap.maximum.z - overlap.minimum.z) / textureIncrement);
1154 dest = _buffer->getTexture().data() + destY * textureSize + destX;
1155
1156 const QByteArray& srcTexture = texture->getContents();
1157 srcSize = glm::sqrt(srcTexture.size());
1158 srcIncrement = info.size / srcSize;
1159
1160 if (srcIncrement == textureIncrement) {
1161 // easy case: same resolution
1162 int srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1163 int srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1164
1165 const char* src = srcTexture.constData() + srcY * srcSize + srcX;
1166 for (int y = 0; y < destHeight; y++, src += srcSize, dest += textureSize) {
1167 memcpy(dest, src, destWidth);
1168 }
1169 } else {
1170 // more difficult: different resolutions
1171 float srcX = (overlap.minimum.x - info.minimum.x) / srcIncrement;
1172 float srcY = (overlap.minimum.z - info.minimum.z) / srcIncrement;
1173 float srcAdvance = textureIncrement / srcIncrement;
1174 for (int y = 0; y < destHeight; y++, dest += textureSize, srcY += srcAdvance) {
1175 const char* src = srcTexture.constData() + (int)srcY * srcSize;
1176 float lineSrcX = srcX;
1177 for (char* lineDest = dest, *end = dest + destWidth; lineDest != end; lineDest++, lineSrcX += srcAdvance) {
1178 *lineDest = src[(int)lineSrcX];
1179 }
1180 }
1181 }
1116 }1182 }
1117 return STOP_RECURSION;1183 return STOP_RECURSION;
1118}1184}
@@ -1138,6 +1204,7 @@ private: · 19 unmodified lines
1138HeightfieldRegionVisitor::HeightfieldRegionVisitor(const MetavoxelLOD& lod) :1204HeightfieldRegionVisitor::HeightfieldRegionVisitor(const MetavoxelLOD& lod) :
1139 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<1205 MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
1140 AttributeRegistry::getInstance()->getHeightfieldColorAttribute() <<1206 AttributeRegistry::getInstance()->getHeightfieldColorAttribute() <<
1207 AttributeRegistry::getInstance()->getHeightfieldTextureAttribute() <<
1141 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() <<1208 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>() <<
1142 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod),1209 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod),
1143 regionBounds(glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX), glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)),1210 regionBounds(glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX), glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)),
@@ -1165,18 +1232,28 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) { · 21 unmodified lines
1165 colorContentsSize = extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES;1232 colorContentsSize = extendedColorSize * extendedColorSize * HeightfieldData::COLOR_BYTES;
1166 }1233 }
1167 1234
1235 HeightfieldTextureDataPointer texture = info.inputValues.at(2).getInlineValue<HeightfieldTextureDataPointer>();
1236 int textureContentsSize = 0;
1237 if (texture) {
1238 const QByteArray& textureContents = texture->getContents();
1239 int textureSize = glm::sqrt(textureContents.size());
1240 int extendedTextureSize = textureSize + HeightfieldBuffer::SHARED_EDGE;
1241 textureContentsSize = extendedTextureSize * extendedTextureSize;
1242 }
1243
1168 const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>(1244 const HeightfieldBuffer* existingBuffer = static_cast<const HeightfieldBuffer*>(
1169 info.inputValues.at(2).getInlineValue<BufferDataPointer>().data());1245 info.inputValues.at(3).getInlineValue<BufferDataPointer>().data());
1170 Box bounds = info.getBounds();1246 Box bounds = info.getBounds();
1171 if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize &&1247 if (existingBuffer && existingBuffer->getHeight().size() == heightContentsSize &&
1172 existingBuffer->getColor().size() == colorContentsSize) {1248 existingBuffer->getColor().size() == colorContentsSize &&
1249 existingBuffer->getTexture().size() == textureContentsSize) {
1173 // we already have a buffer of the correct resolution 1250 // we already have a buffer of the correct resolution
1174 addRegion(bounds, existingBuffer->getHeightBounds());1251 addRegion(bounds, existingBuffer->getHeightBounds());
1175 return STOP_RECURSION;1252 return STOP_RECURSION;
1176 }1253 }
1177 // we must create a new buffer and update its borders1254 // we must create a new buffer and update its borders
1178 buffer = new HeightfieldBuffer(info.minimum, info.size, QByteArray(heightContentsSize, 0),1255 buffer = new HeightfieldBuffer(info.minimum, info.size, QByteArray(heightContentsSize, 0),
1179 QByteArray(colorContentsSize, 0));1256 QByteArray(colorContentsSize, 0), QByteArray(textureContentsSize, 0));
1180 const Box& heightBounds = buffer->getHeightBounds();1257 const Box& heightBounds = buffer->getHeightBounds();
1181 addRegion(bounds, heightBounds);1258 addRegion(bounds, heightBounds);
1182 1259
@@ -1249,7 +1326,7 @@ int HeightfieldUpdateVisitor::visit(MetavoxelInfo& info) { · 66 unmodified lines
1249 return STOP_RECURSION;1326 return STOP_RECURSION;
1250 }1327 }
1251 HeightfieldBuffer* newBuffer = new HeightfieldBuffer(info.minimum, info.size,1328 HeightfieldBuffer* newBuffer = new HeightfieldBuffer(info.minimum, info.size,
1252 buffer->getHeight(), buffer->getColor());1329 buffer->getHeight(), buffer->getColor(), buffer->getTexture());
1253 _fetchVisitor.init(newBuffer);1330 _fetchVisitor.init(newBuffer);
1254 _data->guide(_fetchVisitor);1331 _data->guide(_fetchVisitor);
1255 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(newBuffer)));1332 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(newBuffer)));