CR feedback

This commit is contained in:
Bradley Austin Davis 2015-09-21 15:44:47 -07:00
parent 84cea1ffd4
commit b3aeaba5f4
5 changed files with 210 additions and 122 deletions

View file

@ -24,12 +24,12 @@ void RenderableDebugableEntityItem::renderBoundingBox(EntityItem* entity, Render
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
auto xfm = entity->getTransformToCenter();
auto shapeTransform = entity->getTransformToCenter();
if (puffedOut != 0.0) {
xfm.postScale(1.0 + puffedOut);
shapeTransform.postScale(1.0 + puffedOut);
}
batch.setModelTransform(Transform()); // we want to include the scale as well
DependencyManager::get<DeferredLightingEffect>()->renderWireCubeInstance(batch, xfm, color);
DependencyManager::get<DeferredLightingEffect>()->renderWireCubeInstance(batch, shapeTransform, color);
}
void RenderableDebugableEntityItem::render(EntityItem* entity, RenderArgs* args) {

View file

@ -127,13 +127,13 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
gpu::Batch& batch = *args->_batch;
batch.setModelTransform(Transform());
auto xfm = getTransformToCenter();
auto shapeTransform = getTransformToCenter();
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
if (getShapeType() == SHAPE_TYPE_SPHERE) {
xfm.postScale(SPHERE_ENTITY_SCALE);
deferredLightingEffect->renderWireSphereInstance(batch, xfm, DEFAULT_COLOR);
shapeTransform.postScale(SPHERE_ENTITY_SCALE);
deferredLightingEffect->renderWireSphereInstance(batch, shapeTransform, DEFAULT_COLOR);
} else {
deferredLightingEffect->renderWireCubeInstance(batch, xfm, DEFAULT_COLOR);
deferredLightingEffect->renderWireCubeInstance(batch, shapeTransform, DEFAULT_COLOR);
}
break;
}

View file

@ -187,10 +187,6 @@ gpu::PipelinePointer DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch
return pipeline;
}
void DeferredLightingEffect::renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color) {
}
uint32_t toCompactColor(const glm::vec4& color) {
uint32_t compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
@ -203,11 +199,11 @@ static const size_t INSTANCE_TRANSFORM_BUFFER = 0;
static const size_t INSTANCE_COLOR_BUFFER = 1;
template <typename F>
void renderInstances(const std::string& name, gpu::Batch& batch, const Transform& xfm, const glm::vec4& color, F f) {
void renderInstances(const std::string& name, gpu::Batch& batch, const Transform& transform, const glm::vec4& color, F f) {
{
gpu::BufferPointer instanceTransformBuffer = batch.getNamedBuffer(name, INSTANCE_TRANSFORM_BUFFER);
glm::mat4 xfmMat4;
instanceTransformBuffer->append(xfm.getMatrix(xfmMat4));
glm::mat4 glmTransform;
instanceTransformBuffer->append(transform.getMatrix(glmTransform));
gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER);
auto compactColor = toCompactColor(color);
@ -225,21 +221,32 @@ void renderInstances(const std::string& name, gpu::Batch& batch, const Transform
});
}
void DeferredLightingEffect::renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color) {
void DeferredLightingEffect::renderSolidSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
static const std::string INSTANCE_NAME = __FUNCTION__;
renderInstances(INSTANCE_NAME, batch, xfm, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
DependencyManager::get<GeometryCache>()->renderSphereInstances(batch, data._count,
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, GeometryCache::Sphere, data._count,
data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]);
});
}
static auto startTime = usecTimestampNow();
void DeferredLightingEffect::renderWireSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
static const std::string INSTANCE_NAME = __FUNCTION__;
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, GeometryCache::Sphere, data._count,
data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]);
});
}
void DeferredLightingEffect::renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color) {
// Enable this in a debug build to cause 'box' entities to iterate through all the
// available shape types, both solid and wireframes
//#define DEBUG_SHAPES
void DeferredLightingEffect::renderSolidCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
static const std::string INSTANCE_NAME = __FUNCTION__;
#ifdef DEBUG_SHAPES
renderInstances(INSTANCE_NAME, batch, xfm, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
static auto startTime = usecTimestampNow();
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
auto usecs = usecTimestampNow();
usecs -= startTime;
@ -249,7 +256,9 @@ void DeferredLightingEffect::renderSolidCubeInstance(gpu::Batch& batch, const Tr
float fractionalSeconds = seconds - floor(seconds);
int shapeIndex = (int)seconds;
GeometryCache::Shape shapes[] = {
// Every second we flip to the next shape.
static const int SHAPE_COUNT = 5;
GeometryCache::Shape shapes[SHAPE_COUNT] = {
GeometryCache::Cube,
GeometryCache::Tetrahedron,
GeometryCache::Sphere,
@ -257,9 +266,10 @@ void DeferredLightingEffect::renderSolidCubeInstance(gpu::Batch& batch, const Tr
GeometryCache::Line,
};
shapeIndex %= 5;
shapeIndex %= SHAPE_COUNT;
GeometryCache::Shape shape = shapes[shapeIndex];
// For the first half second for a given shape, show the wireframe, for the second half, show the solid.
if (fractionalSeconds > 0.5f) {
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, shape, data._count,
data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]);
@ -269,16 +279,16 @@ void DeferredLightingEffect::renderSolidCubeInstance(gpu::Batch& batch, const Tr
}
});
#else
renderInstances(INSTANCE_NAME, batch, xfm, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
DependencyManager::get<GeometryCache>()->renderCubeInstances(batch, data._count,
data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]);
});
#endif
}
void DeferredLightingEffect::renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color) {
void DeferredLightingEffect::renderWireCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
static const std::string INSTANCE_NAME = __FUNCTION__;
renderInstances(INSTANCE_NAME, batch, xfm, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
DependencyManager::get<GeometryCache>()->renderWireCubeInstances(batch, data._count,
data._buffers[INSTANCE_TRANSFORM_BUFFER], data._buffers[INSTANCE_COLOR_BUFFER]);
});

View file

