Commit f34e2ad9 authored by Jan Möbius's avatar Jan Möbius
Browse files

Merge branch 'master' into splatcloud_rendering

parent 13087275
......@@ -57,6 +57,7 @@
//== INCLUDES ====================================================
#include <ACG/GL/acg_glew.hh>
#include <ACG/GL/IRenderer.hh>
#include "SplatCloudNode.hh"
......@@ -105,12 +106,15 @@ SplatCloudNode::SplatCloudNode( const SplatCloud &_splatCloud, BaseNode *_parent
vboGlId_ ( 0 ),
vboNumSplats_ ( 0 ),
vboData_ ( 0 ),
vboStride_ ( 0 ),
vboPositionsOffset_ ( -1 ),
vboColorsOffset_ ( -1 ),
vboNormalsOffset_ ( -1 ),
vboPointsizesOffset_( -1 ),
vboSelectionsOffset_( -1 ),
vboPickColorsOffset_( -1 )
vboPickColorsOffset_( -1 ),
pointsizeScale_ ( 1.0f ),
backfaceCulling_ ( false )
{
// create a new VBO (will be invalid and rebuilt the next time drawn (or picked))
createVBO();
......@@ -194,7 +198,7 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
if( vboPositionsOffset_ != -1 )
{
ACG::GLState::enableClientState( GL_VERTEX_ARRAY );
ACG::GLState::vertexPointer( 3, GL_FLOAT, 0, (unsigned char *) 0 + vboPositionsOffset_ );
ACG::GLState::vertexPointer( 3, GL_FLOAT, static_cast<GLsizei>(vboStride_), (unsigned char *) 0 + vboPositionsOffset_ );
}
else
{
......@@ -205,7 +209,7 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
if( vboColorsOffset_ != -1 )
{
ACG::GLState::enableClientState( GL_SECONDARY_COLOR_ARRAY );
glSecondaryColorPointer( 3, GL_UNSIGNED_BYTE, 0, (unsigned char *) 0 + vboColorsOffset_ ); // TODO: use ACG::GLState::secondaryColorPointer() when implemented
glSecondaryColorPointer( 3, GL_UNSIGNED_BYTE, static_cast<GLsizei>(vboStride_), (unsigned char *) 0 + vboColorsOffset_ ); // TODO: use ACG::GLState::secondaryColorPointer() when implemented
}
else
{
......@@ -217,7 +221,7 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
if( vboNormalsOffset_ != -1 )
{
ACG::GLState::enableClientState( GL_NORMAL_ARRAY );
ACG::GLState::normalPointer( GL_FLOAT, 0, (unsigned char *) 0 + vboNormalsOffset_ );
ACG::GLState::normalPointer( GL_FLOAT, static_cast<GLsizei>(vboStride_), (unsigned char *) 0 + vboNormalsOffset_ );
}
else
{
......@@ -230,7 +234,7 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
{
glClientActiveTexture( GL_TEXTURE0 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
ACG::GLState::enableClientState( GL_TEXTURE_COORD_ARRAY );
ACG::GLState::texcoordPointer( 1, GL_FLOAT, 0, (unsigned char *) 0 + vboPointsizesOffset_ );
ACG::GLState::texcoordPointer( 1, GL_FLOAT, static_cast<GLsizei>(vboStride_), (unsigned char *) 0 + vboPointsizesOffset_ );
}
else
{
......@@ -244,7 +248,7 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
{
glClientActiveTexture( GL_TEXTURE1 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
ACG::GLState::enableClientState( GL_TEXTURE_COORD_ARRAY );
ACG::GLState::texcoordPointer( 1, GL_FLOAT, 0, (unsigned char *) 0 + vboSelectionsOffset_ );
ACG::GLState::texcoordPointer( 1, GL_FLOAT, static_cast<GLsizei>(vboStride_), (unsigned char *) 0 + vboSelectionsOffset_ );
}
else
{
......@@ -257,7 +261,7 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
if( vboPickColorsOffset_ != -1 )
{
ACG::GLState::enableClientState( GL_COLOR_ARRAY );
ACG::GLState::colorPointer( 4, GL_UNSIGNED_BYTE, 0, (unsigned char *) 0 + vboPickColorsOffset_ );
ACG::GLState::colorPointer( 4, GL_UNSIGNED_BYTE, static_cast<GLsizei>(vboStride_), (unsigned char *) 0 + vboPickColorsOffset_ );
}
else
{
......@@ -316,6 +320,210 @@ void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode
}
}
//----------------------------------------------------------------
void SplatCloudNode::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
{
static const int RENDERMODE_DOTS = 1;
static const int RENDERMODE_SPLATS = 2;
// check if drawmode is valid
int rendermode;
if (_drawMode.containsAtomicDrawMode(splatsDrawMode_))
rendermode = RENDERMODE_SPLATS;
else if (_drawMode.containsAtomicDrawMode(dotsDrawMode_))
rendermode = RENDERMODE_DOTS;
else if (_drawMode.containsAtomicDrawMode(pointsDrawMode_)) {
static const int RENDERMODE_POINTS = 0;
rendermode = RENDERMODE_POINTS;
}
else
return;
ACG::RenderObject obj;
obj.initFromState(&_state);
obj.setMaterial(_mat);
obj.depthTest = true;
// if VBO is invalid or was (partially) modified, then rebuild
if ((vboData_ == 0) || vboModified())
rebuildVBO(_state);
// if VBO is valid...
if (vboData_ != 0)
{
// activate VBO
obj.vertexBuffer = vboGlId_;
// enable arrays:
// --------------
vboDecl_.clear();
// positions
if (vboPositionsOffset_ != -1)
vboDecl_.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION, size_t(vboPositionsOffset_));
// colors
if (vboColorsOffset_ != -1)
vboDecl_.addElement(GL_UNSIGNED_BYTE, 3, ACG::VERTEX_USAGE_COLOR, size_t(vboColorsOffset_));
else
{
obj.emissive = ACG::Vec3f(defaultColor_[0], defaultColor_[1], defaultColor_[2]);
obj.emissive /= 255.0f;
}
// normals
if (vboNormalsOffset_ != -1)
vboDecl_.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_NORMAL, size_t(vboNormalsOffset_));
else
{
// todo
// defaultNormal_;
}
// pointsizes
if (vboPointsizesOffset_ != -1)
vboDecl_.addElement(GL_FLOAT, 1, ACG::VERTEX_USAGE_TEXCOORD, size_t(vboPointsizesOffset_));
else
{
// todo
// glMultiTexCoord1f(GL_TEXTURE0, defaultPointsize_);
}
// selections
if (vboSelectionsOffset_ != -1)
vboDecl_.addElement(GL_FLOAT, 1, ACG::VERTEX_USAGE_SHADER_INPUT, size_t(vboSelectionsOffset_), "inSplatSelection");
else
{
// todo
// glMultiTexCoord1f(GL_TEXTURE1, 0.0f);
}
// pick colors
if (vboPickColorsOffset_ != -1)
vboDecl_.addElement(GL_UNSIGNED_BYTE, 4, ACG::VERTEX_USAGE_SHADER_INPUT, size_t(vboPickColorsOffset_), "inSplatPickColor");
else
{
// todo
// glColor4ub(255, 255, 255, 255);
}
vboDecl_.setVertexStride(vboStride_);
obj.vertexDecl = &vboDecl_;
// render:
// -------
// enable "pointsize by program" depending on current rendermode
if (rendermode == RENDERMODE_SPLATS || rendermode == RENDERMODE_DOTS)
{
ACG::Vec2f screenSize(_state.viewport_width(), _state.viewport_height());
// obj.setupPointRendering(defaultPointsize_, screenSize);
}
// setup shader
obj.shaderDesc.shadeMode = SG_SHADE_UNLIT;
// obj.shaderDesc.vertexTemplateFile = "SplatCloud_Splats/Vertex_shadergen.glsl";
// obj.shaderDesc.fragmentTemplateFile = "SplatCloud_Splats/Fragment_shadergen.glsl";
obj.shaderDesc.vertexTemplateFile = "SplatCloud_ShaderGen/splat_vs.glsl";
obj.shaderDesc.geometryTemplateFile = "SplatCloud_ShaderGen/splat_gs.glsl";
obj.shaderDesc.fragmentTemplateFile = "SplatCloud_ShaderGen/splat_fs.glsl";
// setup uniforms
/*
uniform float pointsizeScale = 1.0;
uniform bool backfaceCulling = false;
uniform float modelviewScale;
uniform float viewportScaleFov_y;
uniform mat4 g_mPInv;
uniform vec4 invViewportScale;
uniform vec4 invViewportTransp;
uniform float viewportScale_z;
uniform float viewportTransp_z;
*/
// get viewport
int left, bottom, width, height;
_state.get_viewport(left, bottom, width, height);
float x = (float)left;
float y = (float)bottom;
float w = (float)width;
float h = (float)height;
// get depthrange
// TODO: use glstate.get_depth_range when implemented
GLfloat depthRange[2];
glGetFloatv(GL_DEPTH_RANGE, depthRange);
float z = (float)depthRange[0];
float d = (float)depthRange[1] - z;
// check if we are safe
if (w <= 0.0f || h <= 0.0f || d <= 0.0f)
return;
// calculate window-coordinates to normalized-device-coordinates scale
ACG::Vec4f invVPs;
invVPs[0] = 2.0f / w;
invVPs[1] = 2.0f / h;
invVPs[2] = 2.0f / d;
invVPs[3] = 0.0f;
// calculate window-coordinates to normalized-device-coordinates transpose
ACG::Vec4f invVPt;
invVPt[0] = -(x * invVPs[0] + 1.0f);
invVPt[1] = -(y * invVPs[1] + 1.0f);
invVPt[2] = -(z * invVPs[2] + 1.0f);
invVPt[3] = 1.0f;
// calculate normalized-device-coordinates to window-coordinates scale and transpose
GLfloat VPs_z = 0.5f * d;
GLfloat VPt_z = z + VPs_z;
// calculate scaling factor of modelview matrix
static const double RCP_3 = 1.0 / 3.0;
const ACG::GLMatrixd &mv = _state.modelview();
double detMV = mv(0, 0) * (mv(1, 1)*mv(2, 2) - mv(1, 2)*mv(2, 1))
+ mv(0, 1) * (mv(1, 2)*mv(2, 0) - mv(1, 0)*mv(2, 2))
+ mv(0, 2) * (mv(1, 0)*mv(2, 1) - mv(1, 1)*mv(2, 0));
GLfloat MVs = (GLfloat)pow(fabs(detMV), RCP_3);
// calculate scale for pointsizes in eye-coordinates according to fovy and transformation to window-coordinates
GLfloat VPsFov_y = _state.projection()(1, 1) * (0.5f * h);
ACG::GLMatrixf projInv = _state.inverse_projection();
obj.setUniform("invViewportScale", invVPs);
obj.setUniform("invViewportTransp", invVPt);
obj.setUniform("viewportScale_z", VPs_z);
obj.setUniform("viewportTransp_z", VPt_z);
obj.setUniform("modelviewScale", MVs);
obj.setUniform("viewportScaleFov_y", VPsFov_y);
obj.setUniform("invProjection", projInv);
obj.setUniform("pointsizeScale", pointsizeScale_);
obj.setUniform("backfaceCulling", backfaceCulling_);
obj.setUniform("defaultPointsize", defaultPointsize_);
obj.setUniform("defaultNormal", defaultNormal_);
obj.programPointSize = true;
if (vboColorsOffset_ != -1)
obj.shaderDesc.vertexColors = true;
// draw as GLpoints
obj.glDrawArrays(GL_POINTS, 0, vboNumSplats_);
_renderer->addRenderObject(&obj);
}
}
//----------------------------------------------------------------
......@@ -398,7 +606,7 @@ void SplatCloudNode::rebuildVBO( GLState &_state )
// calculate size of data and offsets
unsigned int numSplats = splatCloud_.numSplats();
unsigned int size = 0;
unsigned int stride = 0;
int positionsOffset = -1;
int colorsOffset = -1;
......@@ -407,15 +615,15 @@ void SplatCloudNode::rebuildVBO( GLState &_state )
int selectionsOffset = -1;
int pickColorsOffset = -1;
if( splatCloud_.hasPositions() ) { positionsOffset = size; size += numSplats * 12; }
if( splatCloud_.hasColors() ) { colorsOffset = size; size += numSplats * 3; }
if( splatCloud_.hasNormals() ) { normalsOffset = size; size += numSplats * 12; }
if( splatCloud_.hasPointsizes() ) { pointsizesOffset = size; size += numSplats * 4; }
if( splatCloud_.hasSelections() ) { selectionsOffset = size; size += numSplats * 4; }
/* has pick colors is true */ { pickColorsOffset = size; size += numSplats * 4; }
if( splatCloud_.hasPositions() ) { positionsOffset = stride; stride += 12; }
if( splatCloud_.hasColors() ) { colorsOffset = stride; stride += 3; }
if( splatCloud_.hasNormals() ) { normalsOffset = stride; stride += 12; }
if( splatCloud_.hasPointsizes() ) { pointsizesOffset = stride; stride += 4; }
if( splatCloud_.hasSelections() ) { selectionsOffset = stride; stride += 4; }
/* has pick colors is true */ { pickColorsOffset = stride; stride += 4; }
// tell GL that we are seldomly updating the VBO but are often drawing it
glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, 0, GL_STATIC_DRAW_ARB );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, static_cast<GLsizei>(stride * numSplats), 0, GL_STATIC_DRAW_ARB );
// get pointer to VBO memory
unsigned char *data = (unsigned char *) glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB );
......@@ -433,6 +641,7 @@ void SplatCloudNode::rebuildVBO( GLState &_state )
{
vboNumSplats_ = numSplats;
vboData_ = data;
vboStride_ = stride;
vboPositionsOffset_ = positionsOffset;
vboColorsOffset_ = colorsOffset;
......@@ -551,6 +760,7 @@ void SplatCloudNode::rebuildVBOPositions()
{
// add position
const Position &p = getPosition( i );
buffer = vboData_ + vboPositionsOffset_ + i * vboStride_;
addFloatToBuffer( p[0], buffer );
addFloatToBuffer( p[1], buffer );
addFloatToBuffer( p[2], buffer );
......@@ -579,6 +789,8 @@ void SplatCloudNode::rebuildVBOColors()
{
// add color
const Color &c = getColor( i );
buffer = vboData_ + vboColorsOffset_ + i * vboStride_;
addUCharToBuffer( c[0], buffer );
addUCharToBuffer( c[1], buffer );
addUCharToBuffer( c[2], buffer );
......@@ -607,6 +819,8 @@ void SplatCloudNode::rebuildVBONormals()
{
// add normal
const Normal &n = getNormal( i );
buffer = vboData_ + vboNormalsOffset_ + i * vboStride_;
addFloatToBuffer( n[0], buffer );
addFloatToBuffer( n[1], buffer );
addFloatToBuffer( n[2], buffer );
......@@ -635,7 +849,9 @@ void SplatCloudNode::rebuildVBOPointsizes()
{
// add pointsize
const Pointsize &ps = getPointsize( i );
addFloatToBuffer( ps, buffer );
buffer = vboData_ + vboPointsizesOffset_ + i * vboStride_;
addFloatToBuffer(ps, buffer);
}
}
......@@ -660,7 +876,9 @@ void SplatCloudNode::rebuildVBOSelections()
for( i=0; i<num; ++i )
{
const bool &s = getSelection( i );
addFloatToBuffer( (s ? 1.0f : 0.0f), buffer );
buffer = vboData_ + vboSelectionsOffset_ + i * vboStride_;
addFloatToBuffer((s ? 1.0f : 0.0f), buffer);
}
}
......@@ -686,6 +904,8 @@ void SplatCloudNode::rebuildVBOPickColors( GLState &_state )
{
// add pick color
const Vec4uc &pc = _state.pick_get_name_color( i );
buffer = vboData_ + vboPickColorsOffset_ + i * vboStride_;
addUCharToBuffer( pc[0], buffer );
addUCharToBuffer( pc[1], buffer );
addUCharToBuffer( pc[2], buffer );
......
......@@ -75,6 +75,7 @@
#include <ACG/GL/gl.hh>
#include <ACG/GL/VertexDeclaration.hh>
//== NAMESPACES ==================================================
......@@ -126,6 +127,9 @@ public:
/// draw the SplatCloud
void draw( GLState &_state, const DrawModes::DrawMode &_drawMode );
/// create render objects
void getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat );
/// picking
void pick( GLState &_state, PickTarget _target );
......@@ -174,6 +178,12 @@ public:
inline const Viewlist &getViewlist ( int _idx ) const { return splatCloud_.hasViewlists() ? splatCloud_.viewlists ( _idx ) : DEFAULT_VIEWLIST; }
inline const Selection &getSelection( int _idx ) const { return splatCloud_.hasSelections() ? splatCloud_.selections( _idx ) : DEFAULT_SELECTION; }
// ---- render object params ----
inline void setPointsizeScale(float _scale) { pointsizeScale_ = _scale; }
inline void setBackfaceCulling(bool _enable) { backfaceCulling_ = _enable; }
//----------------------------------------------------------------
private:
......@@ -229,6 +239,7 @@ private:
GLuint vboGlId_;
unsigned int vboNumSplats_;
unsigned char *vboData_;
unsigned int vboStride_;
/// offsets relative to vboData_ or -1 if *not* present in VBO
int vboPositionsOffset_;
......@@ -238,6 +249,8 @@ private:
int vboSelectionsOffset_;
int vboPickColorsOffset_;
ACG::VertexDeclaration vboDecl_;
/// returns true iff the internal block structure of the VBO has to be changed
inline bool vboStructureModified() const
{
......@@ -264,6 +277,11 @@ private:
static const Index DEFAULT_INDEX;
static const Viewlist DEFAULT_VIEWLIST;
static const Selection DEFAULT_SELECTION;
// ---- rendering params ----
float pointsizeScale_;
bool backfaceCulling_;
};
......
......@@ -267,6 +267,8 @@ void SplatCloudObject::reloadShaders()
*/
void SplatCloudObject::enableBackfaceCulling( bool _enable )
{
splatCloudNode_->setBackfaceCulling(_enable);
// get drawmodes
ACG::SceneGraph::DrawModes::DrawMode splatsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Splats" );
ACG::SceneGraph::DrawModes::DrawMode dotsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Dots" );
......@@ -346,6 +348,8 @@ void SplatCloudObject::enableBackfaceCulling( bool _enable )
*/
void SplatCloudObject::setPointsizeScale( float _scale )
{
splatCloudNode_->setPointsizeScale(_scale);
// get drawmodes
ACG::SceneGraph::DrawModes::DrawMode splatsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Splats" );
ACG::SceneGraph::DrawModes::DrawMode dotsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Dots" );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment