Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Adding B-Spline curves for ribbon via tessellation shaders. #1706

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions avogadro/rendering/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ set(shader_files
"linestrip_fs.glsl"
"linestrip_vs.glsl"
"mesh_fs.glsl"
"bspline_tev.glsl"
"bspline_tcs.glsl"
"bspline_fs.glsl"
"bspline_vs.glsl"
"mesh_opaque_fs.glsl"
"mesh_vs.glsl"
"solid_vs.glsl"
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
154 changes: 152 additions & 2 deletions avogadro/rendering/cartoongeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,174 @@
******************************************************************************/

#include "cartoongeometry.h"
#include "shader.h"
#include "shaderprogram.h"
#include "camera.h"
#include "bufferobject.h"



#include <cmath>

namespace {

#include "bspline_vs.h"
#include "bspline_fs.h"
#include "bspline_tcs.h"
#include "bspline_tev.h"

} // namespace

using Avogadro::Vector3f;
using Avogadro::Vector3ub;
using Avogadro::Vector4ub;

namespace Avogadro::Rendering {

class Cartoon::Private
{
public:
Private() {}

Check warning on line 34 in avogadro/rendering/cartoongeometry.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/rendering/cartoongeometry.cpp#L34

Member variable 'Private::numberOfVertices' is not initialized in the constructor.

BufferObject vbo;
BufferObject ibo;

inline static Shader* vertexShader = nullptr;
inline static Shader* fragmentShader = nullptr;
inline static Shader* fragmentShaderOpaque = nullptr;

Check notice on line 41 in avogadro/rendering/cartoongeometry.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/rendering/cartoongeometry.cpp#L41

class member 'Private::fragmentShaderOpaque' is never used.
inline static ShaderProgram* program = nullptr;
inline static ShaderProgram* programOpaque = nullptr;

size_t numberOfVertices;
size_t numberOfIndices;
};


using Core::Residue;
using std::vector;

const float Cartoon::ELIPSE_RATIO = 0.75f;

Cartoon::Cartoon()
: BSplineGeometry(false), m_minRadius(-1.0f), m_maxRadius(-1.0f)
: BSplineGeometry(false), m_minRadius(-1.0f), m_maxRadius(-1.0f), m_dirty(false), d(new Private)
{}

Cartoon::Cartoon(float minRadius, float maxRadius)
: BSplineGeometry(false), m_minRadius(minRadius), m_maxRadius(maxRadius)
: BSplineGeometry(false), m_minRadius(minRadius), m_maxRadius(maxRadius), m_dirty(true),
d(new Private), m_vertices(other.m_vertices), m_indices(other.m_indices)
{}

Cartoon::~Cartoon()
{
delete d;
}

void Cartoon::update()
{
if (m_vertices.empty() || m_indices.empty())
return;

// Check if the VBOs are ready, if not get them ready.
if (!d->vbo.ready() || m_dirty) {
d->vbo.upload(m_vertices, BufferObject::ArrayBuffer);
d->ibo.upload(m_indices, BufferObject::ElementArrayBuffer);
d->numberOfVertices = m_vertices.size();
d->numberOfIndices = m_indices.size();
m_dirty = false;
}

// Build and link the shader if it has not been used yet.
if (d->vertexShader == nullptr) {
d->vertexShader = new Shader;
d->vertexShader->setType(Shader::Vertex);
d->vertexShader->setSource(bspline_vs);

d->fragmentShader = new Shader;
d->fragmentShader->setType(Shader::Fragment);
d->fragmentShader->setSource(bspline_fs);

if (!d->vertexShader->compile())
std::cout << d->vertexShader->error() << std::endl;
if (!d->fragmentShader->compile())
std::cout << d->fragmentShader->error() << std::endl;

if (d->program == nullptr)
d->program = new ShaderProgram;
d->program->attachShader(*d->vertexShader);
d->program->attachShader(*d->fragmentShader);
if (!d->program->link())
std::cout << d->program->error() << std::endl;
}
}

void Cartoon::render(const Camera& camera)
{
if (m_indices.empty() || m_vertices.empty())
return;

// Prepare the VBOs, IBOs and shader program if necessary.
update();

ShaderProgram* program;
program = d->programOpaque;

if (!program->bind())
std::cout << program->error() << std::endl;

d->vbo.bind();
d->ibo.bind();

// Set up our attribute arrays.
if (!program->enableAttributeArray("vertex"))
std::cout << program->error() << std::endl;
if (!program->useAttributeArray("vertex", PackedVertex::vertexOffset(),
sizeof(PackedVertex), FloatType, 3,
ShaderProgram::NoNormalize)) {
std::cout << program->error() << std::endl;
}
if (!program->enableAttributeArray("color"))
std::cout << program->error() << std::endl;
if (!program->useAttributeArray("color", PackedVertex::colorOffset(),
sizeof(PackedVertex), UCharType, 4,
ShaderProgram::Normalize)) {
std::cout << program->error() << std::endl;
}
if (!program->enableAttributeArray("normal"))
std::cout << program->error() << std::endl;
if (!program->useAttributeArray("normal", PackedVertex::normalOffset(),
sizeof(PackedVertex), FloatType, 3,
ShaderProgram::NoNormalize)) {
std::cout << program->error() << std::endl;
}

// Set up our uniforms (model-view and projection matrices right now).
if (!program->setUniformValue("modelView", camera.modelView().matrix())) {
std::cout << program->error() << std::endl;
}
if (!program->setUniformValue("projection", camera.projection().matrix())) {
std::cout << program->error() << std::endl;
}
Matrix3f normalMatrix = camera.modelView().linear().inverse().transpose();
if (!program->setUniformValue("normalMatrix", normalMatrix))
std::cout << program->error() << std::endl;

// Render the loaded spheres using the shader and bound VBO.
glDrawRangeElements(GL_TRIANGLES, 0,
static_cast<GLuint>(d->numberOfVertices - 1),
static_cast<GLsizei>(d->numberOfIndices), GL_UNSIGNED_INT,
reinterpret_cast<const GLvoid*>(0));

d->vbo.release();
d->ibo.release();

program->disableAttributeArray("vertex");
program->disableAttributeArray("color");
program->disableAttributeArray("normal");

program->release();
}


vector<ColorNormalVertex> Cartoon::computeCirclePoints(const Eigen::Affine3f& a,
const Eigen::Affine3f& b,
bool flat) const
Expand Down
26 changes: 26 additions & 0 deletions avogadro/rendering/cartoongeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,30 @@

class AVOGADRORENDERING_EXPORT Cartoon : public BSplineGeometry
{

public:
struct PackedVertex
{
Vector4ub color; // 4 bytes
Vector3f normal; // 12 bytes
Vector3f vertex; // 12 bytes
unsigned char padding[4]; // 4 bytes

Check notice on line 34 in avogadro/rendering/cartoongeometry.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/rendering/cartoongeometry.h#L34

struct member 'PackedVertex::padding' is never used.

PackedVertex(const Vector4ub& c, const Vector3f& n, const Vector3f& v)

Check warning on line 36 in avogadro/rendering/cartoongeometry.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/rendering/cartoongeometry.h#L36

Member variable 'PackedVertex::padding' is not initialized in the constructor.
: color(c)
, normal(n)
, vertex(v)
{}

static int colorOffset() { return 0; }
static int normalOffset() { return static_cast<int>(sizeof(Vector4ub)); }
static int vertexOffset()
{
return normalOffset() + static_cast<int>(sizeof(Vector3f));
}
}; // 32 bytes total size - 16/32/64 are ideal for alignment.


Cartoon();
Cartoon(float minRadius, float maxRadius);
static const float ELIPSE_RATIO;
Expand All @@ -39,6 +62,9 @@
bool flat) const override;

float computeScale(size_t index, float t, float scale) const override;
void render(const Camera& camera) override;
void update();


std::vector<std::pair<CartoonType, size_t>> m_type;
float m_minRadius, m_maxRadius;
Expand Down
22 changes: 20 additions & 2 deletions avogadro/rendering/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,25 @@ bool Shader::compile()
m_handle = 0;
}

GLenum type_ = m_type == Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;
GLenum type_;
switch (m_type) {
case Vertex:
type_ = GL_VERTEX_SHADER;
break;
case Fragment:
type_ = GL_FRAGMENT_SHADER;
break;
case TessellationControl:
type_ = GL_TESS_CONTROL_SHADER;
break;
case TessellationEvaluation:
type_ = GL_TESS_EVALUATION_SHADER;
break;
default:
m_error = "Unknown shader type.";
return false;
}

GLuint handle_ = glCreateShader(type_);
const auto* source_ = static_cast<const GLchar*>(m_source.c_str());
glShaderSource(handle_, 1, &source_, nullptr);
Expand Down Expand Up @@ -80,4 +98,4 @@ void Shader::cleanup()
m_dirty = false;
}

} // End Avogadro namespace
} // End Avogadro namespace
4 changes: 3 additions & 1 deletion avogadro/rendering/shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class AVOGADRORENDERING_EXPORT Shader
{
Vertex, /**< Vertex shader */
Fragment, /**< Fragment shader */
TessellationControl,
TessellationEvaluation,
Unknown /**< Unknown (default) */
};

