Merge remote-tracking branch 'upstream/master' into core

Conflicts:
	interface/src/ui/overlays/Circle3DOverlay.cpp
	libraries/gpu/src/gpu/Format.h
	libraries/render-utils/src/GeometryCache.cpp
	libraries/render-utils/src/Model.cpp
	libraries/render-utils/src/text/Font.cpp
This commit is contained in:
Brad Davis 2015-08-01 20:01:59 -07:00
commit 180f912924
10 changed files with 122 additions and 36 deletions

View file

@ -23,7 +23,7 @@ var RAD_TO_DEG = 180.0 / PI;
var AZIMUTH_RATE = 90.0;
var ALTITUDE_RATE = 200.0;
var RADIUS_RATE = 1.0 / 100.0;
var PAN_RATE = 50.0;
var PAN_RATE = 250.0;
var Y_AXIS = {
x: 0,
@ -139,7 +139,7 @@ function handlePanMode(dx, dy) {
var right = Quat.getRight(Camera.getOrientation());
var distance = Vec3.length(vector);
var dv = Vec3.sum(Vec3.multiply(up, -distance * dy / PAN_RATE), Vec3.multiply(right, distance * dx / PAN_RATE));
var dv = Vec3.sum(Vec3.multiply(up, distance * dy / PAN_RATE), Vec3.multiply(right, -distance * dx / PAN_RATE));
center = Vec3.sum(center, dv);
position = Vec3.sum(position, dv);

View file

@ -119,19 +119,21 @@ void Circle3DOverlay::render(RenderArgs* args) {
float angle = startAt;
float angleInRadians = glm::radians(angle);
glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
points << firstInnerPoint << firstOuterPoint;
glm::vec2 mostRecentInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 mostRecentOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
while (angle < endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
points << thisOuterPoint << thisInnerPoint;
points << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle
points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle
angle += SLICE_ANGLE;
mostRecentInnerPoint = thisInnerPoint;
mostRecentOuterPoint = thisOuterPoint;
}
// get the last slice portion....
@ -139,14 +141,14 @@ void Circle3DOverlay::render(RenderArgs* args) {
angleInRadians = glm::radians(angle);
glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
points << lastOuterPoint << lastInnerPoint;
points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle
points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle
geometryCache->updateVertices(_quadVerticesID, points, color);
}
// FIXME CORE
// geometryCache->renderVertices(batch, gpu::QUAD_STRIP, _quadVerticesID);
geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID);
} else {
if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {

View file

@ -830,6 +830,56 @@ public:
std::vector<AttributeData> attributes;
};
gpu::BufferPointer FBXMeshPart::getTrianglesForQuads() const {
// if we've been asked for our triangulation of the original quads, but we don't yet have them
// then create them now.
if (!trianglesForQuadsAvailable) {
trianglesForQuadsAvailable = true;
quadsAsTrianglesIndicesBuffer = std::make_shared<gpu::Buffer>();
// QVector<int> quadIndices; // original indices from the FBX mesh
QVector<quint32> quadsAsTrianglesIndices; // triangle versions of quads converted when first needed
const int INDICES_PER_ORIGINAL_QUAD = 4;
const int INDICES_PER_TRIANGULATED_QUAD = 6;
int numberOfQuads = quadIndices.size() / INDICES_PER_ORIGINAL_QUAD;
quadsAsTrianglesIndices.resize(numberOfQuads * INDICES_PER_TRIANGULATED_QUAD);
int originalIndex = 0;
int triangulatedIndex = 0;
for (int fromQuad = 0; fromQuad < numberOfQuads; fromQuad++) {
int i0 = quadIndices[originalIndex + 0];
int i1 = quadIndices[originalIndex + 1];
int i2 = quadIndices[originalIndex + 2];
int i3 = quadIndices[originalIndex + 3];
// Sam's recommended triangle slices
// Triangle tri1 = { v0, v1, v3 };
// Triangle tri2 = { v1, v2, v3 };
// NOTE: Random guy on the internet's recommended triangle slices
// Triangle tri1 = { v0, v1, v2 };
// Triangle tri2 = { v2, v3, v0 };
quadsAsTrianglesIndices[triangulatedIndex + 0] = i0;
quadsAsTrianglesIndices[triangulatedIndex + 1] = i1;
quadsAsTrianglesIndices[triangulatedIndex + 2] = i3;
quadsAsTrianglesIndices[triangulatedIndex + 3] = i1;
quadsAsTrianglesIndices[triangulatedIndex + 4] = i2;
quadsAsTrianglesIndices[triangulatedIndex + 5] = i3;
originalIndex += INDICES_PER_ORIGINAL_QUAD;
triangulatedIndex += INDICES_PER_TRIANGULATED_QUAD;
}
trianglesForQuadsIndicesCount = INDICES_PER_TRIANGULATED_QUAD * numberOfQuads;
quadsAsTrianglesIndicesBuffer->append(quadsAsTrianglesIndices.size() * sizeof(quint32), (gpu::Byte*)quadsAsTrianglesIndices.data());
}
return quadsAsTrianglesIndicesBuffer;
}
void appendIndex(MeshData& data, QVector<int>& indices, int index) {
if (index >= data.polygonIndices.size()) {
return;
@ -1089,7 +1139,6 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
appendIndex(data, part.quadIndices, beginIndex++);
appendIndex(data, part.quadIndices, beginIndex++);
appendIndex(data, part.quadIndices, beginIndex++);
} else {
for (int nextIndex = beginIndex + 1;; ) {
appendIndex(data, part.triangleIndices, beginIndex);

View file

@ -109,9 +109,10 @@ public:
class FBXMeshPart {
public:
QVector<int> quadIndices;
QVector<int> triangleIndices;
QVector<int> quadIndices; // original indices from the FBX mesh
QVector<int> triangleIndices; // original indices from the FBX mesh
mutable gpu::BufferPointer quadsAsTrianglesIndicesBuffer;
glm::vec3 diffuseColor;
glm::vec3 specularColor;
glm::vec3 emissiveColor;
@ -126,6 +127,10 @@ public:
QString materialID;
model::MaterialPointer _material;
mutable bool trianglesForQuadsAvailable = false;
mutable int trianglesForQuadsIndicesCount = 0;
gpu::BufferPointer getTrianglesForQuads() const;
};
/// A single mesh (with optional blendshapes) extracted from an FBX document.

View file

@ -213,7 +213,6 @@ enum Primitive {
TRIANGLES,
TRIANGLE_STRIP,
TRIANGLE_FAN,
NUM_PRIMITIVES,
};

View file

@ -71,7 +71,7 @@ public:
LINE_STRIP,
TRIANGLES,
TRIANGLE_STRIP,
QUADS,
QUADS, // NOTE: These must be translated to triangles before rendering
QUAD_STRIP,
NUM_TOPOLOGIES,

View file

@ -1012,12 +1012,12 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
}
const int FLOATS_PER_VERTEX = 2; // vertices
const int vertices = 4;
const int VERTICES = 4; // 1 quad = 4 vertices
if (!details.isCreated) {
details.isCreated = true;
details.vertices = vertices;
details.vertices = VERTICES;
details.vertexSize = FLOATS_PER_VERTEX;
auto verticesBuffer = std::make_shared<gpu::Buffer>();
@ -1037,7 +1037,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
minCorner.x, minCorner.y,
maxCorner.x, minCorner.y,
minCorner.x, maxCorner.y,
@ -1051,7 +1051,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
}
@ -1103,23 +1102,25 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
}
const int FLOATS_PER_VERTEX = 2 * 2; // text coords & vertices
const int vertices = 4;
const int VERTICES = 4; // 1 quad = 4 vertices
const int NUM_POS_COORDS = 2;
const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float);
if (!details.isCreated) {
details.isCreated = true;
details.vertices = vertices;
details.vertices = VERTICES;
details.vertexSize = FLOATS_PER_VERTEX;
auto verticesBuffer = std::make_shared<gpu::Buffer>();
auto colorBuffer = std::make_shared<gpu::Buffer>();
auto streamFormat = std::make_shared<gpu::Stream::Format>();
auto stream = std::make_shared<gpu::BufferStream>();
details.verticesBuffer = verticesBuffer;
details.colorBuffer = colorBuffer;
details.streamFormat = streamFormat;
details.stream = stream;
@ -1131,7 +1132,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
minCorner.x, minCorner.y, texCoordMinCorner.x, texCoordMinCorner.y,
maxCorner.x, minCorner.y, texCoordMaxCorner.x, texCoordMinCorner.y,
minCorner.x, maxCorner.y, texCoordMinCorner.x, texCoordMaxCorner.y,
@ -1146,7 +1147,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
}
@ -1179,21 +1179,23 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
}
const int FLOATS_PER_VERTEX = 3; // vertices
const int vertices = 4;
const int VERTICES = 4; // 1 quad = 4 vertices
if (!details.isCreated) {
details.isCreated = true;
details.vertices = vertices;
details.vertices = VERTICES;
details.vertexSize = FLOATS_PER_VERTEX;
auto verticesBuffer = std::make_shared<gpu::Buffer>();
auto colorBuffer = std::make_shared<gpu::Buffer>();
auto streamFormat = std::make_shared<gpu::Stream::Format>();
auto stream = std::make_shared<gpu::BufferStream>();
details.verticesBuffer = verticesBuffer;
details.colorBuffer = colorBuffer;
details.streamFormat = streamFormat;
details.stream = stream;
@ -1204,7 +1206,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
minCorner.x, minCorner.y, minCorner.z,
maxCorner.x, minCorner.y, minCorner.z,
minCorner.x, maxCorner.y, maxCorner.z,
@ -1218,7 +1220,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
}
@ -1270,14 +1271,14 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
}
const int FLOATS_PER_VERTEX = 3 + 2; // 3d vertices + text coords
const int vertices = 4;
const int VERTICES = 4; // 1 quad = 4 vertices
const int NUM_POS_COORDS = 3;
const int VERTEX_TEXCOORD_OFFSET = NUM_POS_COORDS * sizeof(float);
if (!details.isCreated) {
details.isCreated = true;
details.vertices = vertices;
details.vertices = VERTICES;
details.vertexSize = FLOATS_PER_VERTEX; // NOTE: this isn't used for BatchItemDetails maybe we can get rid of it
auto verticesBuffer = std::make_shared<gpu::Buffer>();
@ -1298,7 +1299,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
float vertexBuffer[VERTICES * FLOATS_PER_VERTEX] = {
bottomLeft.x, bottomLeft.y, bottomLeft.z, texCoordBottomLeft.x, texCoordBottomLeft.y,
bottomRight.x, bottomRight.y, bottomRight.z, texCoordBottomRight.x, texCoordBottomRight.y,
topLeft.x, topLeft.y, topLeft.z, texCoordTopLeft.x, texCoordTopLeft.y,

View file

@ -2096,9 +2096,11 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
}
if (part.quadIndices.size() > 0) {
// FIXME CORE
// batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset);
batch.setIndexBuffer(gpu::UINT32, part.getTrianglesForQuads(), 0);
batch.drawIndexed(gpu::TRIANGLES, part.trianglesForQuadsIndicesCount, 0);
offset += part.quadIndices.size() * sizeof(int);
batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); // restore this in case there are triangles too
}
if (part.triangleIndices.size() > 0) {

View file

@ -18,8 +18,12 @@ struct TextureVertex {
TextureVertex(const glm::vec2& pos, const glm::vec2& tex) : pos(pos), tex(tex) {}
};
static const int NUMBER_OF_INDICES_PER_QUAD = 6; // 1 quad = 2 triangles
static const int VERTICES_PER_QUAD = 4; // 1 quad = 4 vertices
struct QuadBuilder {
TextureVertex vertices[4];
TextureVertex vertices[VERTICES_PER_QUAD];
QuadBuilder(const glm::vec2& min, const glm::vec2& size,
const glm::vec2& texMin, const glm::vec2& texSize) {
// min = bottomLeft
@ -249,6 +253,9 @@ void Font::setupGPU() {
void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds) {
_verticesBuffer = std::make_shared<gpu::Buffer>();
_numVertices = 0;
_indicesBuffer = std::make_shared<gpu::Buffer>();
_numIndices = 0;
_lastStringRendered = str;
_lastBounds = bounds;
@ -284,10 +291,28 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2
if (!isNewLine) {
for (auto c : token) {
auto glyph = _glyphs[c];
quint16 verticesOffset = _numVertices;
QuadBuilder qd(glyph, advance - glm::vec2(0.0f, _ascent));
_verticesBuffer->append(sizeof(QuadBuilder), (const gpu::Byte*)&qd);
_numVertices += 4;
// Sam's recommended triangle slices
// Triangle tri1 = { v0, v1, v3 };
// Triangle tri2 = { v1, v2, v3 };
// NOTE: Random guy on the internet's recommended triangle slices
// Triangle tri1 = { v0, v1, v2 };
// Triangle tri2 = { v2, v3, v0 };
quint16 indices[NUMBER_OF_INDICES_PER_QUAD];
indices[0] = verticesOffset + 0;
indices[1] = verticesOffset + 1;
indices[2] = verticesOffset + 3;
indices[3] = verticesOffset + 1;
indices[4] = verticesOffset + 2;
indices[5] = verticesOffset + 3;
_indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices);
_numIndices += NUMBER_OF_INDICES_PER_QUAD;
// Advance by glyph size
advance.x += glyph.d;
@ -318,5 +343,6 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c
batch.setInputFormat(_format);
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
batch.setIndexBuffer(gpu::UINT16, _indicesBuffer, 0);
batch.drawIndexed(gpu::TRIANGLES, _numIndices, 0);
}

View file

@ -64,8 +64,10 @@ private:
gpu::TexturePointer _texture;
gpu::Stream::FormatPointer _format;
gpu::BufferPointer _verticesBuffer;
gpu::BufferPointer _indicesBuffer;
gpu::BufferStreamPointer _stream;
unsigned int _numVertices = 0;
unsigned int _numIndices = 0;
int _fontLoc = -1;
int _outlineLoc = -1;