Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 4 files). Show all
Unified · Split
| @@ -140,6 +140,18 @@ int RenderVisitor::visit(MetavoxelInfo& info) { · 139 unmodified lines | |||
| 140 | return STOP_RECURSION; | 140 | return STOP_RECURSION; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | class HeightfieldPoint { | ||
| 144 | public: | ||
| 145 | glm::vec3 vertex; | ||
| 146 | glm::vec2 textureCoord; | ||
| 147 | }; | ||
| 148 | |||
| 149 | const int SPLAT_COUNT = 4; | ||
| 150 | const GLint SPLAT_TEXTURE_UNITS[] = { 3, 4, 5, 6 }; | ||
| 151 | |||
| 152 | static const int EIGHT_BIT_MAXIMUM = 255; | ||
| 153 | static const float EIGHT_BIT_MAXIMUM_RECIPROCAL = 1.0f / EIGHT_BIT_MAXIMUM; | ||
| 154 | |||
| 143 | void MetavoxelSystem::render() { | 155 | void MetavoxelSystem::render() { |
| 144 | // update the frustum | 156 | // update the frustum |
| 145 | ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum(); | 157 | ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum(); |
| @@ -150,6 +162,154 @@ void MetavoxelSystem::render() { · 4 unmodified lines | |||
| 150 | RenderVisitor renderVisitor(getLOD()); | 162 | RenderVisitor renderVisitor(getLOD()); |
| 151 | guideToAugmented(renderVisitor, true); | 163 | guideToAugmented(renderVisitor, true); |
| 152 | 164 | ||
| 165 | if (!_heightfieldBaseBatches.isEmpty()) { | ||
| 166 | glEnableClientState(GL_VERTEX_ARRAY); | ||
| 167 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 168 | |||
| 169 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); | ||
| 170 | |||
| 171 | glDisable(GL_BLEND); | ||
| 172 | glEnable(GL_CULL_FACE); | ||
| 173 | glEnable(GL_ALPHA_TEST); | ||
| 174 | glAlphaFunc(GL_EQUAL, 0.0f); | ||
| 175 | |||
| 176 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | ||
| 177 | |||
| 178 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind(); | ||
| 179 | |||
| 180 | foreach (const HeightfieldBaseBatch& batch, _heightfieldBaseBatches) { | ||
| 181 | glPushMatrix(); | ||
| 182 | glTranslatef(batch.translation.x, batch.translation.y, batch.translation.z); | ||
| 183 | glm::vec3 axis = glm::axis(batch.rotation); | ||
| 184 | glRotatef(glm::degrees(glm::angle(batch.rotation)), axis.x, axis.y, axis.z); | ||
| 185 | glScalef(batch.scale.x, batch.scale.y, batch.scale.z); | ||
| 186 | |||
| 187 | batch.vertexBuffer->bind(); | ||
| 188 | batch.indexBuffer->bind(); | ||
| 189 | |||
| 190 | HeightfieldPoint* point = 0; | ||
| 191 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | ||
| 192 | glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); | ||
| 193 | |||
| 194 | glBindTexture(GL_TEXTURE_2D, batch.heightTextureID); | ||
| 195 | |||
| 196 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniform( | ||
| 197 | DefaultMetavoxelRendererImplementation::getBaseHeightScaleLocation(), batch.heightScale); | ||
| 198 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniform( | ||
| 199 | DefaultMetavoxelRendererImplementation::getBaseColorScaleLocation(), batch.colorScale); | ||
| 200 | |||
| 201 | glActiveTexture(GL_TEXTURE1); | ||
| 202 | glBindTexture(GL_TEXTURE_2D, batch.colorTextureID); | ||
| 203 | |||
| 204 | glDrawRangeElements(GL_TRIANGLES, 0, batch.vertexCount - 1, batch.indexCount, GL_UNSIGNED_INT, 0); | ||
| 205 | |||
| 206 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 207 | |||
| 208 | glActiveTexture(GL_TEXTURE0); | ||
| 209 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 210 | |||
| 211 | glPopMatrix(); | ||
| 212 | } | ||
| 213 | |||
| 214 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); | ||
| 215 | |||
| 216 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().release(); | ||
| 217 | |||
| 218 | glDisable(GL_ALPHA_TEST); | ||
| 219 | glEnable(GL_BLEND); | ||
| 220 | |||
| 221 | if (!_heightfieldSplatBatches.isEmpty()) { | ||
| 222 | glDepthFunc(GL_LEQUAL); | ||
| 223 | glDepthMask(false); | ||
| 224 | glEnable(GL_POLYGON_OFFSET_FILL); | ||
| 225 | glPolygonOffset(-1.0f, -1.0f); | ||
| 226 | |||
| 227 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().bind(); | ||
| 228 | const DefaultMetavoxelRendererImplementation::SplatLocations& locations = | ||
| 229 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldLocations(); | ||
| 230 | |||
| 231 | foreach (const HeightfieldSplatBatch& batch, _heightfieldSplatBatches) { | ||
| 232 | glPushMatrix(); | ||
| 233 | glTranslatef(batch.translation.x, batch.translation.y, batch.translation.z); | ||
| 234 | glm::vec3 axis = glm::axis(batch.rotation); | ||
| 235 | glRotatef(glm::degrees(glm::angle(batch.rotation)), axis.x, axis.y, axis.z); | ||
| 236 | glScalef(batch.scale.x, batch.scale.y, batch.scale.z); | ||
| 237 | |||
| 238 | batch.vertexBuffer->bind(); | ||
| 239 | batch.indexBuffer->bind(); | ||
| 240 | |||
| 241 | HeightfieldPoint* point = 0; | ||
| 242 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | ||
| 243 | glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); | ||
| 244 | |||
| 245 | glBindTexture(GL_TEXTURE_2D, batch.heightTextureID); | ||
| 246 | |||
| 247 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 248 | locations.heightScale, batch.heightScale.x, batch.heightScale.y); | ||
| 249 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniform( | ||
| 250 | locations.textureScale, batch.textureScale); | ||
| 251 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniform(locations.splatTextureOffset, | ||
| 252 | batch.splatTextureOffset); | ||
| 253 | |||
| 254 | const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL; | ||
| 255 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniform( | ||
| 256 | locations.splatTextureScalesS, batch.splatTextureScalesS); | ||
| 257 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniform( | ||
| 258 | locations.splatTextureScalesT, batch.splatTextureScalesT); | ||
| 259 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 260 | locations.textureValueMinima, | ||
| 261 | (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, | ||
| 262 | (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, | ||
| 263 | (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, | ||
| 264 | (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP); | ||
| 265 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 266 | locations.textureValueMaxima, | ||
| 267 | (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, | ||
| 268 | (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, | ||
| 269 | (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, | ||
| 270 | (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP); | ||
| 271 | |||
| 272 | glActiveTexture(GL_TEXTURE1); | ||
| 273 | glBindTexture(GL_TEXTURE_2D, batch.materialTextureID); | ||
| 274 | |||
| 275 | for (int i = 0; i < SPLAT_COUNT; i++) { | ||
| 276 | glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]); | ||
| 277 | glBindTexture(GL_TEXTURE_2D, batch.splatTextureIDs[i]); | ||
| 278 | } | ||
| 279 | |||
| 280 | glDrawRangeElements(GL_TRIANGLES, 0, batch.vertexCount - 1, batch.indexCount, GL_UNSIGNED_INT, 0); | ||
| 281 | |||
| 282 | for (int i = 0; i < SPLAT_COUNT; i++) { | ||
| 283 | glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]); | ||
| 284 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 285 | } | ||
| 286 | |||
| 287 | glActiveTexture(GL_TEXTURE1); | ||
| 288 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 289 | |||
| 290 | glActiveTexture(GL_TEXTURE0); | ||
| 291 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 292 | |||
| 293 | glPopMatrix(); | ||
| 294 | } | ||
| 295 | |||
| 296 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().release(); | ||
| 297 | |||
| 298 | glDisable(GL_POLYGON_OFFSET_FILL); | ||
| 299 | glDepthMask(true); | ||
| 300 | glDepthFunc(GL_LESS); | ||
| 301 | |||
| 302 | _heightfieldSplatBatches.clear(); | ||
| 303 | } | ||
| 304 | |||
| 305 | glDisable(GL_CULL_FACE); | ||
| 306 | |||
| 307 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 308 | glDisableClientState(GL_VERTEX_ARRAY); | ||
| 309 | |||
| 310 | _heightfieldBaseBatches.clear(); | ||
| 311 | } | ||
| 312 | |||
| 153 | // give external parties a chance to join in | 313 | // give external parties a chance to join in |
| 154 | emit rendering(); | 314 | emit rendering(); |
| 155 | } | 315 | } |
| @@ -670,12 +830,6 @@ void MetavoxelSystemClient::sendDatagram(const QByteArray& data) { · 514 unmodified lines | |||
| 670 | BufferData::~BufferData() { | 830 | BufferData::~BufferData() { |
| 671 | } | 831 | } |
| 672 | 832 | ||
| 673 | const int SPLAT_COUNT = 4; | ||
| 674 | const GLint SPLAT_TEXTURE_UNITS[] = { 3, 4, 5, 6 }; | ||
| 675 | |||
| 676 | static const int EIGHT_BIT_MAXIMUM = 255; | ||
| 677 | static const float EIGHT_BIT_MAXIMUM_RECIPROCAL = 1.0f / EIGHT_BIT_MAXIMUM; | ||
| 678 | |||
| 679 | void VoxelPoint::setNormal(const glm::vec3& normal) { | 833 | void VoxelPoint::setNormal(const glm::vec3& normal) { |
| 680 | this->normal[0] = (char)(normal.x * 127.0f); | 834 | this->normal[0] = (char)(normal.x * 127.0f); |
| 681 | this->normal[1] = (char)(normal.y * 127.0f); | 835 | this->normal[1] = (char)(normal.y * 127.0f); |
| @@ -1937,12 +2091,6 @@ void HeightfieldRenderer::init(Spanner* spanner) { · 1255 unmodified lines | |||
| 1937 | connect(heightfield, &Heightfield::materialChanged, this, &HeightfieldRenderer::applyMaterial); | 2091 | connect(heightfield, &Heightfield::materialChanged, this, &HeightfieldRenderer::applyMaterial); |
| 1938 | } | 2092 | } |
| 1939 | 2093 | ||
| 1940 | class HeightfieldPoint { | ||
| 1941 | public: | ||
| 1942 | glm::vec3 vertex; | ||
| 1943 | glm::vec2 textureCoord; | ||
| 1944 | }; | ||
| 1945 | |||
| 1946 | void HeightfieldRenderer::render(bool cursor) { | 2094 | void HeightfieldRenderer::render(bool cursor) { |
| 1947 | // create the buffer objects lazily | 2095 | // create the buffer objects lazily |
| 1948 | Heightfield* heightfield = static_cast<Heightfield*>(_spanner); | 2096 | Heightfield* heightfield = static_cast<Heightfield*>(_spanner); |
| @@ -1984,6 +2132,7 @@ void HeightfieldRenderer::render(bool cursor) { · 35 unmodified lines | |||
| 1984 | bufferPair.first.create(); | 2132 | bufferPair.first.create(); |
| 1985 | bufferPair.first.bind(); | 2133 | bufferPair.first.bind(); |
| 1986 | bufferPair.first.allocate(vertices.constData(), vertexCount * sizeof(HeightfieldPoint)); | 2134 | bufferPair.first.allocate(vertices.constData(), vertexCount * sizeof(HeightfieldPoint)); |
| 2135 | bufferPair.first.release(); | ||
| 1987 | 2136 | ||
| 1988 | QVector<int> indices(indexCount); | 2137 | QVector<int> indices(indexCount); |
| 1989 | int* index = indices.data(); | 2138 | int* index = indices.data(); |
| @@ -2005,150 +2154,91 @@ void HeightfieldRenderer::render(bool cursor) { · 15 unmodified lines | |||
| 2005 | bufferPair.second.create(); | 2154 | bufferPair.second.create(); |
| 2006 | bufferPair.second.bind(); | 2155 | bufferPair.second.bind(); |
| 2007 | bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); | 2156 | bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); |
| 2008 | 2157 | bufferPair.second.release(); | |
| 2009 | } else { | ||
| 2010 | bufferPair.first.bind(); | ||
| 2011 | bufferPair.second.bind(); | ||
| 2012 | } | 2158 | } |
| 2013 | glPushMatrix(); | ||
| 2014 | glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z); | ||
| 2015 | glm::vec3 axis = glm::axis(heightfield->getRotation()); | ||
| 2016 | glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z); | ||
| 2017 | float xScale = heightfield->getScale(), zScale = xScale * heightfield->getAspectZ(); | ||
| 2018 | glScalef(xScale, xScale * heightfield->getAspectY(), zScale); | ||
| 2019 | |||
| 2020 | HeightfieldPoint* point = 0; | ||
| 2021 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | ||
| 2022 | glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); | ||
| 2023 | |||
| 2024 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); | ||
| 2025 | 2159 | ||
| 2160 | float xScale = heightfield->getScale(), zScale = xScale * heightfield->getAspectZ(); | ||
| 2026 | if (cursor) { | 2161 | if (cursor) { |
| 2027 | glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); | 2162 | bufferPair.first.bind(); |
| 2028 | 2163 | bufferPair.second.bind(); | |
| 2029 | } else { | ||
| 2030 | glEnableClientState(GL_VERTEX_ARRAY); | ||
| 2031 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 2032 | |||
| 2033 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); | ||
| 2034 | 2164 | ||
| 2035 | glDisable(GL_BLEND); | 2165 | glPushMatrix(); |
| 2036 | glEnable(GL_CULL_FACE); | 2166 | glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z); |
| 2037 | glEnable(GL_ALPHA_TEST); | 2167 | glm::vec3 axis = glm::axis(heightfield->getRotation()); |
| 2038 | glAlphaFunc(GL_EQUAL, 0.0f); | 2168 | glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z); |
| 2169 | glScalef(xScale, xScale * heightfield->getAspectY(), zScale); | ||
| 2039 | 2170 | ||
| 2040 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 2171 | HeightfieldPoint* point = 0; |
| 2172 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | ||
| 2173 | glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); | ||
| 2041 | 2174 | ||
| 2042 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind(); | 2175 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); |
| 2043 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue( | ||
| 2044 | DefaultMetavoxelRendererImplementation::getBaseHeightScaleLocation(), 1.0f / width, 1.0f / height, | ||
| 2045 | (innerWidth - 1) / -2.0f, (innerHeight - 1) / -2.0f); | ||
| 2046 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue( | ||
| 2047 | DefaultMetavoxelRendererImplementation::getBaseColorScaleLocation(), (float)width / innerWidth, | ||
| 2048 | (float)height / innerHeight); | ||
| 2049 | |||
| 2050 | glActiveTexture(GL_TEXTURE1); | ||
| 2051 | glBindTexture(GL_TEXTURE_2D, _colorTextureID); | ||
| 2052 | 2176 | ||
| 2053 | glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); | 2177 | glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); |
| 2054 | 2178 | ||
| 2055 | glBindTexture(GL_TEXTURE_2D, 0); | 2179 | glBindTexture(GL_TEXTURE_2D, 0); |
| 2056 | |||
| 2057 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); | ||
| 2058 | |||
| 2059 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().release(); | ||
| 2060 | 2180 | ||
| 2061 | glDisable(GL_ALPHA_TEST); | 2181 | glPopMatrix(); |
| 2062 | glEnable(GL_BLEND); | ||
| 2063 | 2182 | ||
| 2064 | if (heightfield->getMaterial() && !_networkTextures.isEmpty()) { | 2183 | bufferPair.first.release(); |
| 2065 | glDepthFunc(GL_LEQUAL); | 2184 | bufferPair.second.release(); |
| 2066 | glDepthMask(false); | 2185 | return; |
| 2067 | glEnable(GL_POLYGON_OFFSET_FILL); | 2186 | } |
| 2068 | glPolygonOffset(-1.0f, -1.0f); | 2187 | |
| 2069 | 2188 | HeightfieldBaseBatch baseBatch; | |
| 2070 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().bind(); | 2189 | baseBatch.vertexBuffer = &bufferPair.first; |
| 2071 | const DefaultMetavoxelRendererImplementation::SplatLocations& locations = | 2190 | baseBatch.indexBuffer = &bufferPair.second; |
| 2072 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldLocations(); | 2191 | baseBatch.translation = heightfield->getTranslation(); |
| 2073 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | 2192 | baseBatch.rotation = heightfield->getRotation(); |
| 2074 | locations.heightScale, 1.0f / width, 1.0f / height); | 2193 | baseBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale); |
| 2075 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | 2194 | baseBatch.vertexCount = vertexCount; |
| 2076 | locations.textureScale, (float)width / innerWidth, (float)height / innerHeight); | 2195 | baseBatch.indexCount = indexCount; |
| 2077 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(locations.splatTextureOffset, | 2196 | baseBatch.heightTextureID = _heightTextureID; |
| 2078 | glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale, | 2197 | baseBatch.heightScale = glm::vec4(1.0f / width, 1.0f / height, (innerWidth - 1) / -2.0f, (innerHeight - 1) / -2.0f); |
| 2079 | glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale); | 2198 | baseBatch.colorTextureID = _colorTextureID; |
| 2080 | 2199 | baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); | |
| 2081 | glBindTexture(GL_TEXTURE_2D, _materialTextureID); | 2200 | Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); |
| 2201 | |||
| 2202 | if (heightfield->getMaterial() && !_networkTextures.isEmpty()) { | ||
| 2203 | HeightfieldSplatBatch splatBatch; | ||
| 2204 | splatBatch.vertexBuffer = &bufferPair.first; | ||
| 2205 | splatBatch.indexBuffer = &bufferPair.second; | ||
| 2206 | splatBatch.translation = heightfield->getTranslation(); | ||
| 2207 | splatBatch.rotation = heightfield->getRotation(); | ||
| 2208 | splatBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale); | ||
| 2209 | splatBatch.vertexCount = vertexCount; | ||
| 2210 | splatBatch.indexCount = indexCount; | ||
| 2211 | splatBatch.heightTextureID = _heightTextureID; | ||
| 2212 | splatBatch.heightScale = glm::vec4(1.0f / width, 1.0f / height, 0.0f, 0.0f); | ||
| 2213 | splatBatch.materialTextureID = _materialTextureID; | ||
| 2214 | splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); | ||
| 2215 | splatBatch.splatTextureOffset = glm::vec2( | ||
| 2216 | glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale, | ||
| 2217 | glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale); | ||
| 2082 | 2218 | ||
| 2083 | const QVector<SharedObjectPointer>& materials = heightfield->getMaterial()->getMaterials(); | 2219 | const QVector<SharedObjectPointer>& materials = heightfield->getMaterial()->getMaterials(); |
| 2084 | for (int i = 0; i < materials.size(); i += SPLAT_COUNT) { | 2220 | for (int i = 0; i < materials.size(); i += SPLAT_COUNT) { |
| 2085 | QVector4D scalesS, scalesT; | 2221 | for (int j = 0; j < SPLAT_COUNT; j++) { |
| 2086 | 2222 | int index = i + j; | |
| 2087 | for (int j = 0; j < SPLAT_COUNT; j++) { | 2223 | if (index < _networkTextures.size()) { |
| 2088 | glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[j]); | 2224 | const NetworkTexturePointer& texture = _networkTextures.at(index); |
| 2089 | int index = i + j; | 2225 | if (texture) { |
| 2090 | if (index < _networkTextures.size()) { | 2226 | MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data()); |
| 2091 | const NetworkTexturePointer& texture = _networkTextures.at(index); | 2227 | splatBatch.splatTextureScalesS[j] = xScale / material->getScaleS(); |
| 2092 | if (texture) { | 2228 | splatBatch.splatTextureScalesT[j] = zScale / material->getScaleT(); |
| 2093 | MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data()); | 2229 | splatBatch.splatTextureIDs[j] = texture->getID(); |
| 2094 | scalesS[j] = xScale / material->getScaleS(); | 2230 | |
| 2095 | scalesT[j] = zScale / material->getScaleT(); | ||
| 2096 | glBindTexture(GL_TEXTURE_2D, texture->getID()); | ||
| 2097 | } else { | ||
| 2098 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2099 | } | ||
| 2100 | } else { | 2231 | } else { |
| 2101 | glBindTexture(GL_TEXTURE_2D, 0); | 2232 | splatBatch.splatTextureIDs[j] = 0; |
| 2102 | } | 2233 | } |
| 2234 | } else { | ||
| 2235 | splatBatch.splatTextureIDs[j] = 0; | ||
| 2103 | } | 2236 | } |
| 2104 | const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL; | ||
| 2105 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 2106 | locations.splatTextureScalesS, scalesS); | ||
| 2107 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 2108 | locations.splatTextureScalesT, scalesT); | ||
| 2109 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 2110 | locations.textureValueMinima, | ||
| 2111 | (i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, | ||
| 2112 | (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, | ||
| 2113 | (i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, | ||
| 2114 | (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP); | ||
| 2115 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue( | ||
| 2116 | locations.textureValueMaxima, | ||
| 2117 | (i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, | ||
| 2118 | (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, | ||
| 2119 | (i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, | ||
| 2120 | (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP); | ||
| 2121 | glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); | ||
| 2122 | } | 2237 | } |
| 2123 | 2238 | splatBatch.materialIndex = i; | |
| 2124 | for (int i = 0; i < SPLAT_COUNT; i++) { | 2239 | Application::getInstance()->getMetavoxels()->addHeightfieldSplatBatch(splatBatch); |
| 2125 | glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]); | ||
| 2126 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2127 | } | ||
| 2128 | |||
| 2129 | glActiveTexture(GL_TEXTURE1); | ||
| 2130 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2131 | |||
| 2132 | DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().release(); | ||
| 2133 | |||
| 2134 | glDisable(GL_POLYGON_OFFSET_FILL); | ||
| 2135 | glDepthMask(true); | ||
| 2136 | glDepthFunc(GL_LESS); | ||
| 2137 | } | 2240 | } |
| 2138 | glActiveTexture(GL_TEXTURE0); | ||
| 2139 | |||
| 2140 | glDisable(GL_CULL_FACE); | ||
| 2141 | |||
| 2142 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 2143 | glDisableClientState(GL_VERTEX_ARRAY); | ||
| 2144 | } | 2241 | } |
| 2145 | |||
| 2146 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2147 | |||
| 2148 | glPopMatrix(); | ||
| 2149 | |||
| 2150 | bufferPair.first.release(); | ||
| 2151 | bufferPair.second.release(); | ||
| 2152 | } | 2242 | } |
| 2153 | 2243 | ||
| 2154 | void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) { | 2244 | void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) { |