Expand Down Expand Up @@ -78,4 +80,4 @@ class AVOGADRORENDERING_EXPORT Shader
} // End Rendering namespace
} // End Avogadro namespace

#endif // AVOGADRO_RENDERING_SHADER_H
#endif // AVOGADRO_RENDERING_SHADER_H
37 changes: 35 additions & 2 deletions avogadro/rendering/shaderprogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ inline GLenum lookupTextureUnit(GLint index)
} // end anon namespace

ShaderProgram::ShaderProgram()
: m_handle(0), m_vertexShader(0), m_fragmentShader(0), m_linked(false)
: m_handle(0), m_vertexShader(0), m_fragmentShader(0), m_linked(false),
m_tcsShader(0), m_tevShader(0)
{
initializeTextureUnits();
}
Expand Down Expand Up @@ -129,6 +130,18 @@ bool ShaderProgram::attachShader(const Shader& shader)
static_cast<GLuint>(m_fragmentShader));
}
m_fragmentShader = shader.handle();
} else if(shader.type() == Shader::TessellationControl) {
if (m_tcsShader != 0){
glDetachShader(static_cast<GLuint>(m_handle),
static_cast<GLuint>(m_tcsShader));
}
m_tcsShader = shader.handle();
} else if(shader.type() == Shader::TessellationEvaluation) {
if (m_tevShader != 0){
glDetachShader(static_cast<GLuint>(m_handle),
static_cast<GLuint>(m_tevShader));
}
m_tevShader = shader.handle();
} else {
m_error = "Unknown shader type encountered - this should not happen.";
return false;
Expand Down Expand Up @@ -175,6 +188,26 @@ bool ShaderProgram::detachShader(const Shader& shader)
m_fragmentShader = 0;
return true;
}
case Shader::TessellationControl:
if(m_tcsShader != shader.handle()){
m_error = "The supplied shader was not attached to this program.";
return false;
} else{
glDetachShader(static_cast<GLuint>(m_handle),
static_cast<GLuint>(shader.handle()));
m_tcsShader = 0;
return true;
}
case Shader::TessellationEvaluation:
if(m_tevShader != shader.handle()){
m_error = "The supplied shader was not attached to this program.";
return false;
} else{
glDetachShader(static_cast<GLuint>(m_handle),
static_cast<GLuint>(shader.handle()));
m_tevShader = 0;
return true;
}
default:
return false;
}
Expand Down Expand Up @@ -476,4 +509,4 @@ inline int ShaderProgram::findUniform(const std::string& name)
return location;
}

} // End Avogadro namespace
} // End Avogadro namespace
4 changes: 3 additions & 1 deletion avogadro/rendering/shaderprogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ class AVOGADRORENDERING_EXPORT ShaderProgram
Index m_handle;
Index m_vertexShader;
Index m_fragmentShader;
Index m_tcsShader;
Index m_tevShader;

bool m_linked;

Expand Down Expand Up @@ -193,4 +195,4 @@ inline bool ShaderProgram::setAttributeArray(const std::string& name,
} // End Rendering namespace
} // End Avogadro namespace

#endif // AVOGADRO_RENDERING_SHADERPROGRAM_H
#endif // AVOGADRO_RENDERING_SHADERPROGRAM_H
Loading