History

Instanced rendering, first pass

Brad Davis committed 11 years ago

Commit 8a703d01 parent ec8639417 files · +1140 −899Browse files

Showing the changes to libraries/render-utils/src/GeometryCache.cpp (1 of 17 files). Show all

Unified · Split

libraries/render-utils/src/GeometryCache.cpp+100−66
@@ -689,28 +689,31 @@ void GeometryCache::renderVertices(gpu::Batch& batch, gpu::Primitive primitiveTy · 688 unmodified lines
689689 }
690690 }
691691
692−void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color) {
693− Vec2Pair colorKey(glm::vec2(color.x, color.y), glm::vec2(color.z, color.y));
694− const int FLOATS_PER_VERTEX = 3;
695− const int VERTICES_PER_FACE = 4;
696− const int NUMBER_OF_FACES = 6;
697− const int TRIANGLES_PER_FACE = 2;
698− const int VERTICES_PER_TRIANGLE = 3;
699− const int vertices = NUMBER_OF_FACES * VERTICES_PER_FACE;
700− const int indices = NUMBER_OF_FACES * TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;
701− const int vertexPoints = vertices * FLOATS_PER_VERTEX;
702− const int VERTEX_STRIDE = sizeof(GLfloat) * FLOATS_PER_VERTEX * 2; // vertices and normals
703− const int NORMALS_OFFSET = sizeof(GLfloat) * FLOATS_PER_VERTEX;
704−
692+static const int FLOATS_PER_VERTEX = 3;
693+static const int VERTICES_PER_TRIANGLE = 3;
694+
695+static const int CUBE_NUMBER_OF_FACES = 6;
696+static const int CUBE_VERTICES_PER_FACE = 4;
697+static const int CUBE_TRIANGLES_PER_FACE = 2;
698+static const int CUBE_VERTICES = CUBE_NUMBER_OF_FACES * CUBE_VERTICES_PER_FACE;
699+static const int CUBE_VERTEX_POINTS = CUBE_VERTICES * FLOATS_PER_VERTEX;
700+static const int CUBE_INDICES = CUBE_NUMBER_OF_FACES * CUBE_TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;
701+
702+static const gpu::Element CUBE_POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
703+static const gpu::Element CUBE_NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
704+static const gpu::Element CUBE_COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
705+static const gpu::Element INSTANCE_XFM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
706+
707+gpu::BufferPointer GeometryCache::getCubeVertices(float size) {
705708 if (!_solidCubeVertices.contains(size)) {
706709 auto verticesBuffer = std::make_shared<gpu::Buffer>();
707710 _solidCubeVertices[size] = verticesBuffer;
708711
709− GLfloat* vertexData = new GLfloat[vertexPoints * 2]; // vertices and normals
712+ GLfloat* vertexData = new GLfloat[CUBE_VERTEX_POINTS * 2]; // vertices and normals
710713 GLfloat* vertex = vertexData;
711714 float halfSize = size / 2.0f;
712715
713− static GLfloat cannonicalVertices[vertexPoints] =
716+ static GLfloat cannonicalVertices[CUBE_VERTEX_POINTS] =
714717 { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
715718 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
716719 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)
@@ -719,7 +722,7 @@ void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::ve · 2 unmodified lines
719722 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
720723
721724 // normal array
722− static GLfloat cannonicalNormals[vertexPoints] =
725+ static GLfloat cannonicalNormals[CUBE_VERTEX_POINTS] =
723726 { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
724727 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
725728 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
@@ -731,7 +734,7 @@ void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::ve · 5 unmodified lines
731734 GLfloat* cannonicalVertex = &cannonicalVertices[0];
732735 GLfloat* cannonicalNormal = &cannonicalNormals[0];
733736
734− for (int i = 0; i < vertices; i++) {
737+ for (int i = 0; i < CUBE_VERTICES; i++) {
735738 // vertices
736739 *(vertex++) = halfSize * *cannonicalVertex++;
737740 *(vertex++) = halfSize * *cannonicalVertex++;
@@ -742,90 +745,121 @@ void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::ve · 4 unmodified lines
742745 *(vertex++) = *cannonicalNormal++;
743746 *(vertex++) = *cannonicalNormal++;
744747 }
745−
746− verticesBuffer->append(sizeof(GLfloat) * vertexPoints * 2, (gpu::Byte*) vertexData);
748+ verticesBuffer->append(sizeof(GLfloat) * CUBE_VERTEX_POINTS * 2, (gpu::Byte*) vertexData);
747749 }
748750
751+ return _solidCubeVertices[size];
752+}
753+
754+gpu::BufferPointer GeometryCache::getSolidCubeIndices() {
749755 if (!_solidCubeIndexBuffer) {
750− static GLubyte cannonicalIndices[indices] =
751− { 0, 1, 2, 2, 3, 0, // front
756+ static GLubyte cannonicalIndices[CUBE_INDICES] = { 0, 1, 2, 2, 3, 0, // front
752757 4, 5, 6, 6, 7, 4, // right
753758 8, 9,10, 10,11, 8, // top
754759 12,13,14, 14,15,12, // left
755760 16,17,18, 18,19,16, // bottom
756761 20,21,22, 22,23,20 }; // back
757−
762+
758763 auto indexBuffer = std::make_shared<gpu::Buffer>();
759764 _solidCubeIndexBuffer = indexBuffer;
760−
765+
761766 _solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);
762767 }
768+ return _solidCubeIndexBuffer;
769+}
770+
771+
772+void GeometryCache::setupCubeVertices(gpu::Batch& batch, gpu::BufferPointer& verticesBuffer) {
773+ static const int VERTEX_STRIDE = sizeof(GLfloat) * FLOATS_PER_VERTEX * 2; // vertices and normals
774+ static const int NORMALS_OFFSET = sizeof(GLfloat) * FLOATS_PER_VERTEX;
775+
776+ gpu::BufferView verticesView(verticesBuffer, 0, verticesBuffer->getSize(), VERTEX_STRIDE, CUBE_POSITION_ELEMENT);
777+ gpu::BufferView normalsView(verticesBuffer, NORMALS_OFFSET, verticesBuffer->getSize(), VERTEX_STRIDE, CUBE_NORMAL_ELEMENT);
778+ batch.setInputBuffer(gpu::Stream::POSITION, verticesView);
779+ batch.setInputBuffer(gpu::Stream::NORMAL, normalsView);
780+}
781+
782+void GeometryCache::renderSolidCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
783+ static gpu::Stream::FormatPointer streamFormat;
784+ if (!streamFormat) {
785+ streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
786+ streamFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, CUBE_POSITION_ELEMENT, 0);
787+ streamFormat->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, CUBE_NORMAL_ELEMENT);
788+ streamFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, CUBE_COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
789+ streamFormat->setAttribute(gpu::Stream::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, INSTANCE_XFM_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
790+ }
791+ batch.setInputFormat(streamFormat);
792+
793+ gpu::BufferView colorView(colorBuffer, CUBE_COLOR_ELEMENT);
794+ batch.setInputBuffer(gpu::Stream::COLOR, colorView);
763795
796+ gpu::BufferView instanceXfmView(transformBuffer, 0, transformBuffer->getSize(), INSTANCE_XFM_ELEMENT);
797+ batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
798+
799+ gpu::BufferPointer verticesBuffer = getCubeVertices(1.0);
800+ setupCubeVertices(batch, verticesBuffer);
801+ batch.setIndexBuffer(gpu::UINT8, getSolidCubeIndices(), 0);
802+ batch.drawIndexedInstanced(count, gpu::TRIANGLES, CUBE_INDICES);
803+}
804+
805+
806+void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color) {
807+ Vec2Pair colorKey(glm::vec2(color.x, color.y), glm::vec2(color.z, color.y));
764808 if (!_solidCubeColors.contains(colorKey)) {
765809 auto colorBuffer = std::make_shared<gpu::Buffer>();
766810 _solidCubeColors[colorKey] = colorBuffer;
767811
768− const int NUM_COLOR_SCALARS_PER_CUBE = 24;
769812 int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
770813 ((int(color.y * 255.0f) & 0xFF) << 8) |
771814 ((int(color.z * 255.0f) & 0xFF) << 16) |
772815 ((int(color.w * 255.0f) & 0xFF) << 24);
773− int colors[NUM_COLOR_SCALARS_PER_CUBE] = { compactColor, compactColor, compactColor, compactColor,
774− compactColor, compactColor, compactColor, compactColor,
775− compactColor, compactColor, compactColor, compactColor,
776− compactColor, compactColor, compactColor, compactColor,
777− compactColor, compactColor, compactColor, compactColor,
778− compactColor, compactColor, compactColor, compactColor };
779−
816+ int colors[CUBE_VERTICES] = {
817+ compactColor, compactColor, compactColor, compactColor,
818+ compactColor, compactColor, compactColor, compactColor,
819+ compactColor, compactColor, compactColor, compactColor,
820+ compactColor, compactColor, compactColor, compactColor,
821+ compactColor, compactColor, compactColor, compactColor,
822+ compactColor, compactColor, compactColor, compactColor
823+ };
780824 colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
781825 }
782− gpu::BufferPointer verticesBuffer = _solidCubeVertices[size];
783826 gpu::BufferPointer colorBuffer = _solidCubeColors[colorKey];
784827
785− const int VERTICES_SLOT = 0;
786− const int NORMALS_SLOT = 1;
787− const int COLOR_SLOT = 2;
788828 static gpu::Stream::FormatPointer streamFormat;
789− static gpu::Element positionElement, normalElement, colorElement;
790829 if (!streamFormat) {
791830 streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
792− streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
793− streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
794− streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
795− positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
796− normalElement = streamFormat->getAttributes().at(gpu::Stream::NORMAL)._element;
797− colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
831+ streamFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, CUBE_POSITION_ELEMENT, 0);
832+ streamFormat->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, CUBE_NORMAL_ELEMENT);
833+ streamFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, CUBE_COLOR_ELEMENT);
798834 }
799−
800−
801− gpu::BufferView verticesView(verticesBuffer, 0, verticesBuffer->getSize(), VERTEX_STRIDE, positionElement);
802− gpu::BufferView normalsView(verticesBuffer, NORMALS_OFFSET, verticesBuffer->getSize(), VERTEX_STRIDE, normalElement);
803− gpu::BufferView colorView(colorBuffer, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
804−
805835 batch.setInputFormat(streamFormat);
806− batch.setInputBuffer(VERTICES_SLOT, verticesView);
807− batch.setInputBuffer(NORMALS_SLOT, normalsView);
808− batch.setInputBuffer(COLOR_SLOT, colorView);
809− batch.setIndexBuffer(gpu::UINT8, _solidCubeIndexBuffer, 0);
810− batch.drawIndexed(gpu::TRIANGLES, indices);
836+
837+ gpu::BufferView colorView(colorBuffer, CUBE_COLOR_ELEMENT);
838+ batch.setInputBuffer(gpu::Stream::COLOR, colorView);
839+
840+ gpu::BufferPointer verticesBuffer = getCubeVertices(size);
841+ setupCubeVertices(batch, verticesBuffer);
842+
843+ batch.setIndexBuffer(gpu::UINT8, getSolidCubeIndices(), 0);
844+ batch.drawIndexed(gpu::TRIANGLES, CUBE_INDICES);
811845 }
812846
847+
813848 void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) {
814849 Vec2Pair colorKey(glm::vec2(color.x, color.y),glm::vec2(color.z, color.y));
815− const int FLOATS_PER_VERTEX = 3;
816− const int VERTICES_PER_EDGE = 2;
817− const int TOP_EDGES = 4;
818− const int BOTTOM_EDGES = 4;
819− const int SIDE_EDGES = 4;
820− const int vertices = 8;
821− const int indices = (TOP_EDGES + BOTTOM_EDGES + SIDE_EDGES) * VERTICES_PER_EDGE;
850+ static const int WIRE_CUBE_VERTICES_PER_EDGE = 2;
851+ static const int WIRE_CUBE_TOP_EDGES = 4;
852+ static const int WIRE_CUBE_BOTTOM_EDGES = 4;
853+ static const int WIRE_CUBE_SIDE_EDGES = 4;
854+ static const int WIRE_CUBE_VERTICES = 8;
855+ static const int WIRE_CUBE_INDICES = (WIRE_CUBE_TOP_EDGES + WIRE_CUBE_BOTTOM_EDGES + WIRE_CUBE_SIDE_EDGES) * WIRE_CUBE_VERTICES_PER_EDGE;
822856
823857 if (!_cubeVerticies.contains(size)) {
824858 auto verticesBuffer = std::make_shared<gpu::Buffer>();
825859 _cubeVerticies[size] = verticesBuffer;
826860
827− int vertexPoints = vertices * FLOATS_PER_VERTEX;
828− GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a wire cube
861+ static const int WIRE_CUBE_VERTEX_POINTS = WIRE_CUBE_VERTICES * FLOATS_PER_VERTEX;
862+ GLfloat* vertexData = new GLfloat[WIRE_CUBE_VERTEX_POINTS]; // only vertices, no normals because we're a wire cube
829863 GLfloat* vertex = vertexData;
830864 float halfSize = size / 2.0f;
831865
@@ -834,15 +868,15 @@ void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec · 2 unmodified lines
834868 1,-1, 1, 1,-1,-1, -1,-1,-1, -1,-1, 1 // v4, v5, v6, v7 (bottom)
835869 };
836870
837− for (int i = 0; i < vertexPoints; i++) {
871+ for (int i = 0; i < WIRE_CUBE_VERTEX_POINTS; i++) {
838872 vertex[i] = cannonicalVertices[i] * halfSize;
839873 }
840874
841− verticesBuffer->append(sizeof(GLfloat) * vertexPoints, (gpu::Byte*) vertexData); // I'm skeptical that this is right
875+ verticesBuffer->append(sizeof(GLfloat) * WIRE_CUBE_VERTEX_POINTS, (gpu::Byte*) vertexData); // I'm skeptical that this is right
842876 }
843877
844878 if (!_wireCubeIndexBuffer) {
845− static GLubyte cannonicalIndices[indices] = {
879+ static GLubyte cannonicalIndices[WIRE_CUBE_INDICES] = {
846880 0, 1, 1, 2, 2, 3, 3, 0, // (top)
847881 4, 5, 5, 6, 6, 7, 7, 4, // (bottom)
848882 0, 4, 1, 5, 2, 6, 3, 7, // (side edges)
@@ -890,7 +924,7 @@ void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec · 41 unmodified lines
890924 batch.setInputBuffer(VERTICES_SLOT, verticesView);
891925 batch.setInputBuffer(COLOR_SLOT, colorView);
892926 batch.setIndexBuffer(gpu::UINT8, _wireCubeIndexBuffer, 0);
893− batch.drawIndexed(gpu::LINES, indices);
927+ batch.drawIndexed(gpu::LINES, WIRE_CUBE_INDICES);
894928 }
895929
896930 void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {