mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +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));
|
||||
}
|
||||
|
||||
void Batch::setProjectionTransform(const Transform& proj) {
|
||||
void Batch::setProjectionTransform(const Mat4& proj) {
|
||||
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) {
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
||||
void setModelTransform(const Transform& model);
|
||||
void setViewTransform(const Transform& view);
|
||||
void setProjectionTransform(const Transform& proj);
|
||||
void setProjectionTransform(const Mat4& proj);
|
||||
|
||||
// Shader Stage
|
||||
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
||||
|
|
|
@ -13,6 +13,23 @@
|
|||
|
||||
<@if GLPROFILE == PC_GL @>
|
||||
<@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 @>
|
||||
<@def VERSION_HEADER #version 120@>
|
||||
<@else@>
|
||||
|
|
|
@ -29,6 +29,21 @@ class Batch;
|
|||
class Backend {
|
||||
public:
|
||||
|
||||
class TransformObject {
|
||||
public:
|
||||
Mat4 _model;
|
||||
Mat4 _modelInverse;
|
||||
Mat4 _modelView;
|
||||
Mat4 _modelViewInverseTranspose;
|
||||
};
|
||||
|
||||
class TransformCamera {
|
||||
public:
|
||||
Mat4 _view;
|
||||
Mat4 _viewInverse;
|
||||
Mat4 _projection;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
static void setGPUObject(const Buffer& buffer, T* bo) {
|
||||
buffer.setGPUObject(reinterpret_cast<GPUObject*>(bo));
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#ifndef hifi_gpu_Format_h
|
||||
#define hifi_gpu_Format_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <assert.h>
|
||||
|
||||
namespace gpu {
|
||||
|
@ -24,6 +25,12 @@ typedef char int8;
|
|||
|
||||
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
|
||||
enum Type {
|
||||
|
||||
|
|
|
@ -386,18 +386,49 @@ void GLBackend::do_setViewTransform(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;
|
||||
}
|
||||
|
||||
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() {
|
||||
#define LEGACY_TRANSFORM_PIPELINE
|
||||
#ifdef LEGACY_TRANSFORM_PIPELINE
|
||||
if (_transform._invalidProj) {
|
||||
// TODO: implement the projection matrix assignment to gl state
|
||||
/* if (_transform._lastMode != GL_PROJECTION) {
|
||||
if (_transform._lastMode != GL_PROJECTION) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
_transform._lastMode = GL_PROJECTION;
|
||||
}
|
||||
CHECK_GL_ERROR();*/
|
||||
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&_transform._projection));
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
if (_transform._invalidModel || _transform._invalidView) {
|
||||
|
@ -434,6 +465,46 @@ void GLBackend::updateTransform() {
|
|||
_transform._invalidModel = 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) {
|
||||
|
|
|
@ -113,11 +113,17 @@ protected:
|
|||
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setProjectionTransform(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void initTransform();
|
||||
void killTransform();
|
||||
void updateTransform();
|
||||
struct TransformStageState {
|
||||
TransformObject _transformObject;
|
||||
TransformCamera _transformCamera;
|
||||
GLuint _transformObjectBuffer;
|
||||
GLuint _transformCameraBuffer;
|
||||
Transform _model;
|
||||
Transform _view;
|
||||
Transform _projection;
|
||||
Mat4 _projection;
|
||||
bool _invalidModel;
|
||||
bool _invalidView;
|
||||
bool _invalidProj;
|
||||
|
@ -125,6 +131,8 @@ protected:
|
|||
GLenum _lastMode;
|
||||
|
||||
TransformStageState() :
|
||||
_transformObjectBuffer(0),
|
||||
_transformCameraBuffer(0),
|
||||
_model(),
|
||||
_view(),
|
||||
_projection(),
|
||||
|
|
|
@ -13,19 +13,19 @@
|
|||
struct TransformObject {
|
||||
mat4 _model;
|
||||
mat4 _modelInverseTranspose;
|
||||
mat4 _modelView;
|
||||
mat4 _modelViewInverseTranspose;
|
||||
};
|
||||
|
||||
struct TransformCamera {
|
||||
mat4 _view;
|
||||
mat4 _viewInverseTranspose;
|
||||
mat4 _proj;
|
||||
mat4 _projInverseTranspose;
|
||||
mat4 _viewProj;
|
||||
mat4 _viewProjInverseTranspose;
|
||||
mat4 _viewInverse;
|
||||
mat4 _projection;
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
void evalProjectionMatrix(glm::mat4& proj) const;
|
||||
private:
|
||||
// Used for keyhole calculations
|
||||
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) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
|
||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO;
|
||||
if (args) {
|
||||
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
|
||||
if (renderSide != RenderArgs::STEREO_RIGHT) {
|
||||
// Let's introduce a gpu::Batch to capture all the calls to the graphics api
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
<$inputPosition(vin_position)$>
|
||||
<$inputNormal(vin_normal)$>
|
||||
<$inputTexcoord(vin_texcoord)$>
|
||||
<$inputColor(vin_color)$>
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
||||
// the interpolated normal
|
||||
|
@ -30,6 +35,23 @@ void main(void) {
|
|||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||
|
||||
// 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& getInverseMatrix(Mat4& result) const;
|
||||
Mat4& getInverseTransposeMatrix(Mat4& result) const;
|
||||
|
||||
Transform& evalInverse(Transform& result) const;
|
||||
|
||||
|
@ -329,6 +330,13 @@ inline Transform::Mat4& Transform::getInverseMatrix(Transform::Mat4& result) con
|
|||
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) {
|
||||
// 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)) {
|
||||
|
|
Loading…
Reference in a new issue