mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 19:29:47 +02:00
Merge pull request #6871 from Atlante45/feat/draw-call-info
Unify normal and named draw paths
This commit is contained in:
commit
1b52d700a0
29 changed files with 482 additions and 388 deletions
|
@ -96,26 +96,31 @@ void renderWorldBox(gpu::Batch& batch) {
|
||||||
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY);
|
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY);
|
||||||
|
|
||||||
|
|
||||||
geometryCache->renderWireCubeInstance(batch, Transform(), GREY4);
|
geometryCache->renderWireCubeInstance(batch, GREY4);
|
||||||
|
|
||||||
// Draw meter markers along the 3 axis to help with measuring things
|
// Draw meter markers along the 3 axis to help with measuring things
|
||||||
const float MARKER_DISTANCE = 1.0f;
|
const float MARKER_DISTANCE = 1.0f;
|
||||||
const float MARKER_RADIUS = 0.05f;
|
const float MARKER_RADIUS = 0.05f;
|
||||||
|
|
||||||
transform = Transform().setScale(MARKER_RADIUS);
|
transform = Transform().setScale(MARKER_RADIUS);
|
||||||
geometryCache->renderSolidSphereInstance(batch, transform, RED);
|
batch.setModelTransform(transform);
|
||||||
|
geometryCache->renderSolidSphereInstance(batch, RED);
|
||||||
|
|
||||||
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS);
|
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS);
|
||||||
geometryCache->renderSolidSphereInstance(batch, transform, RED);
|
batch.setModelTransform(transform);
|
||||||
|
geometryCache->renderSolidSphereInstance(batch, RED);
|
||||||
|
|
||||||
transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS);
|
transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS);
|
||||||
geometryCache->renderSolidSphereInstance(batch, transform, GREEN);
|
batch.setModelTransform(transform);
|
||||||
|
geometryCache->renderSolidSphereInstance(batch, GREEN);
|
||||||
|
|
||||||
transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
|
transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
|
||||||
geometryCache->renderSolidSphereInstance(batch, transform, BLUE);
|
batch.setModelTransform(transform);
|
||||||
|
geometryCache->renderSolidSphereInstance(batch, BLUE);
|
||||||
|
|
||||||
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
|
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
|
||||||
geometryCache->renderSolidSphereInstance(batch, transform, GREY);
|
batch.setModelTransform(transform);
|
||||||
|
geometryCache->renderSolidSphereInstance(batch, GREY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a random vector of average length 1
|
// Return a random vector of average length 1
|
||||||
|
|
|
@ -456,7 +456,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
Transform transform;
|
Transform transform;
|
||||||
transform.setTranslation(position);
|
transform.setTranslation(position);
|
||||||
transform.postScale(INDICATOR_RADIUS);
|
transform.postScale(INDICATOR_RADIUS);
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, transform, LOOK_AT_INDICATOR_COLOR);
|
batch.setModelTransform(transform);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, LOOK_AT_INDICATOR_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the avatar is looking at me, indicate that they are
|
// If the avatar is looking at me, indicate that they are
|
||||||
|
@ -484,8 +485,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
eyeDiameter = DEFAULT_EYE_DIAMETER;
|
eyeDiameter = DEFAULT_EYE_DIAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch.setModelTransform(Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT));
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch,
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch,
|
||||||
Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT),
|
|
||||||
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
||||||
|
|
||||||
position = getHead()->getRightEyePosition();
|
position = getHead()->getRightEyePosition();
|
||||||
|
@ -494,8 +495,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
if (eyeDiameter == 0.0f) {
|
if (eyeDiameter == 0.0f) {
|
||||||
eyeDiameter = DEFAULT_EYE_DIAMETER;
|
eyeDiameter = DEFAULT_EYE_DIAMETER;
|
||||||
}
|
}
|
||||||
|
batch.setModelTransform(Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT));
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch,
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch,
|
||||||
Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT),
|
|
||||||
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
glm::vec4(LOOKING_AT_ME_COLOR, alpha));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,8 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
transform.setTranslation(position);
|
transform.setTranslation(position);
|
||||||
transform.setRotation(palm.getRotation());
|
transform.setRotation(palm.getRotation());
|
||||||
transform.postScale(SPHERE_RADIUS);
|
transform.postScale(SPHERE_RADIUS);
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, transform, grayColor);
|
batch.setModelTransform(transform);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, grayColor);
|
||||||
|
|
||||||
// draw a green sphere at the old "finger tip"
|
// draw a green sphere at the old "finger tip"
|
||||||
transform = Transform();
|
transform = Transform();
|
||||||
|
@ -68,7 +69,8 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
transform.setTranslation(position);
|
transform.setTranslation(position);
|
||||||
transform.setRotation(palm.getRotation());
|
transform.setRotation(palm.getRotation());
|
||||||
transform.postScale(SPHERE_RADIUS);
|
transform.postScale(SPHERE_RADIUS);
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, transform, greenColor);
|
batch.setModelTransform(transform);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, greenColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -467,5 +467,6 @@ void Head::renderLookatTarget(RenderArgs* renderArgs, glm::vec3 lookatPosition)
|
||||||
const float LOOK_AT_TARGET_RADIUS = 0.075f;
|
const float LOOK_AT_TARGET_RADIUS = 0.075f;
|
||||||
transform.postScale(LOOK_AT_TARGET_RADIUS);
|
transform.postScale(LOOK_AT_TARGET_RADIUS);
|
||||||
const glm::vec4 LOOK_AT_TARGET_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f };
|
const glm::vec4 LOOK_AT_TARGET_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f };
|
||||||
geometryCache->renderSolidSphereInstance(batch, transform, LOOK_AT_TARGET_COLOR);
|
batch.setModelTransform(transform);
|
||||||
|
geometryCache->renderSolidSphereInstance(batch, LOOK_AT_TARGET_COLOR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,17 +349,15 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float scale
|
||||||
// draw a blue sphere at the capsule top point
|
// draw a blue sphere at the capsule top point
|
||||||
glm::vec3 topPoint = _translation + getRotation() * (scale * (_boundingCapsuleLocalOffset + (0.5f * _boundingCapsuleHeight) * Vectors::UNIT_Y));
|
glm::vec3 topPoint = _translation + getRotation() * (scale * (_boundingCapsuleLocalOffset + (0.5f * _boundingCapsuleHeight) * Vectors::UNIT_Y));
|
||||||
|
|
||||||
geometryCache->renderSolidSphereInstance(batch,
|
batch.setModelTransform(Transform().setTranslation(topPoint).postScale(scale * _boundingCapsuleRadius));
|
||||||
Transform().setTranslation(topPoint).postScale(scale * _boundingCapsuleRadius),
|
geometryCache->renderSolidSphereInstance(batch, glm::vec4(0.6f, 0.6f, 0.8f, alpha));
|
||||||
glm::vec4(0.6f, 0.6f, 0.8f, alpha));
|
|
||||||
|
|
||||||
// draw a yellow sphere at the capsule bottom point
|
// draw a yellow sphere at the capsule bottom point
|
||||||
glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, scale * _boundingCapsuleHeight, 0.0f);
|
glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, scale * _boundingCapsuleHeight, 0.0f);
|
||||||
glm::vec3 axis = topPoint - bottomPoint;
|
glm::vec3 axis = topPoint - bottomPoint;
|
||||||
|
|
||||||
geometryCache->renderSolidSphereInstance(batch,
|
batch.setModelTransform(Transform().setTranslation(bottomPoint).postScale(scale * _boundingCapsuleRadius));
|
||||||
Transform().setTranslation(bottomPoint).postScale(scale * _boundingCapsuleRadius),
|
geometryCache->renderSolidSphereInstance(batch, glm::vec4(0.8f, 0.8f, 0.6f, alpha));
|
||||||
glm::vec4(0.8f, 0.8f, 0.6f, alpha));
|
|
||||||
|
|
||||||
// draw a green cylinder between the two points
|
// draw a green cylinder between the two points
|
||||||
glm::vec3 origin(0.0f);
|
glm::vec3 origin(0.0f);
|
||||||
|
|
|
@ -60,7 +60,8 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
transform.setScale(dimensions);
|
transform.setScale(dimensions);
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidCubeInstance(*batch, transform, cubeColor);
|
batch->setModelTransform(transform);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderSolidCubeInstance(*batch, cubeColor);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
|
@ -96,9 +97,9 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
||||||
geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor);
|
geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
batch->setModelTransform(Transform());
|
|
||||||
transform.setScale(dimensions);
|
transform.setScale(dimensions);
|
||||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(*batch, transform, cubeColor);
|
batch->setModelTransform(transform);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(*batch, cubeColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,13 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
|
|
||||||
if (batch) {
|
if (batch) {
|
||||||
batch->setModelTransform(Transform());
|
|
||||||
|
|
||||||
Transform transform = _transform;
|
Transform transform = _transform;
|
||||||
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
||||||
|
batch->setModelTransform(transform);
|
||||||
if (_isSolid) {
|
if (_isSolid) {
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(*batch, transform, sphereColor);
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(*batch, sphereColor);
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<GeometryCache>()->renderWireSphereInstance(*batch, transform, sphereColor);
|
DependencyManager::get<GeometryCache>()->renderWireSphereInstance(*batch, sphereColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,14 +61,14 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_procedural->ready()) {
|
|
||||||
batch.setModelTransform(transToCenter); // we want to include the scale as well
|
batch.setModelTransform(transToCenter); // we want to include the scale as well
|
||||||
|
if (_procedural->ready()) {
|
||||||
_procedural->prepare(batch, getPosition(), getDimensions());
|
_procedural->prepare(batch, getPosition(), getDimensions());
|
||||||
auto color = _procedural->getColor(cubeColor);
|
auto color = _procedural->getColor(cubeColor);
|
||||||
batch._glColor4f(color.r, color.g, color.b, color.a);
|
batch._glColor4f(color.r, color.g, color.b, color.a);
|
||||||
DependencyManager::get<GeometryCache>()->renderCube(batch);
|
DependencyManager::get<GeometryCache>()->renderCube(batch);
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidCubeInstance(batch, transToCenter, cubeColor);
|
DependencyManager::get<GeometryCache>()->renderSolidCubeInstance(batch, cubeColor);
|
||||||
}
|
}
|
||||||
static const auto triCount = DependencyManager::get<GeometryCache>()->getCubeTriangleCount();
|
static const auto triCount = DependencyManager::get<GeometryCache>()->getCubeTriangleCount();
|
||||||
args->_details._trianglesRendered += (int)triCount;
|
args->_details._trianglesRendered += (int)triCount;
|
||||||
|
|
|
@ -440,8 +440,8 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
bool success;
|
bool success;
|
||||||
auto shapeTransform = getTransformToCenter(success);
|
auto shapeTransform = getTransformToCenter(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
batch.setModelTransform(Transform()); // we want to include the scale as well
|
batch.setModelTransform(shapeTransform); // we want to include the scale as well
|
||||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(batch, shapeTransform, greenColor);
|
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(batch, greenColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,15 +64,14 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||||
if (_procedural->ready()) {
|
|
||||||
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
|
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
|
||||||
|
if (_procedural->ready()) {
|
||||||
_procedural->prepare(batch, getPosition(), getDimensions());
|
_procedural->prepare(batch, getPosition(), getDimensions());
|
||||||
auto color = _procedural->getColor(sphereColor);
|
auto color = _procedural->getColor(sphereColor);
|
||||||
batch._glColor4f(color.r, color.g, color.b, color.a);
|
batch._glColor4f(color.r, color.g, color.b, color.a);
|
||||||
DependencyManager::get<GeometryCache>()->renderSphere(batch);
|
DependencyManager::get<GeometryCache>()->renderSphere(batch);
|
||||||
} else {
|
} else {
|
||||||
batch.setModelTransform(Transform());
|
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, sphereColor);
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidSphereInstance(batch, modelTransform, sphereColor);
|
|
||||||
}
|
}
|
||||||
static const auto triCount = DependencyManager::get<GeometryCache>()->getSphereTriangleCount();
|
static const auto triCount = DependencyManager::get<GeometryCache>()->getSphereTriangleCount();
|
||||||
args->_details._trianglesRendered += (int)triCount;
|
args->_details._trianglesRendered += (int)triCount;
|
||||||
|
|
|
@ -132,7 +132,6 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
batch.setModelTransform(Transform());
|
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
auto shapeTransform = getTransformToCenter(success);
|
auto shapeTransform = getTransformToCenter(success);
|
||||||
|
@ -142,9 +141,11 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||||
shapeTransform.postScale(SPHERE_ENTITY_SCALE);
|
shapeTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||||
geometryCache->renderWireSphereInstance(batch, shapeTransform, DEFAULT_COLOR);
|
batch.setModelTransform(shapeTransform);
|
||||||
|
geometryCache->renderWireSphereInstance(batch, DEFAULT_COLOR);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->renderWireCubeInstance(batch, shapeTransform, DEFAULT_COLOR);
|
batch.setModelTransform(shapeTransform);
|
||||||
|
geometryCache->renderWireCubeInstance(batch, DEFAULT_COLOR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef gpu__GPUConfig__
|
#ifndef hifi_gpu_GPUConfig_h
|
||||||
#define gpu__GPUConfig__
|
#define hifi_gpu_GPUConfig_h
|
||||||
|
|
||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES 1
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
|
@ -38,8 +38,6 @@
|
||||||
#define GPU_FEATURE_PROFILE GPU_CORE
|
#define GPU_FEATURE_PROFILE GPU_CORE
|
||||||
#define GPU_INPUT_PROFILE GPU_CORE_43
|
#define GPU_INPUT_PROFILE GPU_CORE_43
|
||||||
|
|
||||||
#elif defined(ANDROID)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
@ -50,4 +48,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
||||||
|
// Deactivate SSBO for now, we've run into some issues
|
||||||
|
// on GL 4.3 capable GPUs not behaving as expected
|
||||||
|
//#define GPU_SSBO_DRAW_CALL_INFO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_gpu_GPUConfig_h
|
||||||
|
|
|
@ -29,20 +29,6 @@ ProfileRangeBatch::~ProfileRangeBatch() {
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
Batch::Batch() :
|
|
||||||
_commands(),
|
|
||||||
_commandOffsets(),
|
|
||||||
_params(),
|
|
||||||
_data(),
|
|
||||||
_buffers(),
|
|
||||||
_textures(),
|
|
||||||
_streamFormats(),
|
|
||||||
_transforms(),
|
|
||||||
_pipelines(),
|
|
||||||
_framebuffers()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Batch::Batch(const CacheState& cacheState) : Batch() {
|
Batch::Batch(const CacheState& cacheState) : Batch() {
|
||||||
_commands.reserve(cacheState.commandsSize);
|
_commands.reserve(cacheState.commandsSize);
|
||||||
_commandOffsets.reserve(cacheState.offsetsSize);
|
_commandOffsets.reserve(cacheState.offsetsSize);
|
||||||
|
@ -88,6 +74,8 @@ void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex
|
||||||
_params.push_back(startVertex);
|
_params.push_back(startVertex);
|
||||||
_params.push_back(numVertices);
|
_params.push_back(numVertices);
|
||||||
_params.push_back(primitiveType);
|
_params.push_back(primitiveType);
|
||||||
|
|
||||||
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex) {
|
void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex) {
|
||||||
|
@ -96,6 +84,8 @@ void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 start
|
||||||
_params.push_back(startIndex);
|
_params.push_back(startIndex);
|
||||||
_params.push_back(numIndices);
|
_params.push_back(numIndices);
|
||||||
_params.push_back(primitiveType);
|
_params.push_back(primitiveType);
|
||||||
|
|
||||||
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex, uint32 startInstance) {
|
void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex, uint32 startInstance) {
|
||||||
|
@ -106,6 +96,8 @@ void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 n
|
||||||
_params.push_back(numVertices);
|
_params.push_back(numVertices);
|
||||||
_params.push_back(primitiveType);
|
_params.push_back(primitiveType);
|
||||||
_params.push_back(numInstances);
|
_params.push_back(numInstances);
|
||||||
|
|
||||||
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex, uint32 startInstance) {
|
void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex, uint32 startInstance) {
|
||||||
|
@ -116,6 +108,8 @@ void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, u
|
||||||
_params.push_back(numIndices);
|
_params.push_back(numIndices);
|
||||||
_params.push_back(primitiveType);
|
_params.push_back(primitiveType);
|
||||||
_params.push_back(numInstances);
|
_params.push_back(numInstances);
|
||||||
|
|
||||||
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,12 +117,16 @@ void Batch::multiDrawIndirect(uint32 numCommands, Primitive primitiveType) {
|
||||||
ADD_COMMAND(multiDrawIndirect);
|
ADD_COMMAND(multiDrawIndirect);
|
||||||
_params.push_back(numCommands);
|
_params.push_back(numCommands);
|
||||||
_params.push_back(primitiveType);
|
_params.push_back(primitiveType);
|
||||||
|
|
||||||
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType) {
|
void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType) {
|
||||||
ADD_COMMAND(multiDrawIndexedIndirect);
|
ADD_COMMAND(multiDrawIndexedIndirect);
|
||||||
_params.push_back(nbCommands);
|
_params.push_back(nbCommands);
|
||||||
_params.push_back(primitiveType);
|
_params.push_back(primitiveType);
|
||||||
|
|
||||||
|
captureDrawCallInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
||||||
|
@ -185,7 +183,8 @@ void Batch::setIndirectBuffer(const BufferPointer& buffer, Offset offset, Offset
|
||||||
void Batch::setModelTransform(const Transform& model) {
|
void Batch::setModelTransform(const Transform& model) {
|
||||||
ADD_COMMAND(setModelTransform);
|
ADD_COMMAND(setModelTransform);
|
||||||
|
|
||||||
_params.push_back(_transforms.cache(model));
|
_currentModel = model;
|
||||||
|
_invalidModel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setViewTransform(const Transform& view) {
|
void Batch::setViewTransform(const Transform& view) {
|
||||||
|
@ -344,6 +343,19 @@ void Batch::runLambda(std::function<void()> f) {
|
||||||
_params.push_back(_lambdas.cache(f));
|
_params.push_back(_lambdas.cache(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Batch::startNamedCall(const std::string& name) {
|
||||||
|
ADD_COMMAND(startNamedCall);
|
||||||
|
_params.push_back(_names.cache(name));
|
||||||
|
|
||||||
|
_currentNamedCall = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Batch::stopNamedCall() {
|
||||||
|
ADD_COMMAND(stopNamedCall);
|
||||||
|
|
||||||
|
_currentNamedCall.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void Batch::enableStereo(bool enable) {
|
void Batch::enableStereo(bool enable) {
|
||||||
_enableStereo = enable;
|
_enableStereo = enable;
|
||||||
}
|
}
|
||||||
|
@ -360,14 +372,13 @@ bool Batch::isSkyboxEnabled() const {
|
||||||
return _enableSkybox;
|
return _enableSkybox;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setupNamedCalls(const std::string& instanceName, size_t count, NamedBatchData::Function function) {
|
void Batch::setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function) {
|
||||||
NamedBatchData& instance = _namedData[instanceName];
|
NamedBatchData& instance = _namedData[instanceName];
|
||||||
instance.count += count;
|
if (!instance.function) {
|
||||||
instance.function = function;
|
instance.function = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function) {
|
captureNamedDrawCallInfo(instanceName);
|
||||||
setupNamedCalls(instanceName, 1, function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t index) {
|
BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t index) {
|
||||||
|
@ -376,16 +387,74 @@ BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t ind
|
||||||
instance.buffers.resize(index + 1);
|
instance.buffers.resize(index + 1);
|
||||||
}
|
}
|
||||||
if (!instance.buffers[index]) {
|
if (!instance.buffers[index]) {
|
||||||
instance.buffers[index].reset(new Buffer());
|
instance.buffers[index] = std::make_shared<Buffer>();
|
||||||
}
|
}
|
||||||
return instance.buffers[index];
|
return instance.buffers[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Batch::DrawCallInfoBuffer& Batch::getDrawCallInfoBuffer() {
|
||||||
|
if (_currentNamedCall.empty()) {
|
||||||
|
return _drawCallInfos;
|
||||||
|
} else {
|
||||||
|
return _namedData[_currentNamedCall].drawCallInfos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Batch::DrawCallInfoBuffer& Batch::getDrawCallInfoBuffer() const {
|
||||||
|
if (_currentNamedCall.empty()) {
|
||||||
|
return _drawCallInfos;
|
||||||
|
} else {
|
||||||
|
auto it = _namedData.find(_currentNamedCall);
|
||||||
|
Q_ASSERT_X(it != _namedData.end(), Q_FUNC_INFO, (_currentNamedCall + " not in _namedData.").data());
|
||||||
|
return it->second.drawCallInfos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Batch::captureDrawCallInfoImpl() {
|
||||||
|
if (_invalidModel) {
|
||||||
|
TransformObject object;
|
||||||
|
_currentModel.getMatrix(object._model);
|
||||||
|
|
||||||
|
// FIXME - we don't want to be using glm::inverse() here but it fixes the flickering issue we are
|
||||||
|
// seeing with planky blocks in toybox. Our implementation of getInverseMatrix() is buggy in cases
|
||||||
|
// of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works.
|
||||||
|
//_model.getInverseMatrix(_object._modelInverse);
|
||||||
|
object._modelInverse = glm::inverse(object._model);
|
||||||
|
|
||||||
|
_objects.push_back(object);
|
||||||
|
|
||||||
|
// Flag is clean
|
||||||
|
_invalidModel = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& drawCallInfos = getDrawCallInfoBuffer();
|
||||||
|
drawCallInfos.push_back((uint16)_objects.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Batch::captureDrawCallInfo() {
|
||||||
|
if (!_currentNamedCall.empty()) {
|
||||||
|
// If we are processing a named call, we don't want to register the raw draw calls
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
captureDrawCallInfoImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Batch::captureNamedDrawCallInfo(std::string name) {
|
||||||
|
std::swap(_currentNamedCall, name); // Set and save _currentNamedCall
|
||||||
|
captureDrawCallInfoImpl();
|
||||||
|
std::swap(_currentNamedCall, name); // Restore _currentNamedCall
|
||||||
|
}
|
||||||
|
|
||||||
void Batch::preExecute() {
|
void Batch::preExecute() {
|
||||||
for (auto& mapItem : _namedData) {
|
for (auto& mapItem : _namedData) {
|
||||||
mapItem.second.process(*this);
|
auto& name = mapItem.first;
|
||||||
|
auto& instance = mapItem.second;
|
||||||
|
|
||||||
|
startNamedCall(name);
|
||||||
|
instance.process(*this);
|
||||||
|
stopNamedCall();
|
||||||
}
|
}
|
||||||
_namedData.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
|
QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
|
||||||
|
|
|
@ -29,7 +29,12 @@ class QDebug;
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
enum ReservedSlot {
|
enum ReservedSlot {
|
||||||
|
|
||||||
|
#ifdef GPU_SSBO_DRAW_CALL_INFO
|
||||||
TRANSFORM_OBJECT_SLOT = 6,
|
TRANSFORM_OBJECT_SLOT = 6,
|
||||||
|
#else
|
||||||
|
TRANSFORM_OBJECT_SLOT = 31,
|
||||||
|
#endif
|
||||||
TRANSFORM_CAMERA_SLOT = 7,
|
TRANSFORM_CAMERA_SLOT = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,13 +50,31 @@ class Batch {
|
||||||
public:
|
public:
|
||||||
typedef Stream::Slot Slot;
|
typedef Stream::Slot Slot;
|
||||||
|
|
||||||
|
|
||||||
|
class DrawCallInfo {
|
||||||
|
public:
|
||||||
|
using Index = uint16_t;
|
||||||
|
|
||||||
|
DrawCallInfo(Index idx) : index(idx) {}
|
||||||
|
|
||||||
|
Index index { 0 };
|
||||||
|
uint16_t unused { 0 }; // Reserved space for later
|
||||||
|
|
||||||
|
};
|
||||||
|
// Make sure DrawCallInfo has no extra padding
|
||||||
|
static_assert(sizeof(DrawCallInfo) == 4, "DrawCallInfo size is incorrect.");
|
||||||
|
|
||||||
|
using DrawCallInfoBuffer = std::vector<DrawCallInfo>;
|
||||||
|
|
||||||
struct NamedBatchData {
|
struct NamedBatchData {
|
||||||
using BufferPointers = std::vector<BufferPointer>;
|
using BufferPointers = std::vector<BufferPointer>;
|
||||||
using Function = std::function<void(gpu::Batch&, NamedBatchData&)>;
|
using Function = std::function<void(gpu::Batch&, NamedBatchData&)>;
|
||||||
|
|
||||||
BufferPointers buffers;
|
BufferPointers buffers;
|
||||||
size_t count { 0 };
|
|
||||||
Function function;
|
Function function;
|
||||||
|
DrawCallInfoBuffer drawCallInfos;
|
||||||
|
|
||||||
|
size_t count() const { return drawCallInfos.size(); }
|
||||||
|
|
||||||
void process(Batch& batch) {
|
void process(Batch& batch) {
|
||||||
if (function) {
|
if (function) {
|
||||||
|
@ -62,6 +85,16 @@ public:
|
||||||
|
|
||||||
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
|
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
|
||||||
|
|
||||||
|
DrawCallInfoBuffer _drawCallInfos;
|
||||||
|
|
||||||
|
std::string _currentNamedCall;
|
||||||
|
|
||||||
|
const DrawCallInfoBuffer& getDrawCallInfoBuffer() const;
|
||||||
|
DrawCallInfoBuffer& getDrawCallInfoBuffer();
|
||||||
|
|
||||||
|
void captureDrawCallInfo();
|
||||||
|
void captureNamedDrawCallInfo(std::string name);
|
||||||
|
|
||||||
class CacheState {
|
class CacheState {
|
||||||
public:
|
public:
|
||||||
size_t commandsSize;
|
size_t commandsSize;
|
||||||
|
@ -88,7 +121,7 @@ public:
|
||||||
transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { }
|
transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
Batch();
|
Batch() {}
|
||||||
Batch(const CacheState& cacheState);
|
Batch(const CacheState& cacheState);
|
||||||
explicit Batch(const Batch& batch);
|
explicit Batch(const Batch& batch);
|
||||||
~Batch();
|
~Batch();
|
||||||
|
@ -121,13 +154,8 @@ public:
|
||||||
void multiDrawIndirect(uint32 numCommands, Primitive primitiveType);
|
void multiDrawIndirect(uint32 numCommands, Primitive primitiveType);
|
||||||
void multiDrawIndexedIndirect(uint32 numCommands, Primitive primitiveType);
|
void multiDrawIndexedIndirect(uint32 numCommands, Primitive primitiveType);
|
||||||
|
|
||||||
|
|
||||||
void setupNamedCalls(const std::string& instanceName, size_t count, NamedBatchData::Function function);
|
|
||||||
void setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function);
|
void setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function);
|
||||||
BufferPointer getNamedBuffer(const std::string& instanceName, uint8_t index = 0);
|
BufferPointer getNamedBuffer(const std::string& instanceName, uint8_t index = 0);
|
||||||
void setNamedBuffer(const std::string& instanceName, BufferPointer& buffer, uint8_t index = 0);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Input Stage
|
// Input Stage
|
||||||
// InputFormat
|
// InputFormat
|
||||||
|
@ -304,6 +332,9 @@ public:
|
||||||
|
|
||||||
COMMAND_runLambda,
|
COMMAND_runLambda,
|
||||||
|
|
||||||
|
COMMAND_startNamedCall,
|
||||||
|
COMMAND_stopNamedCall,
|
||||||
|
|
||||||
// TODO: As long as we have gl calls explicitely issued from interface
|
// TODO: As long as we have gl calls explicitely issued from interface
|
||||||
// code, we need to be able to record and batch these calls. THe long
|
// code, we need to be able to record and batch these calls. THe long
|
||||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||||
|
@ -395,7 +426,7 @@ public:
|
||||||
typedef Cache<PipelinePointer>::Vector PipelineCaches;
|
typedef Cache<PipelinePointer>::Vector PipelineCaches;
|
||||||
typedef Cache<FramebufferPointer>::Vector FramebufferCaches;
|
typedef Cache<FramebufferPointer>::Vector FramebufferCaches;
|
||||||
typedef Cache<QueryPointer>::Vector QueryCaches;
|
typedef Cache<QueryPointer>::Vector QueryCaches;
|
||||||
typedef Cache<std::string>::Vector ProfileRangeCaches;
|
typedef Cache<std::string>::Vector StringCaches;
|
||||||
typedef Cache<std::function<void()>>::Vector LambdaCache;
|
typedef Cache<std::function<void()>>::Vector LambdaCache;
|
||||||
|
|
||||||
// Cache Data in a byte array if too big to fit in Param
|
// Cache Data in a byte array if too big to fit in Param
|
||||||
|
@ -415,6 +446,18 @@ public:
|
||||||
Params _params;
|
Params _params;
|
||||||
Bytes _data;
|
Bytes _data;
|
||||||
|
|
||||||
|
// SSBO class... layout MUST match the layout in TransformCamera.slh
|
||||||
|
class TransformObject {
|
||||||
|
public:
|
||||||
|
Mat4 _model;
|
||||||
|
Mat4 _modelInverse;
|
||||||
|
};
|
||||||
|
|
||||||
|
using TransformObjects = std::vector<TransformObject>;
|
||||||
|
bool _invalidModel { true };
|
||||||
|
Transform _currentModel;
|
||||||
|
TransformObjects _objects;
|
||||||
|
|
||||||
BufferCaches _buffers;
|
BufferCaches _buffers;
|
||||||
TextureCaches _textures;
|
TextureCaches _textures;
|
||||||
StreamFormatCaches _streamFormats;
|
StreamFormatCaches _streamFormats;
|
||||||
|
@ -423,7 +466,8 @@ public:
|
||||||
FramebufferCaches _framebuffers;
|
FramebufferCaches _framebuffers;
|
||||||
QueryCaches _queries;
|
QueryCaches _queries;
|
||||||
LambdaCache _lambdas;
|
LambdaCache _lambdas;
|
||||||
ProfileRangeCaches _profileRanges;
|
StringCaches _profileRanges;
|
||||||
|
StringCaches _names;
|
||||||
|
|
||||||
NamedBatchDataMap _namedData;
|
NamedBatchDataMap _namedData;
|
||||||
|
|
||||||
|
@ -431,8 +475,13 @@ public:
|
||||||
bool _enableSkybox{ false };
|
bool _enableSkybox{ false };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void startNamedCall(const std::string& name);
|
||||||
|
void stopNamedCall();
|
||||||
|
|
||||||
// Maybe useful but shoudln't be public. Please convince me otherwise
|
// Maybe useful but shoudln't be public. Please convince me otherwise
|
||||||
void runLambda(std::function<void()> f);
|
void runLambda(std::function<void()> f);
|
||||||
|
|
||||||
|
void captureDrawCallInfoImpl();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,13 +76,6 @@ public:
|
||||||
virtual void syncCache() = 0;
|
virtual void syncCache() = 0;
|
||||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||||
|
|
||||||
// UBO class... layout MUST match the layout in TransformCamera.slh
|
|
||||||
class TransformObject {
|
|
||||||
public:
|
|
||||||
Mat4 _model;
|
|
||||||
Mat4 _modelInverse;
|
|
||||||
};
|
|
||||||
|
|
||||||
// UBO class... layout MUST match the layout in TransformCamera.slh
|
// UBO class... layout MUST match the layout in TransformCamera.slh
|
||||||
class TransformCamera {
|
class TransformCamera {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -62,6 +62,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
||||||
|
|
||||||
(&::gpu::GLBackend::do_runLambda),
|
(&::gpu::GLBackend::do_runLambda),
|
||||||
|
|
||||||
|
(&::gpu::GLBackend::do_startNamedCall),
|
||||||
|
(&::gpu::GLBackend::do_stopNamedCall),
|
||||||
|
|
||||||
(&::gpu::GLBackend::do_glActiveBindTexture),
|
(&::gpu::GLBackend::do_glActiveBindTexture),
|
||||||
|
|
||||||
(&::gpu::GLBackend::do_glUniform1i),
|
(&::gpu::GLBackend::do_glUniform1i),
|
||||||
|
@ -121,11 +124,7 @@ Backend* GLBackend::createBackend() {
|
||||||
return new GLBackend();
|
return new GLBackend();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLBackend() :
|
GLBackend::GLBackend() {
|
||||||
_input(),
|
|
||||||
_pipeline(),
|
|
||||||
_output()
|
|
||||||
{
|
|
||||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &_uboAlignment);
|
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &_uboAlignment);
|
||||||
initInput();
|
initInput();
|
||||||
initTransform();
|
initTransform();
|
||||||
|
@ -155,10 +154,8 @@ void GLBackend::renderPassTransfer(Batch& batch) {
|
||||||
|
|
||||||
{ // Sync all the buffers
|
{ // Sync all the buffers
|
||||||
PROFILE_RANGE("syncCPUTransform");
|
PROFILE_RANGE("syncCPUTransform");
|
||||||
_transform._cameras.resize(0);
|
_transform._cameras.clear();
|
||||||
_transform._cameraOffsets.clear();
|
_transform._cameraOffsets.clear();
|
||||||
_transform._objects.resize(0);
|
|
||||||
_transform._objectOffsets.clear();
|
|
||||||
|
|
||||||
for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) {
|
for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) {
|
||||||
switch (*command) {
|
switch (*command) {
|
||||||
|
@ -166,10 +163,11 @@ void GLBackend::renderPassTransfer(Batch& batch) {
|
||||||
case Batch::COMMAND_drawIndexed:
|
case Batch::COMMAND_drawIndexed:
|
||||||
case Batch::COMMAND_drawInstanced:
|
case Batch::COMMAND_drawInstanced:
|
||||||
case Batch::COMMAND_drawIndexedInstanced:
|
case Batch::COMMAND_drawIndexedInstanced:
|
||||||
|
case Batch::COMMAND_multiDrawIndirect:
|
||||||
|
case Batch::COMMAND_multiDrawIndexedIndirect:
|
||||||
_transform.preUpdate(_commandIndex, _stereo);
|
_transform.preUpdate(_commandIndex, _stereo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Batch::COMMAND_setModelTransform:
|
|
||||||
case Batch::COMMAND_setViewportTransform:
|
case Batch::COMMAND_setViewportTransform:
|
||||||
case Batch::COMMAND_setViewTransform:
|
case Batch::COMMAND_setViewTransform:
|
||||||
case Batch::COMMAND_setProjectionTransform: {
|
case Batch::COMMAND_setProjectionTransform: {
|
||||||
|
@ -188,12 +186,14 @@ void GLBackend::renderPassTransfer(Batch& batch) {
|
||||||
|
|
||||||
{ // Sync the transform buffers
|
{ // Sync the transform buffers
|
||||||
PROFILE_RANGE("syncGPUTransform");
|
PROFILE_RANGE("syncGPUTransform");
|
||||||
_transform.transfer();
|
_transform.transfer(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::renderPassDraw(Batch& batch) {
|
void GLBackend::renderPassDraw(Batch& batch) {
|
||||||
_transform._objectsItr = _transform._objectOffsets.begin();
|
_currentDraw = -1;
|
||||||
_transform._camerasItr = _transform._cameraOffsets.begin();
|
_transform._camerasItr = _transform._cameraOffsets.begin();
|
||||||
const size_t numCommands = batch.getCommands().size();
|
const size_t numCommands = batch.getCommands().size();
|
||||||
const Batch::Commands::value_type* command = batch.getCommands().data();
|
const Batch::Commands::value_type* command = batch.getCommands().data();
|
||||||
|
@ -209,6 +209,22 @@ void GLBackend::renderPassDraw(Batch& batch) {
|
||||||
case Batch::COMMAND_setProjectionTransform:
|
case Batch::COMMAND_setProjectionTransform:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Batch::COMMAND_draw:
|
||||||
|
case Batch::COMMAND_drawIndexed:
|
||||||
|
case Batch::COMMAND_drawInstanced:
|
||||||
|
case Batch::COMMAND_drawIndexedInstanced:
|
||||||
|
case Batch::COMMAND_multiDrawIndirect:
|
||||||
|
case Batch::COMMAND_multiDrawIndexedIndirect: {
|
||||||
|
// updates for draw calls
|
||||||
|
++_currentDraw;
|
||||||
|
updateInput();
|
||||||
|
updateTransform(batch);
|
||||||
|
updatePipeline();
|
||||||
|
|
||||||
|
CommandCall call = _commandCalls[(*command)];
|
||||||
|
(this->*(call))(batch, *offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
CommandCall call = _commandCalls[(*command)];
|
CommandCall call = _commandCalls[(*command)];
|
||||||
(this->*(call))(batch, *offset);
|
(this->*(call))(batch, *offset);
|
||||||
|
@ -306,10 +322,6 @@ void GLBackend::syncCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_draw(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_draw(Batch& batch, size_t paramOffset) {
|
||||||
updateInput();
|
|
||||||
updateTransform();
|
|
||||||
updatePipeline();
|
|
||||||
|
|
||||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||||
GLenum mode = _primitiveToGLmode[primitiveType];
|
GLenum mode = _primitiveToGLmode[primitiveType];
|
||||||
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
||||||
|
@ -319,10 +331,6 @@ void GLBackend::do_draw(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
||||||
updateInput();
|
|
||||||
updateTransform();
|
|
||||||
updatePipeline();
|
|
||||||
|
|
||||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||||
GLenum mode = _primitiveToGLmode[primitiveType];
|
GLenum mode = _primitiveToGLmode[primitiveType];
|
||||||
uint32 numIndices = batch._params[paramOffset + 1]._uint;
|
uint32 numIndices = batch._params[paramOffset + 1]._uint;
|
||||||
|
@ -338,10 +346,6 @@ void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) {
|
||||||
updateInput();
|
|
||||||
updateTransform();
|
|
||||||
updatePipeline();
|
|
||||||
|
|
||||||
GLint numInstances = batch._params[paramOffset + 4]._uint;
|
GLint numInstances = batch._params[paramOffset + 4]._uint;
|
||||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint;
|
Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint;
|
||||||
GLenum mode = _primitiveToGLmode[primitiveType];
|
GLenum mode = _primitiveToGLmode[primitiveType];
|
||||||
|
@ -353,10 +357,6 @@ void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
|
||||||
updateInput();
|
|
||||||
updateTransform();
|
|
||||||
updatePipeline();
|
|
||||||
|
|
||||||
GLint numInstances = batch._params[paramOffset + 4]._uint;
|
GLint numInstances = batch._params[paramOffset + 4]._uint;
|
||||||
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 3]._uint];
|
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 3]._uint];
|
||||||
uint32 numIndices = batch._params[paramOffset + 2]._uint;
|
uint32 numIndices = batch._params[paramOffset + 2]._uint;
|
||||||
|
@ -381,10 +381,6 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
|
||||||
|
|
||||||
void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) {
|
||||||
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
||||||
updateInput();
|
|
||||||
updateTransform();
|
|
||||||
updatePipeline();
|
|
||||||
|
|
||||||
uint commandCount = batch._params[paramOffset + 0]._uint;
|
uint commandCount = batch._params[paramOffset + 0]._uint;
|
||||||
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint];
|
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint];
|
||||||
|
|
||||||
|
@ -398,10 +394,6 @@ void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) {
|
||||||
|
|
||||||
void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) {
|
||||||
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
||||||
updateInput();
|
|
||||||
updateTransform();
|
|
||||||
updatePipeline();
|
|
||||||
|
|
||||||
uint commandCount = batch._params[paramOffset + 0]._uint;
|
uint commandCount = batch._params[paramOffset + 0]._uint;
|
||||||
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint];
|
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint];
|
||||||
GLenum indexType = _elementTypeToGLType[_input._indexBufferType];
|
GLenum indexType = _elementTypeToGLType[_input._indexBufferType];
|
||||||
|
@ -423,6 +415,15 @@ void GLBackend::do_runLambda(Batch& batch, size_t paramOffset) {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLBackend::do_startNamedCall(Batch& batch, size_t paramOffset) {
|
||||||
|
batch._currentNamedCall = batch._names.get(batch._params[paramOffset]._uint);
|
||||||
|
_currentDraw = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLBackend::do_stopNamedCall(Batch& batch, size_t paramOffset) {
|
||||||
|
batch._currentNamedCall.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void GLBackend::resetStages() {
|
void GLBackend::resetStages() {
|
||||||
resetInputStage();
|
resetInputStage();
|
||||||
resetPipelineStage();
|
resetPipelineStage();
|
||||||
|
|
|
@ -320,28 +320,26 @@ protected:
|
||||||
void killTransform();
|
void killTransform();
|
||||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||||
void syncTransformStateCache();
|
void syncTransformStateCache();
|
||||||
void updateTransform() const;
|
void updateTransform(const Batch& batch);
|
||||||
void resetTransformStage();
|
void resetTransformStage();
|
||||||
|
|
||||||
struct TransformStageState {
|
struct TransformStageState {
|
||||||
using TransformObjects = std::vector<TransformObject>;
|
|
||||||
using TransformCameras = std::vector<TransformCamera>;
|
using TransformCameras = std::vector<TransformCamera>;
|
||||||
|
|
||||||
TransformObject _object;
|
|
||||||
TransformCamera _camera;
|
TransformCamera _camera;
|
||||||
TransformObjects _objects;
|
|
||||||
TransformCameras _cameras;
|
TransformCameras _cameras;
|
||||||
|
|
||||||
size_t _cameraUboSize{ 0 };
|
mutable std::map<std::string, GLvoid*> _drawCallInfoOffsets;
|
||||||
size_t _objectUboSize{ 0 };
|
|
||||||
GLuint _objectBuffer { 0 };
|
GLuint _objectBuffer { 0 };
|
||||||
GLuint _cameraBuffer { 0 };
|
GLuint _cameraBuffer { 0 };
|
||||||
Transform _model;
|
GLuint _drawCallInfoBuffer { 0 };
|
||||||
|
GLuint _objectBufferTexture { 0 };
|
||||||
|
size_t _cameraUboSize { 0 };
|
||||||
Transform _view;
|
Transform _view;
|
||||||
Mat4 _projection;
|
Mat4 _projection;
|
||||||
Vec4i _viewport { 0, 0, 1, 1 };
|
Vec4i _viewport { 0, 0, 1, 1 };
|
||||||
Vec2 _depthRange { 0.0f, 1.0f };
|
Vec2 _depthRange { 0.0f, 1.0f };
|
||||||
bool _invalidModel{true};
|
|
||||||
bool _invalidView { false };
|
bool _invalidView { false };
|
||||||
bool _invalidProj { false };
|
bool _invalidProj { false };
|
||||||
bool _invalidViewport { false };
|
bool _invalidViewport { false };
|
||||||
|
@ -349,13 +347,11 @@ protected:
|
||||||
using Pair = std::pair<size_t, size_t>;
|
using Pair = std::pair<size_t, size_t>;
|
||||||
using List = std::list<Pair>;
|
using List = std::list<Pair>;
|
||||||
List _cameraOffsets;
|
List _cameraOffsets;
|
||||||
List _objectOffsets;
|
|
||||||
mutable List::const_iterator _objectsItr;
|
|
||||||
mutable List::const_iterator _camerasItr;
|
mutable List::const_iterator _camerasItr;
|
||||||
|
|
||||||
void preUpdate(size_t commandIndex, const StereoState& stereo);
|
void preUpdate(size_t commandIndex, const StereoState& stereo);
|
||||||
void update(size_t commandIndex, const StereoState& stereo) const;
|
void update(size_t commandIndex, const StereoState& stereo) const;
|
||||||
void transfer() const;
|
void transfer(const Batch& batch) const;
|
||||||
} _transform;
|
} _transform;
|
||||||
|
|
||||||
int32_t _uboAlignment{ 0 };
|
int32_t _uboAlignment{ 0 };
|
||||||
|
@ -465,6 +461,9 @@ protected:
|
||||||
|
|
||||||
void do_runLambda(Batch& batch, size_t paramOffset);
|
void do_runLambda(Batch& batch, size_t paramOffset);
|
||||||
|
|
||||||
|
void do_startNamedCall(Batch& batch, size_t paramOffset);
|
||||||
|
void do_stopNamedCall(Batch& batch, size_t paramOffset);
|
||||||
|
|
||||||
void resetStages();
|
void resetStages();
|
||||||
|
|
||||||
// TODO: As long as we have gl calls explicitely issued from interface
|
// TODO: As long as we have gl calls explicitely issued from interface
|
||||||
|
@ -487,6 +486,8 @@ protected:
|
||||||
void do_pushProfileRange(Batch& batch, size_t paramOffset);
|
void do_pushProfileRange(Batch& batch, size_t paramOffset);
|
||||||
void do_popProfileRange(Batch& batch, size_t paramOffset);
|
void do_popProfileRange(Batch& batch, size_t paramOffset);
|
||||||
|
|
||||||
|
int _currentDraw { -1 };
|
||||||
|
|
||||||
typedef void (GLBackend::*CommandCall)(Batch&, size_t);
|
typedef void (GLBackend::*CommandCall)(Batch&, size_t);
|
||||||
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
||||||
};
|
};
|
||||||
|
|
|
@ -75,9 +75,9 @@ void makeBindings(GLBackend::GLShader* shader) {
|
||||||
glBindAttribLocation(glprogram, gpu::Stream::SKIN_CLUSTER_WEIGHT, "inSkinClusterWeight");
|
glBindAttribLocation(glprogram, gpu::Stream::SKIN_CLUSTER_WEIGHT, "inSkinClusterWeight");
|
||||||
}
|
}
|
||||||
|
|
||||||
loc = glGetAttribLocation(glprogram, "inInstanceTransform");
|
loc = glGetAttribLocation(glprogram, "_drawCallInfo");
|
||||||
if (loc >= 0 && loc != gpu::Stream::INSTANCE_XFM) {
|
if (loc >= 0 && loc != gpu::Stream::DRAW_CALL_INFO) {
|
||||||
glBindAttribLocation(glprogram, gpu::Stream::INSTANCE_XFM, "inInstanceTransform");
|
glBindAttribLocation(glprogram, gpu::Stream::DRAW_CALL_INFO, "_drawCallInfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link again to take into account the assigned attrib location
|
// Link again to take into account the assigned attrib location
|
||||||
|
@ -92,17 +92,27 @@ void makeBindings(GLBackend::GLShader* shader) {
|
||||||
// now assign the ubo binding, then DON't relink!
|
// now assign the ubo binding, then DON't relink!
|
||||||
|
|
||||||
//Check for gpu specific uniform slotBindings
|
//Check for gpu specific uniform slotBindings
|
||||||
loc = glGetUniformBlockIndex(glprogram, "transformObjectBuffer");
|
#ifdef GPU_SSBO_DRAW_CALL_INFO
|
||||||
|
loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer");
|
||||||
if (loc >= 0) {
|
if (loc >= 0) {
|
||||||
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
||||||
shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
loc = glGetUniformLocation(glprogram, "transformObjectBuffer");
|
||||||
|
if (loc >= 0) {
|
||||||
|
glProgramUniform1i(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
||||||
|
shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer");
|
loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer");
|
||||||
if (loc >= 0) {
|
if (loc >= 0) {
|
||||||
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT);
|
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT);
|
||||||
shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT;
|
shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLShader* compileShader(const Shader& shader) {
|
GLBackend::GLShader* compileShader(const Shader& shader) {
|
||||||
|
|
|
@ -16,8 +16,6 @@ using namespace gpu;
|
||||||
|
|
||||||
// Transform Stage
|
// Transform Stage
|
||||||
void GLBackend::do_setModelTransform(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_setModelTransform(Batch& batch, size_t paramOffset) {
|
||||||
_transform._model = batch._transforms.get(batch._params[paramOffset]._uint);
|
|
||||||
_transform._invalidModel = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setViewTransform(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_setViewTransform(Batch& batch, size_t paramOffset) {
|
||||||
|
@ -63,26 +61,29 @@ void GLBackend::do_setDepthRangeTransform(Batch& batch, size_t paramOffset) {
|
||||||
void GLBackend::initTransform() {
|
void GLBackend::initTransform() {
|
||||||
glGenBuffers(1, &_transform._objectBuffer);
|
glGenBuffers(1, &_transform._objectBuffer);
|
||||||
glGenBuffers(1, &_transform._cameraBuffer);
|
glGenBuffers(1, &_transform._cameraBuffer);
|
||||||
|
glGenBuffers(1, &_transform._drawCallInfoBuffer);
|
||||||
|
#ifndef GPU_SSBO_DRAW_CALL_INFO
|
||||||
|
glGenTextures(1, &_transform._objectBufferTexture);
|
||||||
|
#endif
|
||||||
size_t cameraSize = sizeof(TransformCamera);
|
size_t cameraSize = sizeof(TransformCamera);
|
||||||
while (_transform._cameraUboSize < cameraSize) {
|
while (_transform._cameraUboSize < cameraSize) {
|
||||||
_transform._cameraUboSize += _uboAlignment;
|
_transform._cameraUboSize += _uboAlignment;
|
||||||
}
|
}
|
||||||
size_t objectSize = sizeof(TransformObject);
|
|
||||||
while (_transform._objectUboSize < objectSize) {
|
|
||||||
_transform._objectUboSize += _uboAlignment;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::killTransform() {
|
void GLBackend::killTransform() {
|
||||||
glDeleteBuffers(1, &_transform._objectBuffer);
|
glDeleteBuffers(1, &_transform._objectBuffer);
|
||||||
glDeleteBuffers(1, &_transform._cameraBuffer);
|
glDeleteBuffers(1, &_transform._cameraBuffer);
|
||||||
|
glDeleteBuffers(1, &_transform._drawCallInfoBuffer);
|
||||||
|
#ifndef GPU_SSBO_DRAW_CALL_INFO
|
||||||
|
glDeleteTextures(1, &_transform._objectBufferTexture);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::syncTransformStateCache() {
|
void GLBackend::syncTransformStateCache() {
|
||||||
_transform._invalidViewport = true;
|
_transform._invalidViewport = true;
|
||||||
_transform._invalidProj = true;
|
_transform._invalidProj = true;
|
||||||
_transform._invalidView = true;
|
_transform._invalidView = true;
|
||||||
_transform._invalidModel = true;
|
|
||||||
|
|
||||||
glGetIntegerv(GL_VIEWPORT, (GLint*) &_transform._viewport);
|
glGetIntegerv(GL_VIEWPORT, (GLint*) &_transform._viewport);
|
||||||
|
|
||||||
|
@ -91,7 +92,6 @@ void GLBackend::syncTransformStateCache() {
|
||||||
Mat4 modelView;
|
Mat4 modelView;
|
||||||
auto modelViewInv = glm::inverse(modelView);
|
auto modelViewInv = glm::inverse(modelView);
|
||||||
_transform._view.evalFromRawMatrix(modelViewInv);
|
_transform._view.evalFromRawMatrix(modelViewInv);
|
||||||
_transform._model.setIdentity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) {
|
void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) {
|
||||||
|
@ -108,16 +108,6 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
|
||||||
_view.getInverseMatrix(_camera._view);
|
_view.getInverseMatrix(_camera._view);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_invalidModel) {
|
|
||||||
_model.getMatrix(_object._model);
|
|
||||||
|
|
||||||
// FIXME - we don't want to be using glm::inverse() here but it fixes the flickering issue we are
|
|
||||||
// seeing with planky blocks in toybox. Our implementation of getInverseMatrix() is buggy in cases
|
|
||||||
// of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works.
|
|
||||||
//_model.getInverseMatrix(_object._modelInverse);
|
|
||||||
_object._modelInverse = glm::inverse(_object._model);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_invalidView || _invalidProj || _invalidViewport) {
|
if (_invalidView || _invalidProj || _invalidViewport) {
|
||||||
size_t offset = _cameraUboSize * _cameras.size();
|
size_t offset = _cameraUboSize * _cameras.size();
|
||||||
if (stereo._enable) {
|
if (stereo._enable) {
|
||||||
|
@ -131,56 +121,68 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_invalidModel) {
|
|
||||||
size_t offset = _objectUboSize * _objects.size();
|
|
||||||
_objectOffsets.push_back(TransformStageState::Pair(commandIndex, offset));
|
|
||||||
_objects.push_back(_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flags are clean
|
// Flags are clean
|
||||||
_invalidView = _invalidProj = _invalidModel = _invalidViewport = false;
|
_invalidView = _invalidProj = _invalidViewport = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::TransformStageState::transfer() const {
|
void GLBackend::TransformStageState::transfer(const Batch& batch) const {
|
||||||
// FIXME not thread safe
|
// FIXME not thread safe
|
||||||
static std::vector<uint8_t> bufferData;
|
static std::vector<uint8_t> bufferData;
|
||||||
if (!_cameras.empty()) {
|
if (!_cameras.empty()) {
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer);
|
|
||||||
bufferData.resize(_cameraUboSize * _cameras.size());
|
bufferData.resize(_cameraUboSize * _cameras.size());
|
||||||
for (size_t i = 0; i < _cameras.size(); ++i) {
|
for (size_t i = 0; i < _cameras.size(); ++i) {
|
||||||
memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera));
|
memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera));
|
||||||
}
|
}
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
|
||||||
}
|
|
||||||
|
|
||||||
if (!_objects.empty()) {
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer);
|
|
||||||
bufferData.resize(_objectUboSize * _objects.size());
|
|
||||||
for (size_t i = 0; i < _objects.size(); ++i) {
|
|
||||||
memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject));
|
|
||||||
}
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_cameras.empty() || !_objects.empty()) {
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!batch._objects.empty()) {
|
||||||
|
auto byteSize = batch._objects.size() * sizeof(Batch::TransformObject);
|
||||||
|
bufferData.resize(byteSize);
|
||||||
|
memcpy(bufferData.data(), batch._objects.data(), byteSize);
|
||||||
|
|
||||||
|
#ifdef GPU_SSBO_DRAW_CALL_INFO
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, _objectBuffer);
|
||||||
|
glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
#else
|
||||||
|
glBindBuffer(GL_TEXTURE_BUFFER, _objectBuffer);
|
||||||
|
glBufferData(GL_TEXTURE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!batch._namedData.empty()) {
|
||||||
|
bufferData.clear();
|
||||||
|
for (auto& data : batch._namedData) {
|
||||||
|
auto currentSize = bufferData.size();
|
||||||
|
auto bytesToCopy = data.second.drawCallInfos.size() * sizeof(Batch::DrawCallInfo);
|
||||||
|
bufferData.resize(currentSize + bytesToCopy);
|
||||||
|
memcpy(bufferData.data() + currentSize, data.second.drawCallInfos.data(), bytesToCopy);
|
||||||
|
_drawCallInfoOffsets[data.first] = (GLvoid*)currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _drawCallInfoBuffer);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GPU_SSBO_DRAW_CALL_INFO
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer);
|
||||||
|
#else
|
||||||
|
glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT);
|
||||||
|
glBindTexture(GL_TEXTURE_BUFFER, _objectBufferTexture);
|
||||||
|
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _objectBuffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const {
|
void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const {
|
||||||
static const size_t INVALID_OFFSET = (size_t)-1;
|
static const size_t INVALID_OFFSET = (size_t)-1;
|
||||||
size_t offset = INVALID_OFFSET;
|
size_t offset = INVALID_OFFSET;
|
||||||
while ((_objectsItr != _objectOffsets.end()) && (commandIndex >= (*_objectsItr).first)) {
|
|
||||||
offset = (*_objectsItr).second;
|
|
||||||
++_objectsItr;
|
|
||||||
}
|
|
||||||
if (offset != INVALID_OFFSET) {
|
|
||||||
glBindBufferRange(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT,
|
|
||||||
_objectBuffer, offset, sizeof(Backend::TransformObject));
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = INVALID_OFFSET;
|
|
||||||
while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) {
|
while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) {
|
||||||
offset = (*_camerasItr).second;
|
offset = (*_camerasItr).second;
|
||||||
++_camerasItr;
|
++_camerasItr;
|
||||||
|
@ -197,8 +199,23 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::updateTransform() const {
|
void GLBackend::updateTransform(const Batch& batch) {
|
||||||
_transform.update(_commandIndex, _stereo);
|
_transform.update(_commandIndex, _stereo);
|
||||||
|
|
||||||
|
auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer();
|
||||||
|
if (batch._currentNamedCall.empty()) {
|
||||||
|
auto& drawCallInfo = drawCallInfoBuffer[_currentDraw];
|
||||||
|
glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled
|
||||||
|
glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused);
|
||||||
|
} else {
|
||||||
|
glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer);
|
||||||
|
glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0,
|
||||||
|
_transform._drawCallInfoOffsets[batch._currentNamedCall]);
|
||||||
|
glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::resetTransformStage() {
|
void GLBackend::resetTransformStage() {
|
||||||
|
|
|
@ -10,13 +10,12 @@
|
||||||
!>
|
!>
|
||||||
<@if not GPU_INPUTS_SLH@>
|
<@if not GPU_INPUTS_SLH@>
|
||||||
<@def GPU_INPUTS_SLH@>
|
<@def GPU_INPUTS_SLH@>
|
||||||
in vec4 inPosition;
|
layout(location = 0) in vec4 inPosition;
|
||||||
in vec4 inNormal;
|
layout(location = 1) in vec4 inNormal;
|
||||||
in vec4 inColor;
|
layout(location = 2) in vec4 inColor;
|
||||||
in vec4 inTexCoord0;
|
layout(location = 3) in vec4 inTexCoord0;
|
||||||
in vec4 inTangent;
|
layout(location = 4) in vec4 inTangent;
|
||||||
in vec4 inSkinClusterIndex;
|
layout(location = 5) in vec4 inSkinClusterIndex;
|
||||||
in vec4 inSkinClusterWeight;
|
layout(location = 6) in vec4 inSkinClusterWeight;
|
||||||
in vec4 inTexCoord1;
|
layout(location = 7) in vec4 inTexCoord1;
|
||||||
in mat4 inInstanceTransform;
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -34,14 +34,7 @@ const ElementArray& getDefaultElements() {
|
||||||
//SKIN_CLUSTER_WEIGHT = 6,
|
//SKIN_CLUSTER_WEIGHT = 6,
|
||||||
Element::VEC4F_XYZW,
|
Element::VEC4F_XYZW,
|
||||||
//TEXCOORD1 = 7,
|
//TEXCOORD1 = 7,
|
||||||
Element::VEC2F_UV,
|
Element::VEC2F_UV
|
||||||
//INSTANCE_SCALE = 8,
|
|
||||||
Element::VEC3F_XYZ,
|
|
||||||
//INSTANCE_TRANSLATE = 9,
|
|
||||||
Element::VEC3F_XYZ,
|
|
||||||
//INSTANCE_XFM = 10,
|
|
||||||
// FIXME make a matrix element
|
|
||||||
Element::VEC4F_XYZW
|
|
||||||
}};
|
}};
|
||||||
return defaultElements;
|
return defaultElements;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,12 +37,10 @@ public:
|
||||||
SKIN_CLUSTER_INDEX = 5,
|
SKIN_CLUSTER_INDEX = 5,
|
||||||
SKIN_CLUSTER_WEIGHT = 6,
|
SKIN_CLUSTER_WEIGHT = 6,
|
||||||
TEXCOORD1 = 7,
|
TEXCOORD1 = 7,
|
||||||
INSTANCE_SCALE = 8,
|
NUM_INPUT_SLOTS = TEXCOORD1 + 1,
|
||||||
INSTANCE_TRANSLATE = 9,
|
|
||||||
INSTANCE_XFM = 10,
|
|
||||||
|
|
||||||
// Instance XFM is a mat4, and as such takes up 4 slots
|
|
||||||
NUM_INPUT_SLOTS = INSTANCE_XFM + 4,
|
DRAW_CALL_INFO = 15, // Reserve last input slot for draw call infos
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint8 Slot;
|
typedef uint8 Slot;
|
||||||
|
|
|
@ -10,12 +10,7 @@
|
||||||
<@if not GPU_TRANSFORM_STATE_SLH@>
|
<@if not GPU_TRANSFORM_STATE_SLH@>
|
||||||
<@def GPU_TRANSFORM_STATE_SLH@>
|
<@def GPU_TRANSFORM_STATE_SLH@>
|
||||||
|
|
||||||
<@func declareStandardTransform()@>
|
<@func declareStandardCameraTransform()@>
|
||||||
struct TransformObject {
|
|
||||||
mat4 _model;
|
|
||||||
mat4 _modelInverse;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TransformCamera {
|
struct TransformCamera {
|
||||||
mat4 _view;
|
mat4 _view;
|
||||||
mat4 _viewInverse;
|
mat4 _viewInverse;
|
||||||
|
@ -25,13 +20,6 @@ struct TransformCamera {
|
||||||
vec4 _viewport;
|
vec4 _viewport;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform transformObjectBuffer {
|
|
||||||
TransformObject _object;
|
|
||||||
};
|
|
||||||
TransformObject getTransformObject() {
|
|
||||||
return _object;
|
|
||||||
}
|
|
||||||
|
|
||||||
layout(std140) uniform transformCameraBuffer {
|
layout(std140) uniform transformCameraBuffer {
|
||||||
TransformCamera _camera;
|
TransformCamera _camera;
|
||||||
};
|
};
|
||||||
|
@ -40,6 +28,50 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
||||||
|
<@func declareStandardObjectTransform()@>
|
||||||
|
struct TransformObject {
|
||||||
|
mat4 _model;
|
||||||
|
mat4 _modelInverse;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location=15) in ivec2 _drawCallInfo;
|
||||||
|
|
||||||
|
<@if FALSE @>
|
||||||
|
// Disable SSBOs for now
|
||||||
|
layout(std140) buffer transformObjectBuffer {
|
||||||
|
TransformObject _object[];
|
||||||
|
};
|
||||||
|
TransformObject getTransformObject() {
|
||||||
|
return _object[_drawCallInfo.x];
|
||||||
|
}
|
||||||
|
<@else@>
|
||||||
|
uniform samplerBuffer transformObjectBuffer;
|
||||||
|
|
||||||
|
TransformObject getTransformObject() {
|
||||||
|
int offset = 8 * _drawCallInfo.x;
|
||||||
|
TransformObject object;
|
||||||
|
object._model[0] = texelFetch(transformObjectBuffer, offset);
|
||||||
|
object._model[1] = texelFetch(transformObjectBuffer, offset + 1);
|
||||||
|
object._model[2] = texelFetch(transformObjectBuffer, offset + 2);
|
||||||
|
object._model[3] = texelFetch(transformObjectBuffer, offset + 3);
|
||||||
|
|
||||||
|
object._modelInverse[0] = texelFetch(transformObjectBuffer, offset + 4);
|
||||||
|
object._modelInverse[1] = texelFetch(transformObjectBuffer, offset + 5);
|
||||||
|
object._modelInverse[2] = texelFetch(transformObjectBuffer, offset + 6);
|
||||||
|
object._modelInverse[3] = texelFetch(transformObjectBuffer, offset + 7);
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
<@endif@>
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
||||||
|
<@func declareStandardTransform()@>
|
||||||
|
<$declareStandardObjectTransform()$>
|
||||||
|
<$declareStandardCameraTransform()$>
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformCameraViewport(cameraTransform, viewport)@>
|
<@func transformCameraViewport(cameraTransform, viewport)@>
|
||||||
<$viewport$> = <$cameraTransform$>._viewport;
|
<$viewport$> = <$cameraTransform$>._viewport;
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
@ -53,15 +85,6 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformInstancedModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@>
|
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
|
||||||
{ // transformModelToClipPos
|
|
||||||
vec4 _eyepos = (inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
|
||||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
|
||||||
}
|
|
||||||
<@endfunc@>
|
|
||||||
|
|
||||||
<@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
<@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
|
@ -74,30 +97,12 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func $transformInstancedModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
|
||||||
{ // transformModelToClipPos
|
|
||||||
vec4 _worldpos = (inInstanceTransform * <$modelPos$>);
|
|
||||||
<$eyePos$> = (<$cameraTransform$>._view * _worldpos);
|
|
||||||
vec4 _eyepos =(inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0);
|
|
||||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos;
|
|
||||||
// <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>);
|
|
||||||
}
|
|
||||||
<@endfunc@>
|
|
||||||
|
|
||||||
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
||||||
{ // transformModelToWorldPos
|
{ // transformModelToWorldPos
|
||||||
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
|
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformInstancedModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
|
||||||
{ // transformModelToWorldPos
|
|
||||||
<$worldPos$> = (inInstanceTransform * <$modelPos$>);
|
|
||||||
}
|
|
||||||
<@endfunc@>
|
|
||||||
|
|
||||||
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
||||||
{ // transformModelToEyeDir
|
{ // transformModelToEyeDir
|
||||||
vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x);
|
vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x);
|
||||||
|
@ -112,21 +117,6 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
<@func transformInstancedModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
|
|
||||||
{ // transformModelToEyeDir
|
|
||||||
mat4 modelInverse = inverse(inInstanceTransform);
|
|
||||||
vec3 mr0 = vec3(modelInverse[0].x, modelInverse[1].x, modelInverse[2].x);
|
|
||||||
vec3 mr1 = vec3(modelInverse[0].y, modelInverse[1].y, modelInverse[2].y);
|
|
||||||
vec3 mr2 = vec3(modelInverse[0].z, modelInverse[1].z, modelInverse[2].z);
|
|
||||||
|
|
||||||
vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2));
|
|
||||||
vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2));
|
|
||||||
vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2));
|
|
||||||
|
|
||||||
<$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>));
|
|
||||||
}
|
|
||||||
<@endfunc@>
|
|
||||||
|
|
||||||
<@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@>
|
<@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@>
|
||||||
{ // transformEyeToWorldDir
|
{ // transformEyeToWorldDir
|
||||||
<$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0));
|
<$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0));
|
||||||
|
|
|
@ -43,7 +43,6 @@ static const int VERTICES_PER_TRIANGLE = 3;
|
||||||
static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
|
static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
|
||||||
static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
|
static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
|
||||||
static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
|
static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
|
||||||
static const gpu::Element TRANSFORM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW };
|
|
||||||
|
|
||||||
static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
|
static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
|
||||||
static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
|
static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
|
||||||
|
@ -491,7 +490,6 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
|
||||||
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
|
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
|
||||||
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
|
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
|
||||||
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
|
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
|
||||||
INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, TRANSFORM_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
|
|
||||||
}
|
}
|
||||||
return INSTANCED_SOLID_STREAM_FORMAT;
|
return INSTANCED_SOLID_STREAM_FORMAT;
|
||||||
}
|
}
|
||||||
|
@ -511,11 +509,9 @@ GeometryCache::~GeometryCache() {
|
||||||
#endif //def WANT_DEBUG
|
#endif //def WANT_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
|
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
|
||||||
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
|
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
|
||||||
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
||||||
gpu::BufferView instanceXfmView(transformBuffer, 0, transformBuffer->getSize(), TRANSFORM_ELEMENT);
|
|
||||||
batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
|
void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
|
||||||
|
@ -528,24 +524,24 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
|
||||||
_shapes[shape].drawWire(batch);
|
_shapes[shape].drawWire(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
|
void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer) {
|
||||||
batch.setInputFormat(getInstancedSolidStreamFormat());
|
batch.setInputFormat(getInstancedSolidStreamFormat());
|
||||||
setupBatchInstance(batch, transformBuffer, colorBuffer);
|
setupBatchInstance(batch, colorBuffer);
|
||||||
_shapes[shape].drawInstances(batch, count);
|
_shapes[shape].drawInstances(batch, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
|
void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer) {
|
||||||
batch.setInputFormat(getInstancedSolidStreamFormat());
|
batch.setInputFormat(getInstancedSolidStreamFormat());
|
||||||
setupBatchInstance(batch, transformBuffer, colorBuffer);
|
setupBatchInstance(batch, colorBuffer);
|
||||||
_shapes[shape].drawWireInstances(batch, count);
|
_shapes[shape].drawWireInstances(batch, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
|
void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) {
|
||||||
renderShapeInstances(batch, Cube, count, transformBuffer, colorBuffer);
|
renderShapeInstances(batch, Cube, count, colorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
|
void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) {
|
||||||
renderWireShapeInstances(batch, Cube, count, transformBuffer, colorBuffer);
|
renderWireShapeInstances(batch, Cube, count, colorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderCube(gpu::Batch& batch) {
|
void GeometryCache::renderCube(gpu::Batch& batch) {
|
||||||
|
@ -556,8 +552,8 @@ void GeometryCache::renderWireCube(gpu::Batch& batch) {
|
||||||
renderWireShape(batch, Cube);
|
renderWireShape(batch, Cube);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) {
|
void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) {
|
||||||
renderShapeInstances(batch, Sphere, count, transformBuffer, colorBuffer);
|
renderShapeInstances(batch, Sphere, count, colorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderSphere(gpu::Batch& batch) {
|
void GeometryCache::renderSphere(gpu::Batch& batch) {
|
||||||
|
@ -1854,45 +1850,34 @@ uint32_t toCompactColor(const glm::vec4& color) {
|
||||||
return compactColor;
|
return compactColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const size_t INSTANCE_TRANSFORM_BUFFER = 0;
|
static const size_t INSTANCE_COLOR_BUFFER = 0;
|
||||||
static const size_t INSTANCE_COLOR_BUFFER = 1;
|
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void renderInstances(const std::string& name, gpu::Batch& batch, const Transform& transform, const glm::vec4& color, F f) {
|
void renderInstances(const std::string& name, gpu::Batch& batch, const glm::vec4& color, F f) {
|
||||||
{
|
{
|
||||||
gpu::BufferPointer instanceTransformBuffer = batch.getNamedBuffer(name, INSTANCE_TRANSFORM_BUFFER);
|
|
||||||
glm::mat4 glmTransform;
|
|
||||||
instanceTransformBuffer->append(transform.getMatrix(glmTransform));
|
|
||||||
|
|
||||||
gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER);
|
gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER);
|
||||||
auto compactColor = toCompactColor(color);
|
auto compactColor = toCompactColor(color);
|
||||||
instanceColorBuffer->append(compactColor);
|
instanceColorBuffer->append(compactColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setupNamedCalls(name, [f](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
batch.setupNamedCalls(name, [f](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
auto pipeline = DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
||||||
auto location = pipeline->getProgram()->getUniforms().findLocation("Instanced");
|
|
||||||
|
|
||||||
batch._glUniform1i(location, 1);
|
|
||||||
f(batch, data);
|
f(batch, data);
|
||||||
batch._glUniform1i(location, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
|
void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||||
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, GeometryCache::Sphere, data.count,
|
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, GeometryCache::Sphere, data.count(),
|
||||||
data.buffers[INSTANCE_TRANSFORM_BUFFER],
|
|
||||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
|
void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||||
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, GeometryCache::Sphere, data.count,
|
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, GeometryCache::Sphere, data.count(),
|
||||||
data.buffers[INSTANCE_TRANSFORM_BUFFER],
|
|
||||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1901,12 +1886,12 @@ void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const Transform&
|
||||||
// available shape types, both solid and wireframes
|
// available shape types, both solid and wireframes
|
||||||
//#define DEBUG_SHAPES
|
//#define DEBUG_SHAPES
|
||||||
|
|
||||||
void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
|
void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||||
|
|
||||||
#ifdef DEBUG_SHAPES
|
#ifdef DEBUG_SHAPES
|
||||||
static auto startTime = usecTimestampNow();
|
static auto startTime = usecTimestampNow();
|
||||||
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
|
|
||||||
auto usecs = usecTimestampNow();
|
auto usecs = usecTimestampNow();
|
||||||
usecs -= startTime;
|
usecs -= startTime;
|
||||||
|
@ -1931,29 +1916,25 @@ void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const Transform&
|
||||||
|
|
||||||
// For the first half second for a given shape, show the wireframe, for the second half, show the solid.
|
// For the first half second for a given shape, show the wireframe, for the second half, show the solid.
|
||||||
if (fractionalSeconds > 0.5f) {
|
if (fractionalSeconds > 0.5f) {
|
||||||
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, shape, data.count,
|
DependencyManager::get<GeometryCache>()->renderShapeInstances(batch, shape, data.count(),
|
||||||
data.buffers[INSTANCE_TRANSFORM_BUFFER],
|
|
||||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, shape, data.count,
|
DependencyManager::get<GeometryCache>()->renderWireShapeInstances(batch, shape, data.count(),
|
||||||
data.buffers[INSTANCE_TRANSFORM_BUFFER],
|
|
||||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
DependencyManager::get<GeometryCache>()->renderCubeInstances(batch, data.count,
|
DependencyManager::get<GeometryCache>()->renderCubeInstances(batch, data.count(),
|
||||||
data.buffers[INSTANCE_TRANSFORM_BUFFER],
|
|
||||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) {
|
void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color) {
|
||||||
static const std::string INSTANCE_NAME = __FUNCTION__;
|
static const std::string INSTANCE_NAME = __FUNCTION__;
|
||||||
renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstances(batch, data.count,
|
DependencyManager::get<GeometryCache>()->renderWireCubeInstances(batch, data.count(),
|
||||||
data.buffers[INSTANCE_TRANSFORM_BUFFER],
|
|
||||||
data.buffers[INSTANCE_COLOR_BUFFER]);
|
data.buffers[INSTANCE_COLOR_BUFFER]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,41 +154,41 @@ public:
|
||||||
gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
|
||||||
bool emissive = false, bool depthBias = false);
|
bool emissive = false, bool depthBias = false);
|
||||||
|
|
||||||
void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color);
|
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||||
void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) {
|
void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||||
renderSolidSphereInstance(batch, xfm, glm::vec4(color, 1.0));
|
renderSolidSphereInstance(batch, glm::vec4(color, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color);
|
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||||
void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) {
|
void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||||
renderWireSphereInstance(batch, xfm, glm::vec4(color, 1.0));
|
renderWireSphereInstance(batch, glm::vec4(color, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color);
|
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||||
void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) {
|
void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||||
renderSolidCubeInstance(batch, xfm, glm::vec4(color, 1.0));
|
renderSolidCubeInstance(batch, glm::vec4(color, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color);
|
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color);
|
||||||
void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) {
|
void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color) {
|
||||||
renderWireCubeInstance(batch, xfm, glm::vec4(color, 1.0));
|
renderWireCubeInstance(batch, glm::vec4(color, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer);
|
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||||
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer);
|
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||||
void renderShape(gpu::Batch& batch, Shape shape);
|
void renderShape(gpu::Batch& batch, Shape shape);
|
||||||
void renderWireShape(gpu::Batch& batch, Shape shape);
|
void renderWireShape(gpu::Batch& batch, Shape shape);
|
||||||
size_t getShapeTriangleCount(Shape shape);
|
size_t getShapeTriangleCount(Shape shape);
|
||||||
|
|
||||||
void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
|
void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||||
void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
|
void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||||
void renderCube(gpu::Batch& batch);
|
void renderCube(gpu::Batch& batch);
|
||||||
void renderWireCube(gpu::Batch& batch);
|
void renderWireCube(gpu::Batch& batch);
|
||||||
size_t getCubeTriangleCount();
|
size_t getCubeTriangleCount();
|
||||||
|
|
||||||
void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
|
void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||||
void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
|
void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer);
|
||||||
void renderSphere(gpu::Batch& batch);
|
void renderSphere(gpu::Batch& batch);
|
||||||
void renderWireSphere(gpu::Batch& batch);
|
void renderWireSphere(gpu::Batch& batch);
|
||||||
size_t getSphereTriangleCount();
|
size_t getSphereTriangleCount();
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<@include DeferredLighting.slh@>
|
<@include DeferredLighting.slh@>
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardCameraTransform()$>
|
||||||
|
|
||||||
|
|
||||||
// Everything about light
|
// Everything about light
|
||||||
|
|
|
@ -17,9 +17,7 @@
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
uniform bool Instanced = false;
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
|
|
||||||
out vec3 _normal;
|
out vec3 _normal;
|
||||||
out vec3 _modelNormal;
|
out vec3 _modelNormal;
|
||||||
out vec3 _color;
|
out vec3 _color;
|
||||||
|
@ -35,11 +33,6 @@ void main(void) {
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
if (Instanced) {
|
|
||||||
<$transformInstancedModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
|
||||||
<$transformInstancedModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
|
||||||
} else {
|
|
||||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -124,7 +124,6 @@ class QTestWindow : public QWindow {
|
||||||
glm::mat4 _projectionMatrix;
|
glm::mat4 _projectionMatrix;
|
||||||
RateCounter fps;
|
RateCounter fps;
|
||||||
QTime _time;
|
QTime _time;
|
||||||
int _instanceLocation{ -1 };
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderText();
|
void renderText();
|
||||||
|
@ -164,7 +163,6 @@ public:
|
||||||
state->setMultisampleEnable(true);
|
state->setMultisampleEnable(true);
|
||||||
state->setDepthTest(gpu::State::DepthTest { true });
|
state->setDepthTest(gpu::State::DepthTest { true });
|
||||||
_pipeline = gpu::Pipeline::create(shader, state);
|
_pipeline = gpu::Pipeline::create(shader, state);
|
||||||
_instanceLocation = _pipeline->getProgram()->getUniforms().findLocation("Instanced");
|
|
||||||
|
|
||||||
// Clear screen
|
// Clear screen
|
||||||
gpu::Batch batch;
|
gpu::Batch batch;
|
||||||
|
@ -218,16 +216,16 @@ public:
|
||||||
static const std::string GRID_INSTANCE = "Grid";
|
static const std::string GRID_INSTANCE = "Grid";
|
||||||
static auto compactColor1 = toCompactColor(vec4{ 0.35f, 0.25f, 0.15f, 1.0f });
|
static auto compactColor1 = toCompactColor(vec4{ 0.35f, 0.25f, 0.15f, 1.0f });
|
||||||
static auto compactColor2 = toCompactColor(vec4{ 0.15f, 0.25f, 0.35f, 1.0f });
|
static auto compactColor2 = toCompactColor(vec4{ 0.15f, 0.25f, 0.35f, 1.0f });
|
||||||
static gpu::BufferPointer transformBuffer;
|
static std::vector<glm::mat4> transforms;
|
||||||
static gpu::BufferPointer colorBuffer;
|
static gpu::BufferPointer colorBuffer;
|
||||||
if (!transformBuffer) {
|
if (!transforms.empty()) {
|
||||||
transformBuffer = std::make_shared<gpu::Buffer>();
|
transforms.reserve(200);
|
||||||
colorBuffer = std::make_shared<gpu::Buffer>();
|
colorBuffer = std::make_shared<gpu::Buffer>();
|
||||||
for (int i = 0; i < 100; ++i) {
|
for (int i = 0; i < 100; ++i) {
|
||||||
{
|
{
|
||||||
glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i));
|
glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i));
|
||||||
transform = glm::scale(transform, vec3(100, 1, 1));
|
transform = glm::scale(transform, vec3(100, 1, 1));
|
||||||
transformBuffer->append(transform);
|
transforms.push_back(transform);
|
||||||
colorBuffer->append(compactColor1);
|
colorBuffer->append(compactColor1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,21 +233,21 @@ public:
|
||||||
glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0)));
|
glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0)));
|
||||||
transform = glm::translate(transform, vec3(0, -1, -50 + i));
|
transform = glm::translate(transform, vec3(0, -1, -50 + i));
|
||||||
transform = glm::scale(transform, vec3(100, 1, 1));
|
transform = glm::scale(transform, vec3(100, 1, 1));
|
||||||
transformBuffer->append(transform);
|
transforms.push_back(transform);
|
||||||
colorBuffer->append(compactColor2);
|
colorBuffer->append(compactColor2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setupNamedCalls(GRID_INSTANCE, 200, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
for (auto& transform : transforms) {
|
||||||
|
batch.setModelTransform(transform);
|
||||||
|
batch.setupNamedCalls(GRID_INSTANCE, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
|
||||||
batch.setViewTransform(camera);
|
batch.setViewTransform(camera);
|
||||||
batch.setModelTransform(Transform());
|
|
||||||
batch.setPipeline(_pipeline);
|
batch.setPipeline(_pipeline);
|
||||||
batch._glUniform1i(_instanceLocation, 1);
|
geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count(), colorBuffer);
|
||||||
geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count, transformBuffer, colorBuffer);
|
|
||||||
batch._glUniform1i(_instanceLocation, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
static const size_t ITEM_COUNT = 1000;
|
static const size_t ITEM_COUNT = 1000;
|
||||||
|
@ -316,14 +314,11 @@ public:
|
||||||
batch.setViewTransform(camera);
|
batch.setViewTransform(camera);
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
batch.setPipeline(_pipeline);
|
batch.setPipeline(_pipeline);
|
||||||
batch._glUniform1i(_instanceLocation, 1);
|
|
||||||
batch.setInputFormat(getInstancedSolidStreamFormat());
|
batch.setInputFormat(getInstancedSolidStreamFormat());
|
||||||
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
|
||||||
batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
|
|
||||||
batch.setIndirectBuffer(indirectBuffer);
|
batch.setIndirectBuffer(indirectBuffer);
|
||||||
shapeData.setupBatch(batch);
|
shapeData.setupBatch(batch);
|
||||||
batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES);
|
batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES);
|
||||||
batch._glUniform1i(_instanceLocation, 0);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
batch.setViewTransform(camera);
|
batch.setViewTransform(camera);
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
uniform bool Instanced = false;
|
|
||||||
|
|
||||||
out vec3 _normal;
|
out vec3 _normal;
|
||||||
out vec3 _color;
|
out vec3 _color;
|
||||||
out vec2 _texCoord0;
|
out vec2 _texCoord0;
|
||||||
|
@ -32,12 +30,7 @@ void main(void) {
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
if (Instanced) {
|
|
||||||
<$transformInstancedModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
|
||||||
<$transformInstancedModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
|
||||||
} else {
|
|
||||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
|
||||||
}
|
|
||||||
_normal = vec3(0.0, 0.0, 1.0);
|
_normal = vec3(0.0, 0.0, 1.0);
|
||||||
}
|
}
|
Loading…
Reference in a new issue