History

Merge branch 'master' of https://github.com/highfidelity/hifi into temp0

Sam Gateau committed 12 years ago

Commit bd5c6512 parents 738369e 864dd01120 files · +7329 −2521Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+147−42
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333
3434 REGISTER_META_OBJECT(DefaultMetavoxelRendererImplementation)
3535 REGISTER_META_OBJECT(SphereRenderer)
36+REGISTER_META_OBJECT(CuboidRenderer)
3637 REGISTER_META_OBJECT(StaticModelRenderer)
3738
3839 static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
@@ -963,6 +964,12 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const · 924 unmodified lines
963964 Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
964965 }
965966
967+void VoxelPoint::setNormal(const glm::vec3& normal) {
968+ this->normal[0] = (char)(normal.x * 127.0f);
969+ this->normal[1] = (char)(normal.y * 127.0f);
970+ this->normal[2] = (char)(normal.z * 127.0f);
971+}
972+
966973 VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
967974 const QVector<SharedObjectPointer>& materials) :
968975 _vertices(vertices),
@@ -1534,8 +1541,21 @@ public: · 565 unmodified lines
15341541 glm::vec3 normal;
15351542 QRgb color;
15361543 char material;
1544+ int axis;
15371545 };
15381546
1547+class AxisIndex {
1548+public:
1549+ int x, y, z;
1550+
1551+ AxisIndex(int x = -1, int y = -1, int z = -1) : x(x), y(y), z(z) { }
1552+};
1553+
1554+static glm::vec3 safeNormalize(const glm::vec3& vector) {
1555+ float length = glm::length(vector);
1556+ return (length > 0.0f) ? (vector / length) : vector;
1557+}
1558+
15391559 int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
15401560 if (!info.isLeaf) {
15411561 return DEFAULT_ORDER;
@@ -1574,10 +1594,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 32 unmodified lines
15741594 // as we scan down the cube generating vertices between grid points, we remember the indices of the last
15751595 // (element, line, section--x, y, z) so that we can connect generated vertices as quads
15761596 int expanded = size + 1;
1577− QVector<int> lineIndices(expanded, -1);
1578− QVector<int> lastLineIndices(expanded, -1);
1579− QVector<int> planeIndices(expanded * expanded, -1);
1580− QVector<int> lastPlaneIndices(expanded * expanded, -1);
1597+ QVector<AxisIndex> lineIndices(expanded);
1598+ QVector<AxisIndex> lastLineIndices(expanded);
1599+ QVector<AxisIndex> planeIndices(expanded * expanded);
1600+ QVector<AxisIndex> lastPlaneIndices(expanded * expanded);
15811601
15821602 const int EDGES_PER_CUBE = 12;
15831603 EdgeCrossing crossings[EDGES_PER_CUBE];
@@ -1588,7 +1608,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 4 unmodified lines
15881608 for (int z = 0; z < expanded; z++) {
15891609 const QRgb* colorY = colorZ;
15901610 for (int y = 0; y < expanded; y++) {
1591− int lastIndex = 0;
1611+ AxisIndex lastIndex;
15921612 const QRgb* colorX = colorY;
15931613 for (int x = 0; x < expanded; x++) {
15941614 int alpha0 = colorX[0] >> ALPHA_OFFSET;
@@ -1662,6 +1682,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 67 unmodified lines
16621682 crossing.material = materialBase[0];
16631683 }
16641684 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f);
1685+ crossing.axis = 0;
16651686 }
16661687 if (middleY) {
16671688 if (alpha1 != alpha3) {
@@ -1676,6 +1697,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
16761697 crossing.material = materialBase[1];
16771698 }
16781699 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
1700+ crossing.axis = 1;
16791701 }
16801702 if (alpha2 != alpha3) {
16811703 QRgb hermite = hermiteBase[hermiteStride];
@@ -1689,6 +1711,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
16891711 crossing.material = materialBase[size];
16901712 }
16911713 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f);
1714+ crossing.axis = 0;
16921715 }
16931716 if (middleZ) {
16941717 if (alpha3 != alpha7) {
@@ -1703,6 +1726,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
17031726 crossing.material = materialBase[offset3];
17041727 }
17051728 crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1729+ crossing.axis = 2;
17061730 }
17071731 if (alpha5 != alpha7) {
17081732 QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1];
@@ -1716,6 +1740,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
17161740 crossing.material = materialBase[offset5];
17171741 }
17181742 crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
1743+ crossing.axis = 1;
17191744 }
17201745 if (alpha6 != alpha7) {
17211746 QRgb hermite = hermiteBase[hermiteArea + hermiteStride];
@@ -1729,6 +1754,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
17291754 crossing.material = materialBase[offset6];
17301755 }
17311756 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f);
1757+ crossing.axis = 0;
17321758 }
17331759 }
17341760 }
@@ -1745,6 +1771,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
17451771 crossing.material = materialBase[1];
17461772 }
17471773 crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1774+ crossing.axis = 2;
17481775 }
17491776 if (alpha4 != alpha5) {
17501777 QRgb hermite = hermiteBase[hermiteArea];
@@ -1758,6 +1785,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
17581785 crossing.material = materialBase[area];
17591786 }
17601787 crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f);
1788+ crossing.axis = 0;
17611789 }
17621790 }
17631791 }
@@ -1774,6 +1802,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 10 unmodified lines
17741802 crossing.material = materialBase[0];
17751803 }
17761804 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f);
1805+ crossing.axis = 1;
17771806 }
17781807 if (middleZ) {
17791808 if (alpha2 != alpha6) {
@@ -1788,6 +1817,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 8 unmodified lines
17881817 crossing.material = materialBase[size];
17891818 }
17901819 crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1820+ crossing.axis = 2;
17911821 }
17921822 if (alpha4 != alpha6) {
17931823 QRgb hermite = hermiteBase[hermiteArea + 1];
@@ -1801,6 +1831,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 7 unmodified lines
18011831 crossing.material = materialBase[area];
18021832 }
18031833 crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f);
1834+ crossing.axis = 1;
18041835 }
18051836 }
18061837 }
@@ -1816,11 +1847,12 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 9 unmodified lines
18161847 crossing.material = materialBase[0];
18171848 }
18181849 crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL);
1850+ crossing.axis = 2;
18191851 }
18201852 // at present, we simply average the properties of each crossing as opposed to finding the vertex that
18211853 // minimizes the quadratic error function as described in the reference paper
18221854 glm::vec3 center;
1823− glm::vec3 normal;
1855+ glm::vec3 axisNormals[3];
18241856 const int MAX_MATERIALS_PER_VERTEX = 4;
18251857 quint8 materials[] = { 0, 0, 0, 0 };
18261858 glm::vec4 materialWeights;
@@ -1829,7 +1861,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 2 unmodified lines
18291861 for (int i = 0; i < crossingCount; i++) {
18301862 const EdgeCrossing& crossing = crossings[i];
18311863 center += crossing.point;
1832− normal += crossing.normal;
1864+ axisNormals[crossing.axis] += crossing.normal;
18331865 red += qRed(crossing.color);
18341866 green += qGreen(crossing.color);
18351867 blue += qBlue(crossing.color);
@@ -1852,16 +1884,18 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 16 unmodified lines
18521884 }
18531885 }
18541886 }
1855− normal = glm::normalize(normal);
1887+ glm::vec3 normal = safeNormalize(axisNormals[0] + axisNormals[1] + axisNormals[2]);
18561888 center /= crossingCount;
18571889
18581890 // use a sequence of Givens rotations to perform a QR decomposition
18591891 // see http://www.cs.rice.edu/~jwarren/papers/techreport02408.pdf
18601892 glm::mat4 r(0.0f);
18611893 glm::vec4 bottom;
1894+ float smallestCosNormal = 1.0f;
18621895 for (int i = 0; i < crossingCount; i++) {
18631896 const EdgeCrossing& crossing = crossings[i];
18641897 bottom = glm::vec4(crossing.normal, glm::dot(crossing.normal, crossing.point - center));
1898+ smallestCosNormal = qMin(smallestCosNormal, glm::dot(crossing.normal, normal));
18651899
18661900 for (int j = 0; j < 4; j++) {
18671901 float angle = glm::atan(-bottom[j], r[j][j]);
@@ -1899,12 +1933,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 31 unmodified lines
18991933 int largestI = (largestIndex == 0) ? 1 : 2;
19001934 float sjj = d[largestJ][largestJ];
19011935 float sii = d[largestI][largestI];
1902− float angle = (sii == sjj ? PI_OVER_TWO : glm::atan(2.0f * d[largestJ][largestI], sjj - sii)) / 2.0f;
1936+ float angle = glm::atan(2.0f * d[largestJ][largestI], sjj - sii) / 2.0f;
19031937 glm::quat rotation = glm::angleAxis(angle, largestIndex == 0 ? glm::vec3(0.0f, 0.0f, -1.0f) :
19041938 (largestIndex == 1 ? glm::vec3(0.0f, 1.0f, 0.0f) : glm::vec3(-1.0f, 0.0f, 0.0f)));
1905− if (rotation.w == 0.0f) {
1906− break;
1907− }
19081939 combinedRotation = glm::normalize(rotation * combinedRotation);
19091940 glm::mat3 matrix = glm::mat3_cast(combinedRotation);
19101941 d = matrix * ata * glm::transpose(matrix);
@@ -1933,17 +1964,69 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 22 unmodified lines
19331964 { materials[0], materials[1], materials[2], materials[3] },
19341965 { (quint8)materialWeights[0], (quint8)materialWeights[1], (quint8)materialWeights[2],
19351966 (quint8)materialWeights[3] } };
1936− int index = vertices.size();
1937− vertices.append(point);
1967+
1968+ // determine whether we must "crease" by generating directional normals
1969+ const float CREASE_COS_NORMAL = glm::cos(glm::radians(40.0f));
1970+ AxisIndex index(vertices.size(), vertices.size(), vertices.size());
1971+ if (smallestCosNormal > CREASE_COS_NORMAL) {
1972+ vertices.append(point);
1973+
1974+ } else {
1975+ axisNormals[0] = safeNormalize(axisNormals[0]);
1976+ axisNormals[1] = safeNormalize(axisNormals[1]);
1977+ axisNormals[2] = safeNormalize(axisNormals[2]);
1978+ glm::vec3 normalXY(safeNormalize(axisNormals[0] + axisNormals[1]));
1979+ glm::vec3 normalXZ(safeNormalize(axisNormals[0] + axisNormals[2]));
1980+ glm::vec3 normalYZ(safeNormalize(axisNormals[1] + axisNormals[2]));
1981+ if (glm::dot(axisNormals[0], normalXY) > CREASE_COS_NORMAL &&
1982+ glm::dot(axisNormals[1], normalXY) > CREASE_COS_NORMAL) {
1983+ point.setNormal(normalXY);
1984+ vertices.append(point);
1985+
1986+ point.setNormal(axisNormals[2]);
1987+ index.z = vertices.size();
1988+ vertices.append(point);
1989+
1990+ } else if (glm::dot(axisNormals[0], normalXZ) > CREASE_COS_NORMAL &&
1991+ glm::dot(axisNormals[2], normalXZ) > CREASE_COS_NORMAL) {
1992+ point.setNormal(normalXZ);
1993+ vertices.append(point);
1994+
1995+ point.setNormal(axisNormals[1]);
1996+ index.y = vertices.size();
1997+ vertices.append(point);
1998+
1999+ } else if (glm::dot(axisNormals[1], normalYZ) > CREASE_COS_NORMAL &&
2000+ glm::dot(axisNormals[2], normalYZ) > CREASE_COS_NORMAL) {
2001+ point.setNormal(normalYZ);
2002+ vertices.append(point);
2003+
2004+ point.setNormal(axisNormals[0]);
2005+ index.x = vertices.size();
2006+ vertices.append(point);
2007+
2008+ } else {
2009+ point.setNormal(axisNormals[0]);
2010+ vertices.append(point);
2011+
2012+ point.setNormal(axisNormals[1]);
2013+ index.y = vertices.size();
2014+ vertices.append(point);
2015+
2016+ point.setNormal(axisNormals[2]);
2017+ index.z = vertices.size();
2018+ vertices.append(point);
2019+ }
2020+ }
19382021
19392022 // the first x, y, and z are repeated for the boundary edge; past that, we consider generating
19402023 // quads for each edge that includes a transition, using indices of previously generated vertices
19412024 if (x != 0 && y != 0 && z != 0) {
19422025 if (alpha0 != alpha1) {
1943− indices.append(index);
1944− int index1 = lastLineIndices.at(x);
1945− int index2 = lastPlaneIndices.at((y - 1) * expanded + x);
1946− int index3 = lastPlaneIndices.at(y * expanded + x);
2026+ indices.append(index.x);
2027+ int index1 = lastLineIndices.at(x).x;
2028+ int index2 = lastPlaneIndices.at((y - 1) * expanded + x).x;
2029+ int index3 = lastPlaneIndices.at(y * expanded + x).x;
19472030 if (alpha0 == 0) { // quad faces negative x
19482031 indices.append(index3);
19492032 indices.append(index2);
@@ -1956,10 +2039,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
19562039 }
19572040
19582041 if (alpha0 != alpha2) {
1959− indices.append(index);
1960− int index1 = lastIndex;
1961− int index2 = lastPlaneIndices.at(y * expanded + x - 1);
1962− int index3 = lastPlaneIndices.at(y * expanded + x);
2042+ indices.append(index.y);
2043+ int index1 = lastIndex.y;
2044+ int index2 = lastPlaneIndices.at(y * expanded + x - 1).y;
2045+ int index3 = lastPlaneIndices.at(y * expanded + x).y;
19632046 if (alpha0 == 0) { // quad faces negative y
19642047 indices.append(index1);
19652048 indices.append(index2);
@@ -1972,10 +2055,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { · 6 unmodified lines
19722055 }
19732056
19742057 if (alpha0 != alpha4) {
1975− indices.append(index);
1976− int index1 = lastIndex;
1977− int index2 = lastLineIndices.at(x - 1);
1978− int index3 = lastLineIndices.at(x);
2058+ indices.append(index.z);
2059+ int index1 = lastIndex.z;
2060+ int index2 = lastLineIndices.at(x - 1).z;
2061+ int index3 = lastLineIndices.at(x).z;
19792062 if (alpha0 == 0) { // quad faces negative z
19802063 indices.append(index3);
19812064 indices.append(index2);
@@ -2119,7 +2202,8 @@ int SpannerRenderVisitor::visit(MetavoxelInfo& info) { · 137 unmodified lines
21192202 }
21202203
21212204 bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) {
2122− spanner->getRenderer()->render(1.0f, SpannerRenderer::DEFAULT_MODE, clipMinimum, clipSize);
2205+ const glm::vec4 OPAQUE_WHITE(1.0f, 1.0f, 1.0f, 1.0f);
2206+ spanner->getRenderer()->render(OPAQUE_WHITE, SpannerRenderer::DEFAULT_MODE, clipMinimum, clipSize);
21232207 return true;
21242208 }
21252209
@@ -2285,9 +2369,9 @@ static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { · 159 unmodified lines
22852369 glEnable(plane);
22862370 }
22872371
2288−void ClippedRenderer::render(float alpha, Mode mode, const glm::vec3& clipMinimum, float clipSize) {
2372+void ClippedRenderer::render(const glm::vec4& color, Mode mode, const glm::vec3& clipMinimum, float clipSize) {
22892373 if (clipSize == 0.0f) {
2290− renderUnclipped(alpha, mode);
2374+ renderUnclipped(color, mode);
22912375 return;
22922376 }
22932377 enableClipPlane(GL_CLIP_PLANE0, -1.0f, 0.0f, 0.0f, clipMinimum.x + clipSize);
@@ -2297,7 +2381,7 @@ void ClippedRenderer::render(float alpha, Mode mode, const glm::vec3& clipMinimu · 3 unmodified lines
22972381 enableClipPlane(GL_CLIP_PLANE4, 0.0f, 0.0f, -1.0f, clipMinimum.z + clipSize);
22982382 enableClipPlane(GL_CLIP_PLANE5, 0.0f, 0.0f, 1.0f, -clipMinimum.z);
22992383
2300− renderUnclipped(alpha, mode);
2384+ renderUnclipped(color, mode);
23012385
23022386 glDisable(GL_CLIP_PLANE0);
23032387 glDisable(GL_CLIP_PLANE1);
@@ -2310,9 +2394,9 @@ void ClippedRenderer::render(float alpha, Mode mode, const glm::vec3& clipMinimu · 6 unmodified lines
23102394 SphereRenderer::SphereRenderer() {
23112395 }
23122396
2313−void SphereRenderer::render(float alpha, Mode mode, const glm::vec3& clipMinimum, float clipSize) {
2397+void SphereRenderer::render(const glm::vec4& color, Mode mode, const glm::vec3& clipMinimum, float clipSize) {
23142398 if (clipSize == 0.0f) {
2315− renderUnclipped(alpha, mode);
2399+ renderUnclipped(color, mode);
23162400 return;
23172401 }
23182402 // slight performance optimization: don't render if clip bounds are entirely within sphere
@@ -2321,29 +2405,50 @@ void SphereRenderer::render(float alpha, Mode mode, const glm::vec3& clipMinimum · 2 unmodified lines
23212405 for (int i = 0; i < Box::VERTEX_COUNT; i++) {
23222406 const float CLIP_PROPORTION = 0.95f;
23232407 if (glm::distance(sphere->getTranslation(), clipBox.getVertex(i)) >= sphere->getScale() * CLIP_PROPORTION) {
2324− ClippedRenderer::render(alpha, mode, clipMinimum, clipSize);
2408+ ClippedRenderer::render(color, mode, clipMinimum, clipSize);
23252409 return;
23262410 }
23272411 }
23282412 }
23292413
2330−void SphereRenderer::renderUnclipped(float alpha, Mode mode) {
2414+void SphereRenderer::renderUnclipped(const glm::vec4& color, Mode mode) {
23312415 Sphere* sphere = static_cast<Sphere*>(_spanner);
2332− const QColor& color = sphere->getColor();
2333− glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF() * alpha);
2416+ const QColor& ownColor = sphere->getColor();
2417+ glColor4f(ownColor.redF() * color.r, ownColor.greenF() * color.g, ownColor.blueF() * color.b, ownColor.alphaF() * color.a);
23342418
23352419 glPushMatrix();
23362420 const glm::vec3& translation = sphere->getTranslation();
23372421 glTranslatef(translation.x, translation.y, translation.z);
23382422 glm::quat rotation = sphere->getRotation();
23392423 glm::vec3 axis = glm::axis(rotation);
2340− glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
2424+ glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
23412425
23422426 Application::getInstance()->getGeometryCache()->renderSphere(sphere->getScale(), 10, 10);
23432427
23442428 glPopMatrix();
23452429 }
23462430
2431+CuboidRenderer::CuboidRenderer() {
2432+}
2433+
2434+void CuboidRenderer::renderUnclipped(const glm::vec4& color, Mode mode) {
2435+ Cuboid* cuboid = static_cast<Cuboid*>(_spanner);
2436+ const QColor& ownColor = cuboid->getColor();
2437+ glColor4f(ownColor.redF() * color.r, ownColor.greenF() * color.g, ownColor.blueF() * color.b, ownColor.alphaF() * color.a);
2438+
2439+ glPushMatrix();
2440+ const glm::vec3& translation = cuboid->getTranslation();
2441+ glTranslatef(translation.x, translation.y, translation.z);
2442+ glm::quat rotation = cuboid->getRotation();
2443+ glm::vec3 axis = glm::axis(rotation);
2444+ glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
2445+ glScalef(1.0f, cuboid->getAspectY(), cuboid->getAspectZ());
2446+
2447+ glutSolidCube(cuboid->getScale() * 2.0f);
2448+
2449+ glPopMatrix();
2450+}
2451+
23472452 StaticModelRenderer::StaticModelRenderer() :
23482453 _model(new Model(this)) {
23492454 }
@@ -2377,21 +2482,21 @@ void StaticModelRenderer::simulate(float deltaTime) { · 27 unmodified lines
23772482 _model->simulate(deltaTime);
23782483 }
23792484
2380−void StaticModelRenderer::renderUnclipped(float alpha, Mode mode) {
2485+void StaticModelRenderer::renderUnclipped(const glm::vec4& color, Mode mode) {
23812486 switch (mode) {
23822487 case DIFFUSE_MODE:
2383− _model->render(alpha, Model::DIFFUSE_RENDER_MODE);
2488+ _model->render(color.a, Model::DIFFUSE_RENDER_MODE);
23842489 break;
23852490
23862491 case NORMAL_MODE:
2387− _model->render(alpha, Model::NORMAL_RENDER_MODE);
2492+ _model->render(color.a, Model::NORMAL_RENDER_MODE);
23882493 break;
23892494
23902495 default:
2391− _model->render(alpha);
2496+ _model->render(color.a);
23922497 break;
23932498 }
2394− _model->render(alpha);
2499+ _model->render(color.a);
23952500 }
23962501
23972502 bool StaticModelRenderer::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,