History

Rejiggering the heightfield renderer for LOD.

Andrzej Kapolka committed 11 years ago

Commit 790b0851 parent 1d9c7d74 files · +174 −124Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+126−111
@@ -2073,57 +2073,67 @@ void StaticModelRenderer::applyURL(const QUrl& url) { · 2072 unmodified lines
20732073 }
20742074
20752075 HeightfieldRenderer::HeightfieldRenderer() {
2076− glGenTextures(1, &_heightTextureID);
2077− glBindTexture(GL_TEXTURE_2D, _heightTextureID);
2078− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2079− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2080− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2081− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2082−
2083− glGenTextures(1, &_colorTextureID);
2084− glBindTexture(GL_TEXTURE_2D, _colorTextureID);
2085− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2086− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2087− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2088−
2089− glGenTextures(1, &_materialTextureID);
2090− glBindTexture(GL_TEXTURE_2D, _materialTextureID);
2091− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2092− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2093− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2094− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2095−
2096− glBindTexture(GL_TEXTURE_2D, 0);
2097−}
2098−
2099−HeightfieldRenderer::~HeightfieldRenderer() {
2100− glDeleteTextures(1, &_heightTextureID);
2101− glDeleteTextures(1, &_colorTextureID);
2102− glDeleteTextures(1, &_materialTextureID);
21032076 }
21042077
21052078 void HeightfieldRenderer::init(Spanner* spanner) {
21062079 SpannerRenderer::init(spanner);
21072080
21082081 Heightfield* heightfield = static_cast<Heightfield*>(spanner);
2109− applyHeight(heightfield->getHeight());
2110− applyColor(heightfield->getColor());
2111− applyMaterial(heightfield->getMaterial());
2112−
2113− connect(heightfield, &Heightfield::heightChanged, this, &HeightfieldRenderer::applyHeight);
2114− connect(heightfield, &Heightfield::colorChanged, this, &HeightfieldRenderer::applyColor);
2115− connect(heightfield, &Heightfield::materialChanged, this, &HeightfieldRenderer::applyMaterial);
2082+ connect(heightfield, &Heightfield::rootChanged, this, &HeightfieldRenderer::updateRoot);
2083+ updateRoot();
21162084 }
21172085
21182086 void HeightfieldRenderer::render(bool cursor) {
2119− // create the buffer objects lazily
21202087 Heightfield* heightfield = static_cast<Heightfield*>(_spanner);
2121− if (!heightfield->getHeight()) {
2088+ _root->render(heightfield->getTranslation(), heightfield->getRotation(), glm::vec3(heightfield->getScale(),
2089+ heightfield->getScale() * heightfield->getAspectY(), heightfield->getScale() * heightfield->getAspectZ()), cursor);
2090+}
2091+
2092+void HeightfieldRenderer::updateRoot() {
2093+ Heightfield* heightfield = static_cast<Heightfield*>(_spanner);
2094+ _root = new HeightfieldRendererNode(heightfield->getRoot());
2095+}
2096+
2097+HeightfieldRendererNode::HeightfieldRendererNode(const HeightfieldNodePointer& heightfieldNode) :
2098+ _heightfieldNode(heightfieldNode),
2099+ _heightTextureID(0),
2100+ _colorTextureID(0),
2101+ _materialTextureID(0) {
2102+
2103+ for (int i = 0; i < CHILD_COUNT; i++) {
2104+ HeightfieldNodePointer child = heightfieldNode->getChild(i);
2105+ if (child) {
2106+ _children[i] = new HeightfieldRendererNode(child);
2107+ }
2108+ }
2109+}
2110+
2111+HeightfieldRendererNode::~HeightfieldRendererNode() {
2112+ glDeleteTextures(1, &_heightTextureID);
2113+ glDeleteTextures(1, &_colorTextureID);
2114+ glDeleteTextures(1, &_materialTextureID);
2115+}
2116+
2117+const int X_MAXIMUM_FLAG = 1;
2118+const int Y_MAXIMUM_FLAG = 2;
2119+
2120+void HeightfieldRendererNode::render(const glm::vec3& translation, const glm::quat& rotation,
2121+ const glm::vec3& scale, bool cursor) {
2122+ if (!isLeaf()) {
2123+ glm::vec3 nextScale(scale.x * 0.5f, scale.y, scale.z * 0.5f);
2124+ glm::vec3 xOffset = rotation * glm::vec3(nextScale.x, 0.0f, 0.0f);
2125+ glm::vec3 zOffset = rotation * glm::vec3(0.0f, 0.0f, nextScale.z);
2126+ for (int i = 0; i < CHILD_COUNT; i++) {
2127+ _children[i]->render(translation + (i & X_MAXIMUM_FLAG ? xOffset : glm::vec3()) +
2128+ (i & Y_MAXIMUM_FLAG ? zOffset : glm::vec3()), rotation, nextScale, cursor);
2129+ }
21222130 return;
21232131 }
2124− int width = heightfield->getHeight()->getWidth();
2125− int height = heightfield->getHeight()->getContents().size() / width;
2126−
2132+ if (!_heightfieldNode->getHeight()) {
2133+ return;
2134+ }
2135+ int width = _heightfieldNode->getHeight()->getWidth();
2136+ int height = _heightfieldNode->getHeight()->getContents().size() / width;
21272137 int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER;
21282138 int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER;
21292139 int vertexCount = width * height;
@@ -2180,17 +2190,71 @@ void HeightfieldRenderer::render(bool cursor) { · 50 unmodified lines
21802190 bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int));
21812191 bufferPair.second.release();
21822192 }
2193+ if (_heightTextureID == 0) {
2194+ glGenTextures(1, &_heightTextureID);
2195+ glBindTexture(GL_TEXTURE_2D, _heightTextureID);
2196+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2197+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2198+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2199+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2200+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2201+ const QVector<quint16>& heightContents = _heightfieldNode->getHeight()->getContents();
2202+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, width, height, 0,
2203+ GL_RED, GL_UNSIGNED_SHORT, heightContents.constData());
2204+
2205+ glGenTextures(1, &_colorTextureID);
2206+ glBindTexture(GL_TEXTURE_2D, _colorTextureID);
2207+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2208+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2209+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2210+ if (_heightfieldNode->getColor()) {
2211+ const QByteArray& contents = _heightfieldNode->getColor()->getContents();
2212+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, _heightfieldNode->getColor()->getWidth(),
2213+ contents.size() / (_heightfieldNode->getColor()->getWidth() * DataBlock::COLOR_BYTES),
2214+ 0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData());
2215+
2216+ } else {
2217+ const quint8 WHITE_COLOR[] = { 255, 255, 255 };
2218+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
2219+ }
2220+
2221+ glGenTextures(1, &_materialTextureID);
2222+ glBindTexture(GL_TEXTURE_2D, _materialTextureID);
2223+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2224+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2225+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2226+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2227+ if (_heightfieldNode->getMaterial()) {
2228+ const QByteArray& contents = _heightfieldNode->getMaterial()->getContents();
2229+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, _heightfieldNode->getMaterial()->getWidth(),
2230+ contents.size() / _heightfieldNode->getMaterial()->getWidth(),
2231+ 0, GL_RED, GL_UNSIGNED_BYTE, contents.constData());
2232+
2233+ const QVector<SharedObjectPointer>& materials = _heightfieldNode->getMaterial()->getMaterials();
2234+ _networkTextures.resize(materials.size());
2235+ for (int i = 0; i < materials.size(); i++) {
2236+ const SharedObjectPointer& material = materials.at(i);
2237+ if (material) {
2238+ _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture(
2239+ static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE);
2240+ }
2241+ }
2242+ } else {
2243+ const quint8 ZERO_VALUE = 0;
2244+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE);
2245+ }
2246+ glBindTexture(GL_TEXTURE_2D, 0);
2247+ }
21832248
2184− float xScale = heightfield->getScale(), zScale = xScale * heightfield->getAspectZ();
21852249 if (cursor) {
21862250 bufferPair.first.bind();
21872251 bufferPair.second.bind();
21882252
21892253 glPushMatrix();
2190− glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z);
2191− glm::vec3 axis = glm::axis(heightfield->getRotation());
2192− glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z);
2193− glScalef(xScale, xScale * heightfield->getAspectY(), zScale);
2254+ glTranslatef(translation.x, translation.y, translation.z);
2255+ glm::vec3 axis = glm::axis(rotation);
2256+ glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
2257+ glScalef(scale.x, scale.y, scale.z);
21942258
21952259 HeightfieldPoint* point = 0;
21962260 glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex);
@@ -2208,13 +2272,12 @@ void HeightfieldRenderer::render(bool cursor) { · 11 unmodified lines
22082272 bufferPair.second.release();
22092273 return;
22102274 }
2211−
22122275 HeightfieldBaseLayerBatch baseBatch;
22132276 baseBatch.vertexBuffer = &bufferPair.first;
22142277 baseBatch.indexBuffer = &bufferPair.second;
2215− baseBatch.translation = heightfield->getTranslation();
2216− baseBatch.rotation = heightfield->getRotation();
2217− baseBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale);
2278+ baseBatch.translation = translation;
2279+ baseBatch.rotation = rotation;
2280+ baseBatch.scale = scale;
22182281 baseBatch.vertexCount = vertexCount;
22192282 baseBatch.indexCount = indexCount;
22202283 baseBatch.heightTextureID = _heightTextureID;
@@ -2223,13 +2286,13 @@ void HeightfieldRenderer::render(bool cursor) { · 2 unmodified lines
22232286 baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);
22242287 Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch);
22252288
2226− if (heightfield->getMaterial() && !_networkTextures.isEmpty()) {
2289+ if (!_networkTextures.isEmpty()) {
22272290 HeightfieldSplatBatch splatBatch;
22282291 splatBatch.vertexBuffer = &bufferPair.first;
22292292 splatBatch.indexBuffer = &bufferPair.second;
2230− splatBatch.translation = heightfield->getTranslation();
2231− splatBatch.rotation = heightfield->getRotation();
2232− splatBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale);
2293+ splatBatch.translation = translation;
2294+ splatBatch.rotation = rotation;
2295+ splatBatch.scale = scale;
22332296 splatBatch.vertexCount = vertexCount;
22342297 splatBatch.indexCount = indexCount;
22352298 splatBatch.heightTextureID = _heightTextureID;
@@ -2237,10 +2300,10 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line
22372300 splatBatch.materialTextureID = _materialTextureID;
22382301 splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);
22392302 splatBatch.splatTextureOffset = glm::vec2(
2240− glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale,
2241− glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale);
2303+ glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x,
2304+ glm::dot(translation, rotation * glm::vec3(0.0f, 0.0f, 1.0f)) / scale.z);
22422305
2243− const QVector<SharedObjectPointer>& materials = heightfield->getMaterial()->getMaterials();
2306+ const QVector<SharedObjectPointer>& materials = _heightfieldNode->getMaterial()->getMaterials();
22442307 for (int i = 0; i < materials.size(); i += SPLAT_COUNT) {
22452308 for (int j = 0; j < SPLAT_COUNT; j++) {
22462309 int index = i + j;
@@ -2248,8 +2311,8 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line
22482311 const NetworkTexturePointer& texture = _networkTextures.at(index);
22492312 if (texture) {
22502313 MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data());
2251− splatBatch.splatTextureScalesS[j] = xScale / material->getScaleS();
2252− splatBatch.splatTextureScalesT[j] = zScale / material->getScaleT();
2314+ splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS();
2315+ splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT();
22532316 splatBatch.splatTextureIDs[j] = texture->getID();
22542317
22552318 } else {
@@ -2265,62 +2328,14 @@ void HeightfieldRenderer::render(bool cursor) { · 9 unmodified lines
22652328 }
22662329 }
22672330
2268−void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) {
2269− glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2270− glBindTexture(GL_TEXTURE_2D, _heightTextureID);
2271− if (height) {
2272− const QVector<quint16>& contents = height->getContents();
2273− glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, height->getWidth(), contents.size() / height->getWidth(), 0,
2274− GL_RED, GL_UNSIGNED_SHORT, contents.constData());
2275−
2276− } else {
2277− const quint16 ZERO_VALUE = 0;
2278− glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, 1, 1, 0, GL_RED, GL_UNSIGNED_SHORT, &ZERO_VALUE);
2279− }
2280− glBindTexture(GL_TEXTURE_2D, 0);
2281−}
2282−
2283−void HeightfieldRenderer::applyColor(const HeightfieldColorPointer& color) {
2284− glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2285− glBindTexture(GL_TEXTURE_2D, _colorTextureID);
2286− if (color) {
2287− const QByteArray& contents = color->getContents();
2288− glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, color->getWidth(),
2289− contents.size() / (color->getWidth() * DataBlock::COLOR_BYTES), 0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData());
2290−
2291− } else {
2292− const quint8 WHITE_COLOR[] = { 255, 255, 255 };
2293− glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
2294− }
2295− glBindTexture(GL_TEXTURE_2D, 0);
2296−}
2297−
2298−void HeightfieldRenderer::applyMaterial(const HeightfieldMaterialPointer& material) {
2299− glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2300− glBindTexture(GL_TEXTURE_2D, _materialTextureID);
2301− if (material) {
2302− const QByteArray& contents = material->getContents();
2303− glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, material->getWidth(), contents.size() / material->getWidth(), 0,
2304− GL_RED, GL_UNSIGNED_BYTE, contents.constData());
2305−
2306− const QVector<SharedObjectPointer>& materials = material->getMaterials();
2307− _networkTextures.resize(materials.size());
2308− for (int i = 0; i < materials.size(); i++) {
2309− const SharedObjectPointer& material = materials.at(i);
2310− if (material) {
2311− _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture(
2312− static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE);
2313− } else {
2314− _networkTextures[i].clear();
2315− }
2331+bool HeightfieldRendererNode::isLeaf() const {
2332+ for (int i = 0; i < CHILD_COUNT; i++) {
2333+ if (_children[i]) {
2334+ return false;
23162335 }
2317− } else {
2318− const quint8 ZERO_VALUE = 0;
2319− glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE);
2320− _networkTextures.clear();
23212336 }
2322− glBindTexture(GL_TEXTURE_2D, 0);
2337+ return true;
23232338 }
23242339
2325−QHash<HeightfieldRenderer::IntPair, HeightfieldRenderer::BufferPair> HeightfieldRenderer::_bufferPairs;
2340+QHash<HeightfieldRendererNode::IntPair, HeightfieldRendererNode::BufferPair> HeightfieldRendererNode::_bufferPairs;
23262341