mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 03:56:32 +02:00
SImplified the Transform usage in the gpu::api, no more pointers, just values. Improved the Transform by compressing the memory footprint
This commit is contained in:
parent
b92a617290
commit
7e2c4c0561
9 changed files with 101 additions and 98 deletions
|
@ -160,7 +160,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_lastQueriedViewFrustum(),
|
||||
_lastQueriedTime(usecTimestampNow()),
|
||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||
_viewTransform(new gpu::Transform()),
|
||||
_viewTransform(),
|
||||
_scaleMirror(1.0f),
|
||||
_rotateMirror(0.0f),
|
||||
_raiseMirror(0.0f),
|
||||
|
@ -2911,13 +2911,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
|
||||
// the viewTransofmr object is updatded with the correct values and saved,
|
||||
// this is what is used for rendering the Entities and avatars
|
||||
gpu::Transform viewTransform;
|
||||
Transform viewTransform;
|
||||
viewTransform.setTranslation(whichCamera.getPosition());
|
||||
viewTransform.setRotation(rotation);
|
||||
viewTransform.postTranslate(eyeOffsetPos);
|
||||
viewTransform.postRotate(eyeOffsetOrient);
|
||||
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
viewTransform.setScale(gpu::Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
setViewTransform(viewTransform);
|
||||
|
||||
|
@ -3117,8 +3117,8 @@ void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTransl
|
|||
_viewMatrixTranslation = viewMatrixTranslation;
|
||||
}
|
||||
|
||||
void Application::setViewTransform(const gpu::Transform& view) {
|
||||
(*_viewTransform) = view;
|
||||
void Application::setViewTransform(const Transform& view) {
|
||||
_viewTransform = view;
|
||||
}
|
||||
|
||||
void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||
|
|
|
@ -232,8 +232,8 @@ public:
|
|||
const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; }
|
||||
void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; }
|
||||
|
||||
const gpu::TransformPointer& getViewTransform() const { return _viewTransform; }
|
||||
void setViewTransform(const gpu::Transform& view);
|
||||
const Transform& getViewTransform() const { return _viewTransform; }
|
||||
void setViewTransform(const Transform& view);
|
||||
|
||||
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
||||
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
||||
|
@ -526,7 +526,7 @@ private:
|
|||
QRect _mirrorViewRect;
|
||||
RearMirrorTools* _rearMirrorTools;
|
||||
|
||||
gpu::TransformPointer _viewTransform;
|
||||
Transform _viewTransform;
|
||||
glm::mat4 _untranslatedViewMatrix;
|
||||
glm::vec3 _viewMatrixTranslation;
|
||||
glm::mat4 _projectionMatrix;
|
||||
|
|
|
@ -135,19 +135,19 @@ void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset
|
|||
_params.push_back(type);
|
||||
}
|
||||
|
||||
void Batch::setModelTransform(const TransformPointer& model) {
|
||||
void Batch::setModelTransform(const Transform& model) {
|
||||
ADD_COMMAND(setModelTransform);
|
||||
|
||||
_params.push_back(_transforms.cache(model));
|
||||
}
|
||||
|
||||
void Batch::setViewTransform(const TransformPointer& view) {
|
||||
void Batch::setViewTransform(const Transform& view) {
|
||||
ADD_COMMAND(setViewTransform);
|
||||
|
||||
_params.push_back(_transforms.cache(view));
|
||||
}
|
||||
|
||||
void Batch::setProjectionTransform(const TransformPointer& proj) {
|
||||
void Batch::setProjectionTransform(const Transform& proj) {
|
||||
ADD_COMMAND(setProjectionTransform);
|
||||
|
||||
_params.push_back(_transforms.cache(proj));
|
||||
|
|
|
@ -50,10 +50,6 @@ enum Primitive {
|
|||
NUM_PRIMITIVES,
|
||||
};
|
||||
|
||||
typedef ::Transform Transform;
|
||||
typedef QSharedPointer< ::gpu::Transform > TransformPointer;
|
||||
typedef std::vector< TransformPointer > Transforms;
|
||||
|
||||
class Batch {
|
||||
public:
|
||||
typedef Stream::Slot Slot;
|
||||
|
@ -87,9 +83,9 @@ public:
|
|||
// finaly projected into the clip space by the projection transform
|
||||
// WARNING: ViewTransform transform from eye space to world space, its inverse is composed
|
||||
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
||||
void setModelTransform(const TransformPointer& model);
|
||||
void setViewTransform(const TransformPointer& view);
|
||||
void setProjectionTransform(const TransformPointer& proj);
|
||||
void setModelTransform(const Transform& model);
|
||||
void setViewTransform(const Transform& view);
|
||||
void setProjectionTransform(const Transform& proj);
|
||||
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
|
@ -258,35 +254,35 @@ public:
|
|||
template <typename T>
|
||||
class Cache {
|
||||
public:
|
||||
typedef QSharedPointer<T> Pointer;
|
||||
Pointer _pointer;
|
||||
Cache<T>(const Pointer& pointer) : _pointer(pointer) {}
|
||||
typedef T Data;
|
||||
Data _data;
|
||||
Cache<T>(const Data& data) : _data(data) {}
|
||||
|
||||
class Vector {
|
||||
public:
|
||||
std::vector< Cache<T> > _pointers;
|
||||
std::vector< Cache<T> > _items;
|
||||
|
||||
uint32 cache(const Pointer& pointer) {
|
||||
uint32 offset = _pointers.size();
|
||||
_pointers.push_back(Cache<T>(pointer));
|
||||
uint32 cache(const Data& data) {
|
||||
uint32 offset = _items.size();
|
||||
_items.push_back(Cache<T>(data));
|
||||
return offset;
|
||||
}
|
||||
|
||||
Pointer get(uint32 offset) {
|
||||
if (offset >= _pointers.size()) {
|
||||
return Pointer();
|
||||
Data get(uint32 offset) {
|
||||
if (offset >= _items.size()) {
|
||||
return Data();
|
||||
}
|
||||
return (_pointers.data() + offset)->_pointer;
|
||||
return (_items.data() + offset)->_data;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_pointers.clear();
|
||||
_items.clear();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
typedef Cache<Buffer>::Vector BufferCaches;
|
||||
typedef Cache<Stream::Format>::Vector StreamFormatCaches;
|
||||
|
||||
typedef Cache<BufferPointer>::Vector BufferCaches;
|
||||
typedef Cache<Stream::FormatPointer>::Vector StreamFormatCaches;
|
||||
typedef Cache<Transform>::Vector TransformCaches;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
|
|
@ -430,30 +430,18 @@ void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) {
|
|||
// Transform Stage
|
||||
|
||||
void GLBackend::do_setModelTransform(Batch& batch, uint32 paramOffset) {
|
||||
TransformPointer modelTransform = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
|
||||
if (_transform._model.isNull() || (modelTransform != _transform._model)) {
|
||||
_transform._model = modelTransform;
|
||||
_transform._invalidModel = true;
|
||||
}
|
||||
_transform._model = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
_transform._invalidModel = true;
|
||||
}
|
||||
|
||||
void GLBackend::do_setViewTransform(Batch& batch, uint32 paramOffset) {
|
||||
TransformPointer viewTransform = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
|
||||
if (_transform._view.isNull() || (viewTransform != _transform._view)) {
|
||||
_transform._view = viewTransform;
|
||||
_transform._invalidView = true;
|
||||
}
|
||||
_transform._view = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
_transform._invalidView = true;
|
||||
}
|
||||
|
||||
void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
||||
TransformPointer projectionTransform = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
|
||||
if (_transform._projection.isNull() || (projectionTransform != _transform._projection)) {
|
||||
_transform._projection = projectionTransform;
|
||||
_transform._invalidProj = true;
|
||||
}
|
||||
_transform._projection = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
_transform._invalidProj = true;
|
||||
}
|
||||
|
||||
void GLBackend::updateTransform() {
|
||||
|
@ -468,28 +456,28 @@ void GLBackend::updateTransform() {
|
|||
}
|
||||
|
||||
if (_transform._invalidModel || _transform._invalidView) {
|
||||
if (!_transform._model.isNull()) {
|
||||
if (!_transform._model.isIdentity()) {
|
||||
if (_transform._lastMode != GL_MODELVIEW) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
_transform._lastMode = GL_MODELVIEW;
|
||||
}
|
||||
Transform::Mat4 modelView;
|
||||
if (!_transform._view.isNull()) {
|
||||
if (!_transform._view.isIdentity()) {
|
||||
Transform mvx;
|
||||
Transform::inverseMult(mvx, (*_transform._view), (*_transform._model));
|
||||
Transform::inverseMult(mvx, _transform._view, _transform._model);
|
||||
mvx.getMatrix(modelView);
|
||||
} else {
|
||||
_transform._model->getMatrix(modelView);
|
||||
_transform._model.getMatrix(modelView);
|
||||
}
|
||||
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView));
|
||||
} else {
|
||||
if (!_transform._view.isNull()) {
|
||||
if (!_transform._view.isIdentity()) {
|
||||
if (_transform._lastMode != GL_MODELVIEW) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
_transform._lastMode = GL_MODELVIEW;
|
||||
}
|
||||
Transform::Mat4 modelView;
|
||||
_transform._view->getInverseMatrix(modelView);
|
||||
_transform._view.getInverseMatrix(modelView);
|
||||
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView));
|
||||
} else {
|
||||
// TODO: eventually do something about the matrix when neither view nor model is specified?
|
||||
|
|
|
@ -86,9 +86,9 @@ protected:
|
|||
|
||||
void updateTransform();
|
||||
struct TransformStageState {
|
||||
TransformPointer _model;
|
||||
TransformPointer _view;
|
||||
TransformPointer _projection;
|
||||
Transform _model;
|
||||
Transform _view;
|
||||
Transform _projection;
|
||||
bool _invalidModel;
|
||||
bool _invalidView;
|
||||
bool _invalidProj;
|
||||
|
@ -96,9 +96,9 @@ protected:
|
|||
GLenum _lastMode;
|
||||
|
||||
TransformStageState() :
|
||||
_model(0),
|
||||
_view(0),
|
||||
_projection(0),
|
||||
_model(),
|
||||
_view(),
|
||||
_projection(),
|
||||
_invalidModel(true),
|
||||
_invalidView(true),
|
||||
_invalidProj(true),
|
||||
|
|
|
@ -567,11 +567,11 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
// Capture the view matrix once for the rendering of this model
|
||||
if (_transforms.empty()) {
|
||||
_transforms.push_back(gpu::TransformPointer(new gpu::Transform()));
|
||||
_transforms.push_back(Transform());
|
||||
}
|
||||
(*_transforms[0]) = gpu::Transform((*Application::getInstance()->getViewTransform()));
|
||||
_transforms[0] = Application::getInstance()->getViewTransform();
|
||||
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
||||
_transforms[0]->preTranslate(-_translation);
|
||||
_transforms[0].preTranslate(-_translation);
|
||||
|
||||
batch.setViewTransform(_transforms[0]);
|
||||
|
||||
|
@ -1493,10 +1493,10 @@ void Model::setupBatchTransform(gpu::Batch& batch) {
|
|||
|
||||
// Capture the view matrix once for the rendering of this model
|
||||
if (_transforms.empty()) {
|
||||
_transforms.push_back(gpu::TransformPointer(new gpu::Transform()));
|
||||
_transforms.push_back(Transform());
|
||||
}
|
||||
(*_transforms[0]) = gpu::Transform((*Application::getInstance()->getViewTransform()));
|
||||
_transforms[0]->preTranslate(-_translation);
|
||||
_transforms[0] = Application::getInstance()->getViewTransform();
|
||||
_transforms[0].preTranslate(-_translation);
|
||||
batch.setViewTransform(_transforms[0]);
|
||||
}
|
||||
|
||||
|
@ -2149,10 +2149,9 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
|||
if (state.clusterMatrices.size() > 1) {
|
||||
GLBATCH(glUniformMatrix4fv)(skinLocations->clusterMatrices, state.clusterMatrices.size(), false,
|
||||
(const float*)state.clusterMatrices.constData());
|
||||
batch.setModelTransform(gpu::TransformPointer());
|
||||
batch.setModelTransform(Transform());
|
||||
} else {
|
||||
gpu::TransformPointer modelTransform(new gpu::Transform(state.clusterMatrices[0]));
|
||||
batch.setModelTransform(modelTransform);
|
||||
batch.setModelTransform(Transform(state.clusterMatrices[0]));
|
||||
}
|
||||
|
||||
if (mesh.blendshapes.isEmpty()) {
|
||||
|
|
|
@ -283,7 +283,7 @@ private:
|
|||
QUrl _url;
|
||||
|
||||
gpu::Buffers _blendedVertexBuffers;
|
||||
gpu::Transforms _transforms;
|
||||
std::vector<Transform> _transforms;
|
||||
gpu::Batch _renderBatch;
|
||||
|
||||
QVector<QVector<QSharedPointer<Texture> > > _dilatedTextures;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <bitset>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Transform {
|
||||
public:
|
||||
typedef glm::mat4 Mat4;
|
||||
|
@ -30,16 +32,16 @@ public:
|
|||
typedef glm::quat Quat;
|
||||
|
||||
Transform() :
|
||||
_translation(0),
|
||||
_rotation(1.0f, 0, 0, 0),
|
||||
_scale(1.0f),
|
||||
_translation(0),
|
||||
_flags(FLAG_CACHE_INVALID_BITSET) // invalid cache
|
||||
{
|
||||
}
|
||||
Transform(const Transform& transform) :
|
||||
_translation(transform._translation),
|
||||
_rotation(transform._rotation),
|
||||
_scale(transform._scale),
|
||||
_translation(transform._translation),
|
||||
_flags(transform._flags)
|
||||
{
|
||||
invalidCache();
|
||||
|
@ -49,6 +51,15 @@ public:
|
|||
}
|
||||
~Transform() {}
|
||||
|
||||
Transform& operator=(const Transform& transform) {
|
||||
_rotation = transform._rotation;
|
||||
_scale = transform._scale;
|
||||
_translation = transform._translation;
|
||||
_flags = transform._flags;
|
||||
invalidCache();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void setIdentity();
|
||||
|
||||
const Vec3& getTranslation() const;
|
||||
|
@ -89,7 +100,6 @@ public:
|
|||
// Left will be inversed before the multiplication
|
||||
static Transform& inverseMult(Transform& result, const Transform& left, const Transform& right);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
enum Flag {
|
||||
|
@ -111,14 +121,15 @@ protected:
|
|||
|
||||
|
||||
// TRS
|
||||
Vec3 _translation;
|
||||
Quat _rotation;
|
||||
Vec3 _scale;
|
||||
Vec3 _translation;
|
||||
|
||||
mutable Flags _flags;
|
||||
|
||||
// Cached transform
|
||||
mutable Mat4 _matrix;
|
||||
// TODO: replace this auto ptr by a "unique ptr" as soon as we are compiling in C++11
|
||||
mutable std::auto_ptr<Mat4> _matrix;
|
||||
|
||||
bool isCacheInvalid() const { return _flags[FLAG_CACHE_INVALID]; }
|
||||
void validCache() const { _flags.set(FLAG_CACHE_INVALID, false); }
|
||||
|
@ -135,6 +146,7 @@ protected:
|
|||
void flagNonUniform() { _flags.set(FLAG_NON_UNIFORM, true); }
|
||||
|
||||
void updateCache() const;
|
||||
Mat4& getCachedMatrix(Mat4& result) const;
|
||||
};
|
||||
|
||||
inline void Transform::setIdentity() {
|
||||
|
@ -271,8 +283,25 @@ inline void Transform::postScale(const Vec3& scale) {
|
|||
}
|
||||
|
||||
inline Transform::Mat4& Transform::getMatrix(Transform::Mat4& result) const {
|
||||
updateCache();
|
||||
result = _matrix;
|
||||
if (isRotating()) {
|
||||
Mat3 rot = glm::mat3_cast(_rotation);
|
||||
|
||||
if (isScaling()) {
|
||||
rot[0] *= _scale.x;
|
||||
rot[1] *= _scale.y;
|
||||
rot[2] *= _scale.z;
|
||||
}
|
||||
|
||||
result[0] = Vec4(rot[0], 0.f);
|
||||
result[1] = Vec4(rot[1], 0.f);
|
||||
result[2] = Vec4(rot[2], 0.f);
|
||||
} else {
|
||||
result[0] = Vec4(_scale.x, 0.f, 0.f, 0.f);
|
||||
result[1] = Vec4(0.f, _scale.y, 0.f, 0.f);
|
||||
result[2] = Vec4(0.f, 0.f, _scale.z, 0.f);
|
||||
}
|
||||
|
||||
result[3] = Vec4(_translation, 1.0f);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -369,27 +398,18 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le
|
|||
return result;
|
||||
}
|
||||
|
||||
inline Transform::Mat4& Transform::getCachedMatrix(Transform::Mat4& result) const {
|
||||
updateCache();
|
||||
result = (*_matrix);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void Transform::updateCache() const {
|
||||
if (isCacheInvalid()) {
|
||||
if (isRotating()) {
|
||||
Mat3 rot = glm::mat3_cast(_rotation);
|
||||
|
||||
if (isScaling()) {
|
||||
rot[0] *= _scale.x;
|
||||
rot[1] *= _scale.y;
|
||||
rot[2] *= _scale.z;
|
||||
}
|
||||
|
||||
_matrix[0] = Vec4(rot[0], 0.f);
|
||||
_matrix[1] = Vec4(rot[1], 0.f);
|
||||
_matrix[2] = Vec4(rot[2], 0.f);
|
||||
} else {
|
||||
_matrix[0] = Vec4(_scale.x, 0.f, 0.f, 0.f);
|
||||
_matrix[1] = Vec4(0.f, _scale.y, 0.f, 0.f);
|
||||
_matrix[2] = Vec4(0.f, 0.f, _scale.z, 0.f);
|
||||
if (!_matrix.get()) {
|
||||
_matrix.reset(new Mat4());
|
||||
}
|
||||
|
||||
_matrix[3] = Vec4(_translation, 1.0f);
|
||||
getMatrix((*_matrix));
|
||||
validCache();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue