mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Unify Named/Normal calls
This commit is contained in:
parent
9e0af63441
commit
ccb183e518
10 changed files with 20 additions and 85 deletions
|
@ -260,6 +260,7 @@ protected:
|
|||
using DrawCallInfoBuffer = std::vector<DrawCallInfo>;
|
||||
using NamedDrawCallInfoBuffer = std::map<std::string, DrawCallInfoBuffer>;
|
||||
|
||||
int _currentDraw = 0;
|
||||
DrawCallInfoBuffer _drawCallInfos;
|
||||
NamedDrawCallInfoBuffer _namedDrawCallInfos;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -18,5 +18,4 @@ in vec4 inTangent;
|
|||
in vec4 inSkinClusterIndex;
|
||||
in vec4 inSkinClusterWeight;
|
||||
in vec4 inTexCoord1;
|
||||
in mat4 inInstanceTransform;
|
||||
<@endif@>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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)$>
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in a new issue