@ -57,7 +57,7 @@ static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and n
static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3);
void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const VVertex& vertices) {
void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const VertexVector& vertices) {
vertexBuffer->append(vertices);
_positionView = gpu::BufferView(vertexBuffer, 0,
@ -66,7 +66,7 @@ void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, c
vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT);
}
void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const VIndex& indices, const VIndex& wireIndices) {
void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const IndexVector& indices, const IndexVector& wireIndices) {
_indices = indexBuffer;
if (!indices.empty()) {
_indexOffset = indexBuffer->getSize();
@ -118,12 +118,12 @@ void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count
}
}
const VVertex& icosahedronVertices() {
const VertexVector& icosahedronVertices() {
static const float phi = (1.0 + sqrt(5.0)) / 2.0;
static const float a = 0.5;
static const float b = 1.0 / (2.0 * phi);
static const VVertex vertices{ //
static const VertexVector vertices{ //
vec3(0, b, -a), vec3(-b, a, 0), vec3(b, a, 0), //
vec3(0, b, a), vec3(b, a, 0), vec3(-b, a, 0), //
vec3(0, b, a), vec3(-a, 0, b), vec3(0, -b, a), //
@ -148,13 +148,13 @@ const VVertex& icosahedronVertices() {
return vertices;
}
const VVertex& tetrahedronVertices() {
const VertexVector& tetrahedronVertices() {
static const float a = 1.0f / sqrt(2.0f);
static const auto A = vec3(0, 1, a);
static const auto B = vec3(0, -1, a);
static const auto C = vec3(1, 0, -a);
static const auto D = vec3(-1, 0, -a);
static const VVertex vertices{
static const VertexVector vertices{
A, B, C,
D, B, A,
C, D, A,
@ -163,8 +163,13 @@ const VVertex& tetrahedronVertices() {
return vertices;
}
VVertex tesselate(const VVertex& startingTriangles, int count) {
VVertex triangles = startingTriangles;
static const size_t TESSELTATION_MULTIPLIER = 4;
static const size_t ICOSAHEDRON_TO_SPHERE_TESSELATION_COUNT = 3;
static const size_t VECTOR_TO_VECTOR_WITH_NORMAL_MULTIPLER = 2;
VertexVector tesselate(const VertexVector& startingTriangles, int count) {
VertexVector triangles = startingTriangles;
if (0 != (triangles.size() % 3)) {
throw std::runtime_error("Bad number of vertices for tesselation");
}
@ -173,11 +178,13 @@ VVertex tesselate(const VVertex& startingTriangles, int count) {
triangles[i] = glm::normalize(triangles[i]);
}
VVertex newTriangles;
VertexVector newTriangles;
while (count) {
newTriangles.clear();
newTriangles.reserve(triangles.size() * 4);
for (size_t i = 0; i < triangles.size(); i += 3) {
// Tesselation takes one triangle and makes it into 4 triangles
// See https://en.wikipedia.org/wiki/Space-filling_tree#/media/File:Space_Filling_Tree_Tri_iter_1_2_3.png
newTriangles.reserve(triangles.size() * TESSELTATION_MULTIPLIER);
for (size_t i = 0; i < triangles.size(); i += VERTICES_PER_TRIANGLE) {
const vec3& a = triangles[i];
const vec3& b = triangles[i + 1];
const vec3& c = triangles[i + 2];
@ -221,7 +228,7 @@ void GeometryCache::buildShapes() {
startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
{
ShapeData& shapeData = _shapes[Cube];
VVertex vertices;
VertexVector vertices;
// front
vertices.push_back(vec3(1, 1, 1));
vertices.push_back(vec3(0, 0, 1));
@ -282,14 +289,21 @@ void GeometryCache::buildShapes() {
vertices.push_back(vec3(1, 1, -1));
vertices.push_back(vec3(0, 0, -1));
static const size_t VERTEX_FORMAT_SIZE = 2;
static const size_t VERTEX_OFFSET = 0;
static const size_t NORMAL_OFFSET = 1;
for (size_t i = 0; i < vertices.size(); ++i) {
if (0 == i % 2) {
vertices[i] *= 0.5f;
auto vertexIndex = i;
// Make a unit cube by having the vertices (at index N)
// while leaving the normals (at index N + 1) alone
if (VERTEX_OFFSET == vertexIndex % VERTEX_FORMAT_SIZE) {
vertices[vertexIndex] *= 0.5f;
}
}
shapeData.setupVertices(_shapeVertices, vertices);
VIndex indices{
IndexVector indices{
0, 1, 2, 2, 3, 0, // front
4, 5, 6, 6, 7, 4, // right
8, 9, 10, 10, 11, 8, // top
@ -297,11 +311,11 @@ void GeometryCache::buildShapes() {
16, 17, 18, 18, 19, 16, // bottom
20, 21, 22, 22, 23, 20 // back
};
for (int i = 0; i < indices.size(); ++i) {
indices[i] += startingIndex;
for (auto& index : indices) {
index += startingIndex;
}
VIndex wireIndices{
IndexVector wireIndices{
0, 1, 1, 2, 2, 3, 3, 0, // front
20, 21, 21, 22, 22, 23, 23, 20, // back
0, 23, 1, 22, 2, 21, 3, 20 // sides
@ -318,33 +332,41 @@ void GeometryCache::buildShapes() {
{
ShapeData& shapeData = _shapes[Tetrahedron];
size_t vertexCount = 4;
VVertex vertices;
VertexVector vertices;
{
VVertex originalVertices = tetrahedronVertices();
VertexVector originalVertices = tetrahedronVertices();
vertexCount = originalVertices.size();
vertices.reserve(originalVertices.size() * 2);
for (size_t i = 0; i < originalVertices.size(); i += 3) {
vertices.reserve(originalVertices.size() * VECTOR_TO_VECTOR_WITH_NORMAL_MULTIPLER);
for (size_t i = 0; i < originalVertices.size(); i += VERTICES_PER_TRIANGLE) {
auto triangleStartIndex = i;
vec3 faceNormal;
for (size_t j = 0; j < 3; ++j) {
faceNormal += originalVertices[i + j];
for (size_t j = 0; j < VERTICES_PER_TRIANGLE; ++j) {
auto triangleVertexIndex = j;
auto vertexIndex = triangleStartIndex + triangleVertexIndex;
faceNormal += originalVertices[vertexIndex];
}
faceNormal = glm::normalize(faceNormal);
for (size_t j = 0; j < 3; ++j) {
vertices.push_back(glm::normalize(originalVertices[i + j]));
for (size_t j = 0; j < VERTICES_PER_TRIANGLE; ++j) {
auto triangleVertexIndex = j;
auto vertexIndex = triangleStartIndex + triangleVertexIndex;
vertices.push_back(glm::normalize(originalVertices[vertexIndex]));
vertices.push_back(faceNormal);
}
}
}
shapeData.setupVertices(_shapeVertices, vertices);
VIndex indices;
for (size_t i = 0; i < vertexCount; i += 3) {
for (size_t j = 0; j < 3; ++j) {
indices.push_back(i + j + startingIndex);
IndexVector indices;
for (size_t i = 0; i < vertexCount; i += VERTICES_PER_TRIANGLE) {
auto triangleStartIndex = i;
for (size_t j = 0; j < VERTICES_PER_TRIANGLE; ++j) {
auto triangleVertexIndex = j;
auto vertexIndex = triangleStartIndex + triangleVertexIndex;
indices.push_back(vertexIndex + startingIndex);
}
}
VIndex wireIndices{
IndexVector wireIndices{
0, 1, 1, 2, 2, 0,
0, 3, 1, 3, 2, 3,
};
@ -362,16 +384,21 @@ void GeometryCache::buildShapes() {
startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
{
ShapeData& shapeData = _shapes[Sphere];
VVertex vertices;
VIndex indices;
VertexVector vertices;
IndexVector indices;
{
VVertex originalVertices = tesselate(icosahedronVertices(), 3);
vertices.reserve(originalVertices.size() * 2);
for (size_t i = 0; i < originalVertices.size(); i += 3) {
for (int j = 0; j < 3; ++j) {
vertices.push_back(originalVertices[i + j]);
vertices.push_back(originalVertices[i + j]);
indices.push_back(i + j + startingIndex);
VertexVector originalVertices = tesselate(icosahedronVertices(), ICOSAHEDRON_TO_SPHERE_TESSELATION_COUNT);
vertices.reserve(originalVertices.size() * VECTOR_TO_VECTOR_WITH_NORMAL_MULTIPLER);
for (size_t i = 0; i < originalVertices.size(); i += VERTICES_PER_TRIANGLE) {
auto triangleStartIndex = i;
for (int j = 0; j < VERTICES_PER_TRIANGLE; ++j) {
auto triangleVertexIndex = j;
auto vertexIndex = triangleStartIndex + triangleVertexIndex;
const auto& vertex = originalVertices[i + j];
// Spheres use the same values for vertices and normals
vertices.push_back(vertex);
vertices.push_back(vertex);
indices.push_back(vertexIndex + startingIndex);
}
}
}
@ -386,21 +413,26 @@ void GeometryCache::buildShapes() {
{
ShapeData& shapeData = _shapes[Icosahedron];
VVertex vertices;
VIndex indices;
VertexVector vertices;
IndexVector indices;
{
const VVertex& originalVertices = icosahedronVertices();
vertices.reserve(originalVertices.size() * 2);
const VertexVector& originalVertices = icosahedronVertices();
vertices.reserve(originalVertices.size() * VECTOR_TO_VECTOR_WITH_NORMAL_MULTIPLER);
for (size_t i = 0; i < originalVertices.size(); i += 3) {
auto triangleStartIndex = i;
vec3 faceNormal;
for (size_t j = 0; j < 3; ++j) {
faceNormal += originalVertices[i + j];
for (int j = 0; j < VERTICES_PER_TRIANGLE; ++j) {
auto triangleVertexIndex = j;
auto vertexIndex = triangleStartIndex + triangleVertexIndex;
faceNormal += originalVertices[vertexIndex];
}
faceNormal = glm::normalize(faceNormal);
for (int j = 0; j < 3; ++j) {
vertices.push_back(glm::normalize(originalVertices[i + j]));
for (int j = 0; j < VERTICES_PER_TRIANGLE; ++j) {
auto triangleVertexIndex = j;
auto vertexIndex = triangleStartIndex + triangleVertexIndex;
vertices.push_back(glm::normalize(originalVertices[vertexIndex]));
vertices.push_back(faceNormal);
indices.push_back(i + j + startingIndex);
indices.push_back(vertexIndex + startingIndex);
}
}
}
@ -410,6 +442,24 @@ void GeometryCache::buildShapes() {
shapeData.setupIndices(_shapeIndices, indices, indices);
}
// Line
startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
{
ShapeData& shapeData = _shapes[Line];
shapeData.setupVertices(_shapeVertices, VertexVector{
vec3(-0.5, 0, 0), vec3(-0.5f, 0, 0),
vec3(0.5f, 0, 0), vec3(0.5f, 0, 0)
});
IndexVector wireIndices;
// Only two indices
wireIndices.push_back(0 + startingIndex);
wireIndices.push_back(1 + startingIndex);
shapeData.setupIndices(_shapeIndices, IndexVector(), wireIndices);
}
// Not implememented yet:
//Triangle,
//Quad,
//Circle,
@ -418,20 +468,6 @@ void GeometryCache::buildShapes() {
//Torus,
//Cone,
//Cylinder,
// Line
startingIndex = _shapeVertices->getSize() / SHAPE_VERTEX_STRIDE;
{
ShapeData& shapeData = _shapes[Line];
shapeData.setupVertices(_shapeVertices, VVertex{
vec3(-0.5, 0, 0), vec3(-0.5, 0, 0),
vec3(0.5f, 0, 0), vec3(0.5f, 0, 0)
});
VIndex wireIndices;
wireIndices.push_back(0 + startingIndex);
wireIndices.push_back(1 + startingIndex);
shapeData.setupIndices(_shapeIndices, VIndex(), wireIndices);
}
}
gpu::Stream::FormatPointer& getSolidStreamFormat() {
@ -1092,11 +1128,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
}
//void GeometryCache::renderUnitCube(gpu::Batch& batch) {
// static const glm::vec4 color(1);
// renderSolidCube(batch, 1, color);
//}
void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id) {
static const glm::vec2 topLeft(-1, 1);
static const glm::vec2 bottomRight(1, -1);
@ -2015,29 +2046,54 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
// otherwise, at least the cluster indices/weights can be static
networkMesh->_vertexStream = std::make_shared<gpu::BufferStream>();
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, 0, sizeof(glm::vec3));
if (mesh.normals.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, normalsOffset, sizeof(glm::vec3));
if (mesh.tangents.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, tangentsOffset, sizeof(glm::vec3));
if (mesh.colors.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, colorsOffset, sizeof(glm::vec3));
if (mesh.texCoords.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoordsOffset, sizeof(glm::vec2));
if (mesh.texCoords1.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoords1Offset, sizeof(glm::vec2));
if (mesh.clusterIndices.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4));
if (mesh.clusterWeights.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4));
if (mesh.normals.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, normalsOffset, sizeof(glm::vec3));
}
if (mesh.tangents.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, tangentsOffset, sizeof(glm::vec3));
}
if (mesh.colors.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, colorsOffset, sizeof(glm::vec3));
}
if (mesh.texCoords.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoordsOffset, sizeof(glm::vec2));
}
if (mesh.texCoords1.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoords1Offset, sizeof(glm::vec2));
}
if (mesh.clusterIndices.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4));
}
if (mesh.clusterWeights.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4));
}
int channelNum = 0;
networkMesh->_vertexFormat = std::make_shared<gpu::Stream::Format>();
networkMesh->_vertexFormat->setAttribute(gpu::Stream::POSITION, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
if (mesh.normals.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::NORMAL, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
if (mesh.texCoords.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
if (mesh.normals.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::NORMAL, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
}
if (mesh.tangents.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
}
if (mesh.colors.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
}
if (mesh.texCoords.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
}
if (mesh.texCoords1.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
} else if (checkForTexcoordLightmap && mesh.texCoords.size()) {
// need lightmap texcoord UV but doesn't have uv#1 so just reuse the same channel
networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum - 1, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
}
if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
if (mesh.clusterIndices.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
}
if (mesh.clusterWeights.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
}
}
else {
int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);
@ -2056,21 +2112,43 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData());
networkMesh->_vertexStream = std::make_shared<gpu::BufferStream>();
if (mesh.tangents.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, 0, sizeof(glm::vec3));
if (mesh.colors.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, colorsOffset, sizeof(glm::vec3));
if (mesh.texCoords.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoordsOffset, sizeof(glm::vec2));
if (mesh.clusterIndices.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4));
if (mesh.clusterWeights.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4));
if (mesh.tangents.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, 0, sizeof(glm::vec3));
}
if (mesh.colors.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, colorsOffset, sizeof(glm::vec3));
}
if (mesh.texCoords.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoordsOffset, sizeof(glm::vec2));
}
if (mesh.clusterIndices.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4));
}
if (mesh.clusterWeights.size()) {
networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4));
}
int channelNum = 0;
networkMesh->_vertexFormat = std::make_shared<gpu::Stream::Format>();
networkMesh->_vertexFormat->setAttribute(gpu::Stream::POSITION, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
if (mesh.normals.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::NORMAL, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
if (mesh.texCoords.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
if (mesh.normals.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::NORMAL, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
}
if (mesh.tangents.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
}
if (mesh.colors.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB));
}
if (mesh.texCoords.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
}
if (mesh.clusterIndices.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
}
if (mesh.clusterWeights.size()) {
networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW));
}
}
}

View file

@ -121,8 +121,8 @@ inline uint qHash(const Vec4PairVec4Pair& v, uint seed) {
seed);
}
using VVertex = std::vector<glm::vec3>;
using VIndex = std::vector<uint16_t>;
using VertexVector = std::vector<glm::vec3>;
using IndexVector = std::vector<uint16_t>;
/// Stores cached geometry.
class GeometryCache : public ResourceCache, public Dependency {
@ -262,8 +262,8 @@ private:
gpu::BufferView _normalView;
gpu::BufferPointer _indices;
void setupVertices(gpu::BufferPointer& vertexBuffer, const VVertex& vertices);
void setupIndices(gpu::BufferPointer& indexBuffer, const VIndex& indices, const VIndex& wireIndices);
void setupVertices(gpu::BufferPointer& vertexBuffer, const VertexVector& vertices);
void setupIndices(gpu::BufferPointer& indexBuffer, const IndexVector& indices, const IndexVector& wireIndices);
void setupBatch(gpu::Batch& batch) const;
void draw(gpu::Batch& batch) const;
void drawWire(gpu::Batch& batch) const;