replacing the glTransform pipeline for model rendering

This commit is contained in:
Sam Gateau 2015-02-16 09:31:29 -08:00
parent cfec8a31a5
commit cc3cc4f96f
13 changed files with 185 additions and 14 deletions

View file

@ -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) {

View file

@ -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);

View file

@ -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@>

View file

@ -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));

View file

@ -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 {

View file

@ -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) {

View file

@ -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(),

View file

@ -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);
}

View file

@ -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());
}
}

View file

@ -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;

View file

@ -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

View file

@ -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();
}
*/

View file

@ -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)) {