mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 13:44:32 +02:00
replacing the glTransform pipeline for model rendering
This commit is contained in:
parent
cfec8a31a5
commit
cc3cc4f96f
13 changed files with 185 additions and 14 deletions
|
@ -153,10 +153,10 @@ void Batch::setViewTransform(const Transform& view) {
|
||||||
_params.push_back(_transforms.cache(view));
|
_params.push_back(_transforms.cache(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setProjectionTransform(const Transform& proj) {
|
void Batch::setProjectionTransform(const Mat4& proj) {
|
||||||
ADD_COMMAND(setProjectionTransform);
|
ADD_COMMAND(setProjectionTransform);
|
||||||
|
|
||||||
_params.push_back(_transforms.cache(proj));
|
_params.push_back(cacheData(sizeof(Mat4), &proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
||||||
void setModelTransform(const Transform& model);
|
void setModelTransform(const Transform& model);
|
||||||
void setViewTransform(const Transform& view);
|
void setViewTransform(const Transform& view);
|
||||||
void setProjectionTransform(const Transform& proj);
|
void setProjectionTransform(const Mat4& proj);
|
||||||
|
|
||||||
// Shader Stage
|
// Shader Stage
|
||||||
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
||||||
|
|
|
@ -13,6 +13,23 @@
|
||||||
|
|
||||||
<@if GLPROFILE == PC_GL @>
|
<@if GLPROFILE == PC_GL @>
|
||||||
<@def VERSION_HEADER #version 330 compatibility@>
|
<@def VERSION_HEADER #version 330 compatibility@>
|
||||||
|
|
||||||
|
<@func inputPosition name@>
|
||||||
|
layout(location = 0) in vec3 <$name$>;
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
|
<@func inputNormal name@>
|
||||||
|
layout(location = 1) in vec3 <$name$>;
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
|
<@func inputTexcoord name@>
|
||||||
|
layout(location = 4) in vec2 <$name$>;
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
|
<@func inputColor name@>
|
||||||
|
layout(location = 4) vec3 <$name$>;
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
<@elif GLPROFILE == MAC_GL @>
|
<@elif GLPROFILE == MAC_GL @>
|
||||||
<@def VERSION_HEADER #version 120@>
|
<@def VERSION_HEADER #version 120@>
|
||||||
<@else@>
|
<@else@>
|
||||||
|
|
|
@ -29,6 +29,21 @@ class Batch;
|
||||||
class Backend {
|
class Backend {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
class TransformObject {
|
||||||
|
public:
|
||||||
|
Mat4 _model;
|
||||||
|
Mat4 _modelInverse;
|
||||||
|
Mat4 _modelView;
|
||||||
|
Mat4 _modelViewInverseTranspose;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TransformCamera {
|
||||||
|
public:
|
||||||
|
Mat4 _view;
|
||||||
|
Mat4 _viewInverse;
|
||||||
|
Mat4 _projection;
|
||||||
|
};
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
static void setGPUObject(const Buffer& buffer, T* bo) {
|
static void setGPUObject(const Buffer& buffer, T* bo) {
|
||||||
buffer.setGPUObject(reinterpret_cast<GPUObject*>(bo));
|
buffer.setGPUObject(reinterpret_cast<GPUObject*>(bo));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#ifndef hifi_gpu_Format_h
|
#ifndef hifi_gpu_Format_h
|
||||||
#define hifi_gpu_Format_h
|
#define hifi_gpu_Format_h
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -24,6 +25,12 @@ typedef char int8;
|
||||||
|
|
||||||
typedef uint32 Offset;
|
typedef uint32 Offset;
|
||||||
|
|
||||||
|
typedef glm::mat4 Mat4;
|
||||||
|
typedef glm::mat3 Mat3;
|
||||||
|
typedef glm::vec4 Vec4;
|
||||||
|
typedef glm::vec3 Vec3;
|
||||||
|
typedef glm::vec2 Vec2;
|
||||||
|
|
||||||
// Description of a scalar type
|
// Description of a scalar type
|
||||||
enum Type {
|
enum Type {
|
||||||
|
|
||||||
|
|
|
@ -386,18 +386,49 @@ void GLBackend::do_setViewTransform(Batch& batch, uint32 paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
||||||
_transform._projection = batch._transforms.get(batch._params[paramOffset]._uint);
|
memcpy(&_transform._projection, batch.editData(batch._params[paramOffset]._uint), sizeof(Mat4));
|
||||||
_transform._invalidProj = true;
|
_transform._invalidProj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLBackend::initTransform() {
|
||||||
|
#if defined(Q_OS_MAC)
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
glGenBuffers(1, &_transform._transformObjectBuffer);
|
||||||
|
glGenBuffers(1, &_transform._transformCameraBuffer);
|
||||||
|
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, _transform._transformObjectBuffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(_transform._transformObject), (const void*) &_transform._transformObject, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, _transform._transformCameraBuffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLBackend::killTransform() {
|
||||||
|
#if defined(Q_OS_MAC)
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
glDeleteBuffers(1, &_transform._transformObjectBuffer);
|
||||||
|
glDeleteBuffers(1, &_transform._transformCameraBuffer);
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void GLBackend::updateTransform() {
|
void GLBackend::updateTransform() {
|
||||||
|
#define LEGACY_TRANSFORM_PIPELINE
|
||||||
|
#ifdef LEGACY_TRANSFORM_PIPELINE
|
||||||
if (_transform._invalidProj) {
|
if (_transform._invalidProj) {
|
||||||
// TODO: implement the projection matrix assignment to gl state
|
// TODO: implement the projection matrix assignment to gl state
|
||||||
/* if (_transform._lastMode != GL_PROJECTION) {
|
if (_transform._lastMode != GL_PROJECTION) {
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
_transform._lastMode = GL_PROJECTION;
|
_transform._lastMode = GL_PROJECTION;
|
||||||
}
|
}
|
||||||
CHECK_GL_ERROR();*/
|
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&_transform._projection));
|
||||||
|
|
||||||
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_transform._invalidModel || _transform._invalidView) {
|
if (_transform._invalidModel || _transform._invalidView) {
|
||||||
|
@ -434,6 +465,46 @@ void GLBackend::updateTransform() {
|
||||||
_transform._invalidModel = false;
|
_transform._invalidModel = false;
|
||||||
_transform._invalidView = false;
|
_transform._invalidView = false;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (_transform._invalidProj) {
|
||||||
|
_transform._transformCamera._projection = _transform._projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transform._invalidView) {
|
||||||
|
_transform._view.getInverseMatrix(_transform._transformCamera._view);
|
||||||
|
_transform._view.getMatrix(_transform._transformCamera._viewInverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transform._invalidModel) {
|
||||||
|
_transform._model.getMatrix(_transform._transformObject._model);
|
||||||
|
_transform._model.getInverseMatrix(_transform._transformObject._modelInverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transform._invalidView || _transform._invalidModel) {
|
||||||
|
Transform mvx;
|
||||||
|
Transform::inverseMult(mvx, _transform._view, _transform._model);
|
||||||
|
mvx.getMatrix(_transform._transformObject._modelView);
|
||||||
|
mvx.getInverseTransposeMatrix(_transform._transformObject._modelViewInverseTranspose);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transform._invalidView || _transform._invalidProj) {
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, _transform._transformCameraBuffer);
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transform._invalidView || _transform._invalidModel) {
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, _transform._transformObjectBuffer);
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(_transform._transformObject), (const void*) &_transform._transformObject);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, 0, _transform._transformCameraBuffer, 0, sizeof(TransformCamera));
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, 1, _transform._transformObjectBuffer, 0, sizeof(TransformObject));
|
||||||
|
|
||||||
|
_transform._invalidView = _transform._invalidProj = _transform._invalidModel = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
||||||
|
|
|
@ -113,11 +113,17 @@ protected:
|
||||||
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
||||||
void do_setProjectionTransform(Batch& batch, uint32 paramOffset);
|
void do_setProjectionTransform(Batch& batch, uint32 paramOffset);
|
||||||
|
|
||||||
|
void initTransform();
|
||||||
|
void killTransform();
|
||||||
void updateTransform();
|
void updateTransform();
|
||||||
struct TransformStageState {
|
struct TransformStageState {
|
||||||
|
TransformObject _transformObject;
|
||||||
|
TransformCamera _transformCamera;
|
||||||
|
GLuint _transformObjectBuffer;
|
||||||
|
GLuint _transformCameraBuffer;
|
||||||
Transform _model;
|
Transform _model;
|
||||||
Transform _view;
|
Transform _view;
|
||||||
Transform _projection;
|
Mat4 _projection;
|
||||||
bool _invalidModel;
|
bool _invalidModel;
|
||||||
bool _invalidView;
|
bool _invalidView;
|
||||||
bool _invalidProj;
|
bool _invalidProj;
|
||||||
|
@ -125,6 +131,8 @@ protected:
|
||||||
GLenum _lastMode;
|
GLenum _lastMode;
|
||||||
|
|
||||||
TransformStageState() :
|
TransformStageState() :
|
||||||
|
_transformObjectBuffer(0),
|
||||||
|
_transformCameraBuffer(0),
|
||||||
_model(),
|
_model(),
|
||||||
_view(),
|
_view(),
|
||||||
_projection(),
|
_projection(),
|
||||||
|
|
|
@ -13,19 +13,19 @@
|
||||||
struct TransformObject {
|
struct TransformObject {
|
||||||
mat4 _model;
|
mat4 _model;
|
||||||
mat4 _modelInverseTranspose;
|
mat4 _modelInverseTranspose;
|
||||||
|
mat4 _modelView;
|
||||||
|
mat4 _modelViewInverseTranspose;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransformCamera {
|
struct TransformCamera {
|
||||||
mat4 _view;
|
mat4 _view;
|
||||||
mat4 _viewInverseTranspose;
|
mat4 _viewInverse;
|
||||||
mat4 _proj;
|
mat4 _projection;
|
||||||
mat4 _projInverseTranspose;
|
|
||||||
mat4 _viewProj;
|
|
||||||
mat4 _viewProjInverseTranspose;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vec4 transform(TransformCamera camera, TransformObject object, vec4 pos) {
|
vec4 transform(TransformCamera camera, TransformObject object, vec4 pos) {
|
||||||
return camera._proj * (camera._view * (object._model * pos)));
|
return camera._projection * (object._modelView * pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -866,4 +866,11 @@ float ViewFrustum::distanceToCamera(const glm::vec3& point) const {
|
||||||
return distanceToPoint;
|
return distanceToPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewFrustum::evalProjectionMatrix(glm::mat4& proj) const {
|
||||||
|
if (isOrthographic()) {
|
||||||
|
proj = glm::ortho(getWidth() * -0.5, getWidth() * +0.5, getHeight() * -0.5, getHeight() * 0.5);
|
||||||
|
} else {
|
||||||
|
proj = glm::perspective(getFieldOfView(), getAspectRatio(), getNearClip(), getFarClip());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ public:
|
||||||
|
|
||||||
float distanceToCamera(const glm::vec3& point) const;
|
float distanceToCamera(const glm::vec3& point) const;
|
||||||
|
|
||||||
|
void evalProjectionMatrix(glm::mat4& proj) const;
|
||||||
private:
|
private:
|
||||||
// Used for keyhole calculations
|
// Used for keyhole calculations
|
||||||
ViewFrustum::location pointInKeyhole(const glm::vec3& point) const;
|
ViewFrustum::location pointInKeyhole(const glm::vec3& point) const;
|
||||||
|
|
|
@ -1659,11 +1659,26 @@ void Model::setupBatchTransform(gpu::Batch& batch) {
|
||||||
void Model::endScene(RenderMode mode, RenderArgs* args) {
|
void Model::endScene(RenderMode mode, RenderArgs* args) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
|
|
||||||
|
|
||||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO;
|
RenderArgs::RenderSide renderSide = RenderArgs::MONO;
|
||||||
if (args) {
|
if (args) {
|
||||||
renderSide = args->_renderSide;
|
renderSide = args->_renderSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
glm::mat4 proj;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||||
|
gpu::Batch batch;
|
||||||
|
batch.setProjectionTransform(proj);
|
||||||
|
::gpu::GLBackend::renderBatch(batch);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_viewState->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);
|
||||||
|
|
||||||
|
|
||||||
// Do the rendering batch creation for mono or left eye, not for right eye
|
// Do the rendering batch creation for mono or left eye, not for right eye
|
||||||
if (renderSide != RenderArgs::STEREO_RIGHT) {
|
if (renderSide != RenderArgs::STEREO_RIGHT) {
|
||||||
// Let's introduce a gpu::Batch to capture all the calls to the graphics api
|
// Let's introduce a gpu::Batch to capture all the calls to the graphics api
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
const int MAX_TEXCOORDS = 2;
|
const int MAX_TEXCOORDS = 2;
|
||||||
|
|
||||||
|
<$inputPosition(vin_position)$>
|
||||||
|
<$inputNormal(vin_normal)$>
|
||||||
|
<$inputTexcoord(vin_texcoord)$>
|
||||||
|
<$inputColor(vin_color)$>
|
||||||
|
|
||||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
|
@ -30,6 +35,23 @@ void main(void) {
|
||||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||||
|
|
||||||
// use standard pipeline transform
|
// use standard pipeline transform
|
||||||
gl_Position = ftransform();
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(vin_position, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
void main(void) {
|
||||||
|
// transform and store the normal for interpolation
|
||||||
|
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||||
|
|
||||||
|
// pass along the diffuse color
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
|
||||||
|
// and the texture coordinates
|
||||||
|
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||||
|
|
||||||
|
// use standard pipeline transform
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -90,6 +90,7 @@ public:
|
||||||
|
|
||||||
Mat4& getMatrix(Mat4& result) const;
|
Mat4& getMatrix(Mat4& result) const;
|
||||||
Mat4& getInverseMatrix(Mat4& result) const;
|
Mat4& getInverseMatrix(Mat4& result) const;
|
||||||
|
Mat4& getInverseTransposeMatrix(Mat4& result) const;
|
||||||
|
|
||||||
Transform& evalInverse(Transform& result) const;
|
Transform& evalInverse(Transform& result) const;
|
||||||
|
|
||||||
|
@ -329,6 +330,13 @@ inline Transform::Mat4& Transform::getInverseMatrix(Transform::Mat4& result) con
|
||||||
return inverse.getMatrix(result);
|
return inverse.getMatrix(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Transform::Mat4& Transform::getInverseTransposeMatrix(Transform::Mat4& result) const {
|
||||||
|
getInverseMatrix(result);
|
||||||
|
result = glm::transpose(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Transform::evalFromRawMatrix(const Mat4& matrix) {
|
inline void Transform::evalFromRawMatrix(const Mat4& matrix) {
|
||||||
// for now works only in the case of TRS transformation
|
// for now works only in the case of TRS transformation
|
||||||
if ((matrix[0][3] == 0) && (matrix[1][3] == 0) && (matrix[2][3] == 0) && (matrix[3][3] == 1.0f)) {
|
if ((matrix[0][3] == 0) && (matrix[1][3] == 0) && (matrix[2][3] == 0) && (matrix[3][3] == 1.0f)) {
|
||||||
|
|
Loading…
Reference in a new issue