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
2073}2073}
2074 2074
2075HeightfieldRenderer::HeightfieldRenderer() {2075HeightfieldRenderer::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
2099HeightfieldRenderer::~HeightfieldRenderer() {
2100 glDeleteTextures(1, &_heightTextureID);
2101 glDeleteTextures(1, &_colorTextureID);
2102 glDeleteTextures(1, &_materialTextureID);
2103}2076}
2104 2077
2105void HeightfieldRenderer::init(Spanner* spanner) {2078void HeightfieldRenderer::init(Spanner* spanner) {
2106 SpannerRenderer::init(spanner);2079 SpannerRenderer::init(spanner);
2107 2080
2108 Heightfield* heightfield = static_cast<Heightfield*>(spanner);2081 Heightfield* heightfield = static_cast<Heightfield*>(spanner);
2109 applyHeight(heightfield->getHeight());2082 connect(heightfield, &Heightfield::rootChanged, this, &HeightfieldRenderer::updateRoot);
2110 applyColor(heightfield->getColor());2083 updateRoot();
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);
2116}2084}
2117 2085
2118void HeightfieldRenderer::render(bool cursor) {2086void HeightfieldRenderer::render(bool cursor) {
2119 // create the buffer objects lazily
2120 Heightfield* heightfield = static_cast<Heightfield*>(_spanner);2087 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
2092void HeightfieldRenderer::updateRoot() {
2093 Heightfield* heightfield = static_cast<Heightfield*>(_spanner);
2094 _root = new HeightfieldRendererNode(heightfield->getRoot());
2095}
2096
2097HeightfieldRendererNode::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
2111HeightfieldRendererNode::~HeightfieldRendererNode() {
2112 glDeleteTextures(1, &_heightTextureID);
2113 glDeleteTextures(1, &_colorTextureID);
2114 glDeleteTextures(1, &_materialTextureID);
2115}
2116
2117const int X_MAXIMUM_FLAG = 1;
2118const int Y_MAXIMUM_FLAG = 2;
2119
2120void 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 }
2122 return;2130 return;
2123 }2131 }
2124 int width = heightfield->getHeight()->getWidth();2132 if (!_heightfieldNode->getHeight()) {
2125 int height = heightfield->getHeight()->getContents().size() / width;2133 return;
2126 2134 }
2135 int width = _heightfieldNode->getHeight()->getWidth();
2136 int height = _heightfieldNode->getHeight()->getContents().size() / width;
2127 int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER;2137 int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER;
2128 int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER;2138 int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER;
2129 int vertexCount = width * height;2139 int vertexCount = width * height;
@@ -2180,17 +2190,71 @@ void HeightfieldRenderer::render(bool cursor) { · 50 unmodified lines
2180 bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int));2190 bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int));
2181 bufferPair.second.release();2191 bufferPair.second.release();
2182 }2192 }
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 }
2183 2248
2184 float xScale = heightfield->getScale(), zScale = xScale * heightfield->getAspectZ();
2185 if (cursor) {2249 if (cursor) {
2186 bufferPair.first.bind();2250 bufferPair.first.bind();
2187 bufferPair.second.bind();2251 bufferPair.second.bind();
2188 2252
2189 glPushMatrix();2253 glPushMatrix();
2190 glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z);2254 glTranslatef(translation.x, translation.y, translation.z);
2191 glm::vec3 axis = glm::axis(heightfield->getRotation());2255 glm::vec3 axis = glm::axis(rotation);
2192 glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z);2256 glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
2193 glScalef(xScale, xScale * heightfield->getAspectY(), zScale);2257 glScalef(scale.x, scale.y, scale.z);
2194 2258
2195 HeightfieldPoint* point = 0;2259 HeightfieldPoint* point = 0;
2196 glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex);2260 glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex);
@@ -2208,13 +2272,12 @@ void HeightfieldRenderer::render(bool cursor) { · 11 unmodified lines
2208 bufferPair.second.release();2272 bufferPair.second.release();
2209 return;2273 return;
2210 }2274 }
2211
2212 HeightfieldBaseLayerBatch baseBatch;2275 HeightfieldBaseLayerBatch baseBatch;
2213 baseBatch.vertexBuffer = &bufferPair.first;2276 baseBatch.vertexBuffer = &bufferPair.first;
2214 baseBatch.indexBuffer = &bufferPair.second;2277 baseBatch.indexBuffer = &bufferPair.second;
2215 baseBatch.translation = heightfield->getTranslation();2278 baseBatch.translation = translation;
2216 baseBatch.rotation = heightfield->getRotation();2279 baseBatch.rotation = rotation;
2217 baseBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale);2280 baseBatch.scale = scale;
2218 baseBatch.vertexCount = vertexCount;2281 baseBatch.vertexCount = vertexCount;
2219 baseBatch.indexCount = indexCount;2282 baseBatch.indexCount = indexCount;
2220 baseBatch.heightTextureID = _heightTextureID;2283 baseBatch.heightTextureID = _heightTextureID;
@@ -2223,13 +2286,13 @@ void HeightfieldRenderer::render(bool cursor) { · 2 unmodified lines
2223 baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);2286 baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);
2224 Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); 2287 Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch);
2225 2288
2226 if (heightfield->getMaterial() && !_networkTextures.isEmpty()) {2289 if (!_networkTextures.isEmpty()) {
2227 HeightfieldSplatBatch splatBatch;2290 HeightfieldSplatBatch splatBatch;
2228 splatBatch.vertexBuffer = &bufferPair.first;2291 splatBatch.vertexBuffer = &bufferPair.first;
2229 splatBatch.indexBuffer = &bufferPair.second;2292 splatBatch.indexBuffer = &bufferPair.second;
2230 splatBatch.translation = heightfield->getTranslation();2293 splatBatch.translation = translation;
2231 splatBatch.rotation = heightfield->getRotation();2294 splatBatch.rotation = rotation;
2232 splatBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale);2295 splatBatch.scale = scale;
2233 splatBatch.vertexCount = vertexCount;2296 splatBatch.vertexCount = vertexCount;
2234 splatBatch.indexCount = indexCount;2297 splatBatch.indexCount = indexCount;
2235 splatBatch.heightTextureID = _heightTextureID;2298 splatBatch.heightTextureID = _heightTextureID;
@@ -2237,10 +2300,10 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line
2237 splatBatch.materialTextureID = _materialTextureID;2300 splatBatch.materialTextureID = _materialTextureID;
2238 splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);2301 splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);
2239 splatBatch.splatTextureOffset = glm::vec2(2302 splatBatch.splatTextureOffset = glm::vec2(
2240 glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale,2303 glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x,
2241 glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale);2304 glm::dot(translation, rotation * glm::vec3(0.0f, 0.0f, 1.0f)) / scale.z);
2242 2305
2243 const QVector<SharedObjectPointer>& materials = heightfield->getMaterial()->getMaterials();2306 const QVector<SharedObjectPointer>& materials = _heightfieldNode->getMaterial()->getMaterials();
2244 for (int i = 0; i < materials.size(); i += SPLAT_COUNT) {2307 for (int i = 0; i < materials.size(); i += SPLAT_COUNT) {
2245 for (int j = 0; j < SPLAT_COUNT; j++) {2308 for (int j = 0; j < SPLAT_COUNT; j++) {
2246 int index = i + j;2309 int index = i + j;
@@ -2248,8 +2311,8 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line
2248 const NetworkTexturePointer& texture = _networkTextures.at(index);2311 const NetworkTexturePointer& texture = _networkTextures.at(index);
2249 if (texture) {2312 if (texture) {
2250 MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data());2313 MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data());
2251 splatBatch.splatTextureScalesS[j] = xScale / material->getScaleS();2314 splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS();
2252 splatBatch.splatTextureScalesT[j] = zScale / material->getScaleT();2315 splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT();
2253 splatBatch.splatTextureIDs[j] = texture->getID();2316 splatBatch.splatTextureIDs[j] = texture->getID();
2254 2317
2255 } else {2318 } else {
@@ -2265,62 +2328,14 @@ void HeightfieldRenderer::render(bool cursor) { · 9 unmodified lines
2265 }2328 }
2266}2329}
2267 2330
2268void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) {2331bool HeightfieldRendererNode::isLeaf() const {
2269 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);2332 for (int i = 0; i < CHILD_COUNT; i++) {
2270 glBindTexture(GL_TEXTURE_2D, _heightTextureID);2333 if (_children[i]) {
2271 if (height) {2334 return false;
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
2283void 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
2298void 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 }
2316 }2335 }
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();
2321 }2336 }
2322 glBindTexture(GL_TEXTURE_2D, 0);2337 return true;
2323}2338}
2324 2339
2325QHash<HeightfieldRenderer::IntPair, HeightfieldRenderer::BufferPair> HeightfieldRenderer::_bufferPairs;2340QHash<HeightfieldRendererNode::IntPair, HeightfieldRendererNode::BufferPair> HeightfieldRendererNode::_bufferPairs;
2326 2341