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
689 }689 }
690}690}
691 691
692void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color) {692static const int FLOATS_PER_VERTEX = 3;
693 Vec2Pair colorKey(glm::vec2(color.x, color.y), glm::vec2(color.z, color.y));693static const int VERTICES_PER_TRIANGLE = 3;
694 const int FLOATS_PER_VERTEX = 3;694
695 const int VERTICES_PER_FACE = 4;695static const int CUBE_NUMBER_OF_FACES = 6;
696 const int NUMBER_OF_FACES = 6;696static const int CUBE_VERTICES_PER_FACE = 4;
697 const int TRIANGLES_PER_FACE = 2;697static const int CUBE_TRIANGLES_PER_FACE = 2;
698 const int VERTICES_PER_TRIANGLE = 3;698static const int CUBE_VERTICES = CUBE_NUMBER_OF_FACES * CUBE_VERTICES_PER_FACE;
699 const int vertices = NUMBER_OF_FACES * VERTICES_PER_FACE;699static const int CUBE_VERTEX_POINTS = CUBE_VERTICES * FLOATS_PER_VERTEX;
700 const int indices = NUMBER_OF_FACES * TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;700static const int CUBE_INDICES = CUBE_NUMBER_OF_FACES * CUBE_TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;
701 const int vertexPoints = vertices * FLOATS_PER_VERTEX;701
702 const int VERTEX_STRIDE = sizeof(GLfloat) * FLOATS_PER_VERTEX * 2; // vertices and normals702static const gpu::Element CUBE_POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
703 const int NORMALS_OFFSET = sizeof(GLfloat) * FLOATS_PER_VERTEX;703static const gpu::Element CUBE_NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
704 704static const gpu::Element CUBE_COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
705static const gpu::Element INSTANCE_XFM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
706
707gpu::BufferPointer GeometryCache::getCubeVertices(float size) {
705 if (!_solidCubeVertices.contains(size)) {708 if (!_solidCubeVertices.contains(size)) {
706 auto verticesBuffer = std::make_shared<gpu::Buffer>();709 auto verticesBuffer = std::make_shared<gpu::Buffer>();
707 _solidCubeVertices[size] = verticesBuffer;710 _solidCubeVertices[size] = verticesBuffer;
708 711
709 GLfloat* vertexData = new GLfloat[vertexPoints * 2]; // vertices and normals712 GLfloat* vertexData = new GLfloat[CUBE_VERTEX_POINTS * 2]; // vertices and normals
710 GLfloat* vertex = vertexData;713 GLfloat* vertex = vertexData;
711 float halfSize = size / 2.0f;714 float halfSize = size / 2.0f;
712 715
713 static GLfloat cannonicalVertices[vertexPoints] = 716 static GLfloat cannonicalVertices[CUBE_VERTEX_POINTS] =
714 { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)717 { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
715 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)718 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
716 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)719 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
719 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)722 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
720 723
721 // normal array724 // normal array
722 static GLfloat cannonicalNormals[vertexPoints] = 725 static GLfloat cannonicalNormals[CUBE_VERTEX_POINTS] =
723 { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)726 { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
724 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)727 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
725 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)728 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
731 GLfloat* cannonicalVertex = &cannonicalVertices[0];734 GLfloat* cannonicalVertex = &cannonicalVertices[0];
732 GLfloat* cannonicalNormal = &cannonicalNormals[0];735 GLfloat* cannonicalNormal = &cannonicalNormals[0];
733 736
734 for (int i = 0; i < vertices; i++) {737 for (int i = 0; i < CUBE_VERTICES; i++) {
735 // vertices738 // vertices
736 *(vertex++) = halfSize * *cannonicalVertex++;739 *(vertex++) = halfSize * *cannonicalVertex++;
737 *(vertex++) = halfSize * *cannonicalVertex++;740 *(vertex++) = halfSize * *cannonicalVertex++;
@@ -742,90 +745,121 @@ void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::ve · 4 unmodified lines
742 *(vertex++) = *cannonicalNormal++;745 *(vertex++) = *cannonicalNormal++;
743 *(vertex++) = *cannonicalNormal++;746 *(vertex++) = *cannonicalNormal++;
744 }747 }
745 748 verticesBuffer->append(sizeof(GLfloat) * CUBE_VERTEX_POINTS * 2, (gpu::Byte*) vertexData);
746 verticesBuffer->append(sizeof(GLfloat) * vertexPoints * 2, (gpu::Byte*) vertexData);
747 }749 }
748 750
751 return _solidCubeVertices[size];
752}
753
754gpu::BufferPointer GeometryCache::getSolidCubeIndices() {
749 if (!_solidCubeIndexBuffer) {755 if (!_solidCubeIndexBuffer) {
750 static GLubyte cannonicalIndices[indices] = 756 static GLubyte cannonicalIndices[CUBE_INDICES] = { 0, 1, 2, 2, 3, 0, // front
751 { 0, 1, 2, 2, 3, 0, // front
752 4, 5, 6, 6, 7, 4, // right757 4, 5, 6, 6, 7, 4, // right
753 8, 9,10, 10,11, 8, // top758 8, 9,10, 10,11, 8, // top
754 12,13,14, 14,15,12, // left759 12,13,14, 14,15,12, // left
755 16,17,18, 18,19,16, // bottom760 16,17,18, 18,19,16, // bottom
756 20,21,22, 22,23,20 }; // back761 20,21,22, 22,23,20 }; // back
757 762
758 auto indexBuffer = std::make_shared<gpu::Buffer>();763 auto indexBuffer = std::make_shared<gpu::Buffer>();
759 _solidCubeIndexBuffer = indexBuffer;764 _solidCubeIndexBuffer = indexBuffer;
760 765
761 _solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);766 _solidCubeIndexBuffer->append(sizeof(cannonicalIndices), (gpu::Byte*) cannonicalIndices);
762 }767 }
768 return _solidCubeIndexBuffer;
769}
770
771
772void 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
782void 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);
763 795
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
806void 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));
764 if (!_solidCubeColors.contains(colorKey)) {808 if (!_solidCubeColors.contains(colorKey)) {
765 auto colorBuffer = std::make_shared<gpu::Buffer>();809 auto colorBuffer = std::make_shared<gpu::Buffer>();
766 _solidCubeColors[colorKey] = colorBuffer;810 _solidCubeColors[colorKey] = colorBuffer;
767 811
768 const int NUM_COLOR_SCALARS_PER_CUBE = 24;
769 int compactColor = ((int(color.x * 255.0f) & 0xFF)) |812 int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
770 ((int(color.y * 255.0f) & 0xFF) << 8) |813 ((int(color.y * 255.0f) & 0xFF) << 8) |
771 ((int(color.z * 255.0f) & 0xFF) << 16) |814 ((int(color.z * 255.0f) & 0xFF) << 16) |
772 ((int(color.w * 255.0f) & 0xFF) << 24);815 ((int(color.w * 255.0f) & 0xFF) << 24);
773 int colors[NUM_COLOR_SCALARS_PER_CUBE] = { compactColor, compactColor, compactColor, compactColor,816 int colors[CUBE_VERTICES] = {
774 compactColor, compactColor, compactColor, compactColor,817 compactColor, compactColor, compactColor, compactColor,
775 compactColor, compactColor, compactColor, compactColor,818 compactColor, compactColor, compactColor, compactColor,
776 compactColor, compactColor, compactColor, compactColor,819 compactColor, compactColor, compactColor, compactColor,
777 compactColor, compactColor, compactColor, compactColor,820 compactColor, compactColor, compactColor, compactColor,
778 compactColor, compactColor, compactColor, compactColor };821 compactColor, compactColor, compactColor, compactColor,
779 822 compactColor, compactColor, compactColor, compactColor
823 };
780 colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);824 colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
781 }825 }
782 gpu::BufferPointer verticesBuffer = _solidCubeVertices[size];
783 gpu::BufferPointer colorBuffer = _solidCubeColors[colorKey];826 gpu::BufferPointer colorBuffer = _solidCubeColors[colorKey];
784 827
785 const int VERTICES_SLOT = 0;
786 const int NORMALS_SLOT = 1;
787 const int COLOR_SLOT = 2;
788 static gpu::Stream::FormatPointer streamFormat;828 static gpu::Stream::FormatPointer streamFormat;
789 static gpu::Element positionElement, normalElement, colorElement;
790 if (!streamFormat) {829 if (!streamFormat) {
791 streamFormat = std::make_shared<gpu::Stream::Format>(); // 1 for everyone830 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);831 streamFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, CUBE_POSITION_ELEMENT, 0);
793 streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));832 streamFormat->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, CUBE_NORMAL_ELEMENT);
794 streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));833 streamFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, CUBE_COLOR_ELEMENT);
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;
798 }834 }
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
805 batch.setInputFormat(streamFormat);835 batch.setInputFormat(streamFormat);
806 batch.setInputBuffer(VERTICES_SLOT, verticesView);836
807 batch.setInputBuffer(NORMALS_SLOT, normalsView);837 gpu::BufferView colorView(colorBuffer, CUBE_COLOR_ELEMENT);
808 batch.setInputBuffer(COLOR_SLOT, colorView);838 batch.setInputBuffer(gpu::Stream::COLOR, colorView);
809 batch.setIndexBuffer(gpu::UINT8, _solidCubeIndexBuffer, 0);839
810 batch.drawIndexed(gpu::TRIANGLES, indices);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);
811}845}
812 846
847
813void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) {848void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) {
814 Vec2Pair colorKey(glm::vec2(color.x, color.y),glm::vec2(color.z, color.y));849 Vec2Pair colorKey(glm::vec2(color.x, color.y),glm::vec2(color.z, color.y));
815 const int FLOATS_PER_VERTEX = 3;850 static const int WIRE_CUBE_VERTICES_PER_EDGE = 2;
816 const int VERTICES_PER_EDGE = 2;851 static const int WIRE_CUBE_TOP_EDGES = 4;
817 const int TOP_EDGES = 4;852 static const int WIRE_CUBE_BOTTOM_EDGES = 4;
818 const int BOTTOM_EDGES = 4;853 static const int WIRE_CUBE_SIDE_EDGES = 4;
819 const int SIDE_EDGES = 4;854 static const int WIRE_CUBE_VERTICES = 8;
820 const int 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;
821 const int indices = (TOP_EDGES + BOTTOM_EDGES + SIDE_EDGES) * VERTICES_PER_EDGE;
822 856
823 if (!_cubeVerticies.contains(size)) {857 if (!_cubeVerticies.contains(size)) {
824 auto verticesBuffer = std::make_shared<gpu::Buffer>();858 auto verticesBuffer = std::make_shared<gpu::Buffer>();
825 _cubeVerticies[size] = verticesBuffer;859 _cubeVerticies[size] = verticesBuffer;
826 860
827 int vertexPoints = vertices * FLOATS_PER_VERTEX;861 static const int WIRE_CUBE_VERTEX_POINTS = WIRE_CUBE_VERTICES * FLOATS_PER_VERTEX;
828 GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a wire cube862 GLfloat* vertexData = new GLfloat[WIRE_CUBE_VERTEX_POINTS]; // only vertices, no normals because we're a wire cube
829 GLfloat* vertex = vertexData;863 GLfloat* vertex = vertexData;
830 float halfSize = size / 2.0f;864 float halfSize = size / 2.0f;
831 865
@@ -834,15 +868,15 @@ void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec · 2 unmodified lines
834 1,-1, 1, 1,-1,-1, -1,-1,-1, -1,-1, 1 // v4, v5, v6, v7 (bottom)868 1,-1, 1, 1,-1,-1, -1,-1,-1, -1,-1, 1 // v4, v5, v6, v7 (bottom)
835 };869 };
836 870
837 for (int i = 0; i < vertexPoints; i++) {871 for (int i = 0; i < WIRE_CUBE_VERTEX_POINTS; i++) {
838 vertex[i] = cannonicalVertices[i] * halfSize;872 vertex[i] = cannonicalVertices[i] * halfSize;
839 }873 }
840 874
841 verticesBuffer->append(sizeof(GLfloat) * vertexPoints, (gpu::Byte*) vertexData); // I'm skeptical that this is right875 verticesBuffer->append(sizeof(GLfloat) * WIRE_CUBE_VERTEX_POINTS, (gpu::Byte*) vertexData); // I'm skeptical that this is right
842 }876 }
843 877
844 if (!_wireCubeIndexBuffer) {878 if (!_wireCubeIndexBuffer) {
845 static GLubyte cannonicalIndices[indices] = { 879 static GLubyte cannonicalIndices[WIRE_CUBE_INDICES] = {
846 0, 1, 1, 2, 2, 3, 3, 0, // (top)880 0, 1, 1, 2, 2, 3, 3, 0, // (top)
847 4, 5, 5, 6, 6, 7, 7, 4, // (bottom)881 4, 5, 5, 6, 6, 7, 7, 4, // (bottom)
848 0, 4, 1, 5, 2, 6, 3, 7, // (side edges)882 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
890 batch.setInputBuffer(VERTICES_SLOT, verticesView);924 batch.setInputBuffer(VERTICES_SLOT, verticesView);
891 batch.setInputBuffer(COLOR_SLOT, colorView);925 batch.setInputBuffer(COLOR_SLOT, colorView);
892 batch.setIndexBuffer(gpu::UINT8, _wireCubeIndexBuffer, 0);926 batch.setIndexBuffer(gpu::UINT8, _wireCubeIndexBuffer, 0);
893 batch.drawIndexed(gpu::LINES, indices);927 batch.drawIndexed(gpu::LINES, WIRE_CUBE_INDICES);
894}928}
895 929
896void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {930void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {