Unify Named/Normal calls

This commit is contained in:
Atlante45 2016-01-14 12:37:09 -08:00
parent 9e0af63441
commit ccb183e518
10 changed files with 20 additions and 85 deletions

View file

@ -260,6 +260,7 @@ protected:
using DrawCallInfoBuffer = std::vector<DrawCallInfo>;
using NamedDrawCallInfoBuffer = std::map<std::string, DrawCallInfoBuffer>;
int _currentDraw = 0;
DrawCallInfoBuffer _drawCallInfos;
NamedDrawCallInfoBuffer _namedDrawCallInfos;

View file

@ -75,9 +75,9 @@ void makeBindings(GLBackend::GLShader* shader) {
glBindAttribLocation(glprogram, gpu::Stream::SKIN_CLUSTER_WEIGHT, "inSkinClusterWeight");
}
loc = glGetAttribLocation(glprogram, "inInstanceTransform");
if (loc >= 0 && loc != gpu::Stream::INSTANCE_XFM) {
glBindAttribLocation(glprogram, gpu::Stream::INSTANCE_XFM, "inInstanceTransform");
loc = glGetAttribLocation(glprogram, "_drawCallInfo");
if (loc >= 0 && loc != gpu::Stream::DRAW_CALL_INFO) {
glBindAttribLocation(glprogram, gpu::Stream::DRAW_CALL_INFO, "_drawCallInfo");
}
// Link again to take into account the assigned attrib location

View file

@ -185,6 +185,9 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta
void GLBackend::updateTransform() const {
_transform.update(_commandIndex, _stereo);
auto& drawCallInfo = _drawCallInfos[_currentDraw];
glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused);
}
void GLBackend::resetTransformStage() {

View file

@ -18,5 +18,4 @@ in vec4 inTangent;
in vec4 inSkinClusterIndex;
in vec4 inSkinClusterWeight;
in vec4 inTexCoord1;
in mat4 inInstanceTransform;
<@endif@>

View file

@ -39,10 +39,10 @@ public:
TEXCOORD1 = 7,
INSTANCE_SCALE = 8,
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
NUM_INPUT_SLOTS = DRAW_CALL_INFO + 1,
};
typedef uint8 Slot;

View file

@ -27,11 +27,13 @@ struct TransformCamera {
const int MAX_OBJECTS = 512; // NEEDS to match GLBackend::TransformStageState::update's MAX_OBJECT
in ivec2 _drawCallInfo;
layout(std140) uniform transformObjectBuffer {
TransformObject _object[MAX_OBJECTS];
};
TransformObject getTransformObject() {
return _object;
return _object[_drawCallInfo.x];
}
layout(std140) uniform transformCameraBuffer {
@ -55,15 +57,6 @@ TransformCamera getTransformCamera() {
}
<@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)@>
<!// Equivalent to the following but hoppefully a tad more accurate
//return camera._projection * camera._view * object._model * pos; !>
@ -76,30 +69,12 @@ TransformCamera getTransformCamera() {
}
<@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)@>
{ // transformModelToWorldPos
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
}
<@endfunc@>
<@func transformInstancedModelToWorldPos(objectTransform, modelPos, worldPos)@>
{ // transformModelToWorldPos
<$worldPos$> = (inInstanceTransform * <$modelPos$>);
}
<@endfunc@>
<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@>
{ // transformModelToEyeDir
vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x);
@ -114,21 +89,6 @@ TransformCamera getTransformCamera() {
}
<@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)@>
{ // transformEyeToWorldDir
<$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0));

View file

@ -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 NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
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 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::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::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, TRANSFORM_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
}
return INSTANCED_SOLID_STREAM_FORMAT;
}
@ -511,11 +509,9 @@ GeometryCache::~GeometryCache() {
#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);
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) {
@ -530,13 +526,13 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
batch.setInputFormat(getInstancedSolidStreamFormat());
setupBatchInstance(batch, transformBuffer, colorBuffer);
setupBatchInstance(batch, colorBuffer);
_shapes[shape].drawInstances(batch, count);
}
void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) {
batch.setInputFormat(getInstancedSolidStreamFormat());
setupBatchInstance(batch, transformBuffer, colorBuffer);
setupBatchInstance(batch, colorBuffer);
_shapes[shape].drawWireInstances(batch, count);
}
@ -1871,11 +1867,7 @@ void renderInstances(const std::string& name, gpu::Batch& batch, const Transform
batch.setupNamedCalls(name, [f](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) {
auto pipeline = DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
auto location = pipeline->getProgram()->getUniforms().findLocation("Instanced");
batch._glUniform1i(location, 1);
f(batch, data);
batch._glUniform1i(location, 0);
});
}

View file

@ -17,9 +17,7 @@
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
uniform bool Instanced = false;
// the interpolated normal
out vec3 _normal;
out vec3 _modelNormal;
out vec3 _color;
@ -35,11 +33,6 @@ void main(void) {
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
if (Instanced) {
<$transformInstancedModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformInstancedModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
} else {
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
}
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
}

View file

@ -124,7 +124,6 @@ class QTestWindow : public QWindow {
glm::mat4 _projectionMatrix;
RateCounter fps;
QTime _time;
int _instanceLocation{ -1 };
protected:
void renderText();
@ -164,7 +163,6 @@ public:
state->setMultisampleEnable(true);
state->setDepthTest(gpu::State::DepthTest { true });
_pipeline = gpu::Pipeline::create(shader, state);
_instanceLocation = _pipeline->getProgram()->getUniforms().findLocation("Instanced");
// Clear screen
gpu::Batch batch;
@ -245,9 +243,7 @@ public:
batch.setViewTransform(camera);
batch.setModelTransform(Transform());
batch.setPipeline(_pipeline);
batch._glUniform1i(_instanceLocation, 1);
geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count, transformBuffer, colorBuffer);
batch._glUniform1i(_instanceLocation, 0);
});
}
@ -316,14 +312,12 @@ public:
batch.setViewTransform(camera);
batch.setModelTransform(Transform());
batch.setPipeline(_pipeline);
batch._glUniform1i(_instanceLocation, 1);
batch.setInputFormat(getInstancedSolidStreamFormat());
batch.setInputBuffer(gpu::Stream::COLOR, colorView);
batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView);
batch.setIndirectBuffer(indirectBuffer);
shapeData.setupBatch(batch);
batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES);
batch._glUniform1i(_instanceLocation, 0);
}
#else
batch.setViewTransform(camera);

View file

@ -19,8 +19,6 @@
<$declareStandardTransform()$>
// the interpolated normal
uniform bool Instanced = false;
out vec3 _normal;
out vec3 _color;
out vec2 _texCoord0;
@ -32,12 +30,7 @@ void main(void) {
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
if (Instanced) {
<$transformInstancedModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformInstancedModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
} else {
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
}
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$>
_normal = vec3(0.0, 0.0, 1.0);
}