Skip to content

Commit

Permalink
preparing for drawing points as instances
Browse files Browse the repository at this point in the history
  • Loading branch information
wkjarosz committed Dec 26, 2023
1 parent ecb142e commit 7e71ba6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 24 deletions.
2 changes: 1 addition & 1 deletion assets/shaders/points.frag
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ uniform float point_size;
void main()
{
float alpha = 1.0;
if (point_size > 3.0)
// if (point_size > 3.0)
{
vec2 circCoord = 2.0 * gl_PointCoord - 1.0;
float radius2 = dot(circCoord, circCoord);
Expand Down
37 changes: 20 additions & 17 deletions include/shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,24 +128,21 @@ class Shader
template <typename T>
void set_uniform(const std::string &name, const T &value)
{
size_t shape[3] = {1, 1, 1};
size_t ndim = (size_t)-1;
const void *data;
VariableType vtype = VariableType::Invalid;

size_t shape[3] = {1, 1, 1};
if constexpr (std::is_scalar_v<T>)
{
data = &value;
ndim = 0;
vtype = get_type<T>();
}

if (ndim == (size_t)-1)
set_buffer(name, get_type<T>(), 0, shape, &value);
else
throw std::runtime_error("Shader::set_uniform(): invalid input array dimension!");

set_buffer(name, vtype, ndim, shape, data);
}

/**
Set the "rate at which generic vertex attributes advance when rendering multiple instances"
see:
https://registry.khronos.org/OpenGL-Refpages/es3/html/glVertexAttribDivisor.xhtml
https://registry.khronos.org/OpenGL-Refpages/gl4/html/glVertexAttribDivisor.xhtml
*/
void set_buffer_divisor(const std::string &name, size_t divisor);

// /**
// * \brief Associate a texture with a named shader parameter
// *
Expand Down Expand Up @@ -185,8 +182,13 @@ class Shader
\param indexed
Render indexed geometry? In this case, an \c uint32_t valued buffer with name \c indices must have been
uploaded using \ref set().
\param instances
If you want to render instances, set this to > 0. In this case, make sure to call \ref set_buffer_divisor()
for each registered buffer beforehand to inform the shader how the instances should access the buffers.
*/
void draw_array(PrimitiveType primitive_type, size_t offset, size_t count, bool indexed = false);
void draw_array(PrimitiveType primitive_type, size_t offset, size_t count, bool indexed = false,
size_t instances = 0u);

#if defined(HELLOIMGUI_HAS_OPENGL)
uint32_t shader_handle() const
Expand Down Expand Up @@ -229,8 +231,9 @@ class Shader
int index = 0;
size_t ndim = 0;
size_t shape[3]{0, 0, 0};
size_t size = 0;
bool dirty = false;
size_t size = 0;
size_t instance_divisor = 0;
bool dirty = false;

std::string to_string() const;
};
Expand Down
32 changes: 26 additions & 6 deletions src/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

#include <fmt/core.h>

#include <iostream>

using std::string;

bool check_glerror(const char *cmd)
Expand Down Expand Up @@ -382,6 +380,16 @@ void Shader::set_buffer(const std::string &name, VariableType dtype, size_t ndim
buf.dirty = true;
}

void Shader::set_buffer_divisor(const std::string &name, size_t divisor)
{
auto it = m_buffers.find(name);
if (it == m_buffers.end())
throw std::runtime_error("Shader::set_buffer(): could not find argument named \"" + name + "\"");

Buffer &buf = m_buffers[name];
buf.instance_divisor = divisor;
}

// void Shader::set_texture(const std::string &name, Texture *texture)
// {
// auto it = m_buffers.find(name);
Expand Down Expand Up @@ -454,6 +462,7 @@ void Shader::begin()
std::to_string(buf.ndim) + ")");

CHK(glVertexAttribPointer(buf.index, (GLint)buf.shape[1], gl_type, GL_FALSE, 0, nullptr));
CHK(glVertexAttribDivisor(buf.index, (GLuint)buf.instance_divisor));
break;

case VertexTexture:
Expand Down Expand Up @@ -617,7 +626,7 @@ void Shader::end()
CHK(glUseProgram(0));
}

void Shader::draw_array(PrimitiveType primitive_type, size_t offset, size_t count, bool indexed)
void Shader::draw_array(PrimitiveType primitive_type, size_t offset, size_t count, bool indexed, size_t instances)
{
GLenum primitive_type_gl;
switch (primitive_type)
Expand All @@ -633,10 +642,21 @@ void Shader::draw_array(PrimitiveType primitive_type, size_t offset, size_t coun
}

if (!indexed)
CHK(glDrawArrays(primitive_type_gl, (GLint)offset, (GLsizei)count));
{
if (instances == 0)
CHK(glDrawArrays(primitive_type_gl, (GLint)offset, (GLsizei)count));
else
CHK(glDrawArraysInstanced(primitive_type_gl, (GLint)offset, (GLsizei)count, instances));
}
else
CHK(glDrawElements(primitive_type_gl, (GLsizei)count, GL_UNSIGNED_INT,
(const void *)(offset * sizeof(uint32_t))));
{
if (instances == 0)
CHK(glDrawElements(primitive_type_gl, (GLsizei)count, GL_UNSIGNED_INT,
(const void *)(offset * sizeof(uint32_t))));
else
CHK(glDrawElementsInstanced(primitive_type_gl, (GLsizei)count, GL_UNSIGNED_INT,
(const void *)(offset * sizeof(uint32_t)), instances));
}
}

std::string Shader::Buffer::to_string() const
Expand Down

0 comments on commit 7e71ba6

Please sign in to comment.