- attributes objects track their offset in the VBO
- call to glVertexAttribPointer moved from VBO class to Attributes class - added a public domain function for computing bezier points
This commit is contained in:
parent
9ed0e9ea71
commit
2f7a4cb602
|
@ -39,6 +39,11 @@ GLint sb::Attributes::index() const
|
|||
return attribute_index;
|
||||
}
|
||||
|
||||
void sb::Attributes::offset(GLintptr offset)
|
||||
{
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
/* Returns the count of attributes */
|
||||
std::size_t sb::Attributes::count() const
|
||||
{
|
||||
|
@ -55,18 +60,6 @@ std::size_t sb::Attributes::count() const
|
|||
}, vertices);
|
||||
}
|
||||
|
||||
/* Enable the attributes in the VAO. */
|
||||
void sb::Attributes::enable() const
|
||||
{
|
||||
glEnableVertexAttribArray(*this);
|
||||
}
|
||||
|
||||
/* Disable the attributes in the VAO. */
|
||||
void sb::Attributes::disable() const
|
||||
{
|
||||
glDisableVertexAttribArray(*this);
|
||||
}
|
||||
|
||||
/* Returns the size in bytes of the object's underlying vector of vertices. This can be passed to OpenGL
|
||||
* along with the memory pointer when copying vertices to the GPU. */
|
||||
std::size_t sb::Attributes::size() const
|
||||
|
@ -84,23 +77,20 @@ std::size_t sb::Attributes::size() const
|
|||
}, vertices);
|
||||
}
|
||||
|
||||
/* Set the index to the location of attributes with given name in a shader program. The program
|
||||
* must already be linked to get the location. */
|
||||
void sb::Attributes::bind(GLuint program, const std::string& name)
|
||||
void sb::Attributes::bind(const std::string& name, GLuint program)
|
||||
{
|
||||
index(glGetAttribLocation(program, name.c_str()));
|
||||
std::ostringstream message;
|
||||
message << "index for " << name << " is " << index();
|
||||
sb::Log::log(message, sb::Log::DEBUG);
|
||||
glVertexAttribPointer(index(), dimensions(), type(), normalized(), 0, reinterpret_cast<GLvoid*>(_offset));
|
||||
}
|
||||
|
||||
/* Set the index and bind it to the given name in a shader program. This should be called before
|
||||
* the shader program is linked, otherwise the name will already have been assigned a location
|
||||
* index by GL. */
|
||||
void sb::Attributes::bind(std::uint32_t index, GLuint program, const std::string& name)
|
||||
void sb::Attributes::enable() const
|
||||
{
|
||||
glBindAttribLocation(program, index, name.c_str());
|
||||
this->index(index);
|
||||
glEnableVertexAttribArray(*this);
|
||||
}
|
||||
|
||||
void sb::Attributes::disable() const
|
||||
{
|
||||
glDisableVertexAttribArray(*this);
|
||||
}
|
||||
|
||||
/* Return the GLenum that corresponds to the type of scalar being held in the vertices. This
|
||||
|
|
|
@ -131,6 +131,7 @@ namespace sb
|
|||
std::vector<glm::bvec4>, std::vector<glm::uvec4>, std::vector<glm::ivec4>, std::vector<glm::vec4>>;
|
||||
Vertices vertices;
|
||||
GLint attribute_index = 0;
|
||||
GLintptr _offset = 0;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -272,10 +273,40 @@ namespace sb
|
|||
void extend(const Attributes&, std::size_t = 1);
|
||||
void index(GLint);
|
||||
GLint index() const;
|
||||
void bind(GLuint, const std::string&);
|
||||
void bind(std::uint32_t, GLuint, const std::string&);
|
||||
|
||||
/*!
|
||||
* Set the byte offset into the VBO where this object's vertex data is stored. This can be set by passing this object to
|
||||
* `VBO::add`.
|
||||
*
|
||||
* @param offset byte offset in the VBO where this object's vertex data is stored
|
||||
*/
|
||||
void offset(GLintptr offset);
|
||||
|
||||
/*!
|
||||
* Get the index of the uniform with the given name, store it as this object's index, and create a pointer to these
|
||||
* attributes in the VAO using this object's offset value.
|
||||
*
|
||||
* The offset should have been previously set by a call to `VBO::add` or some equivalent in manual GL calls. The program
|
||||
* must already be linked to get the location.
|
||||
*
|
||||
* @param name uniform name
|
||||
* @param program GLSL program, created with glCreateProgram
|
||||
*/
|
||||
void bind(const std::string& name, GLuint program);
|
||||
|
||||
/*!
|
||||
* Enable the attributes in the VAO associated with this object's index. `Attributes::bind` must have been called previously,
|
||||
* unless the index has been set up manually with direct calls to GL.
|
||||
*
|
||||
* The object's current index is used refer to the pointer.
|
||||
*/
|
||||
void enable() const;
|
||||
|
||||
/*!
|
||||
* Disable the attributes in the VAO associated with this object's index.
|
||||
*/
|
||||
void disable() const;
|
||||
|
||||
std::size_t size() const;
|
||||
std::size_t count() const;
|
||||
GLenum type() const;
|
||||
|
|
|
@ -122,7 +122,7 @@ sb::Texture& sb::Model::texture(const std::string& name)
|
|||
else if (textures().find(name) == textures().end())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "No texture named " << name << " attached to this model.";
|
||||
message << "No texture named " << name << " found attached to this model.";
|
||||
throw std::out_of_range(message.str());
|
||||
}
|
||||
else
|
||||
|
|
|
@ -130,14 +130,19 @@ namespace sb
|
|||
|
||||
public:
|
||||
|
||||
/* A plane in the X and Y dimensions, from (-1.0, -1.0) to (1.0, 1.0) */
|
||||
inline const static std::shared_ptr<sb::Attributes> position = std::make_shared<sb::Attributes>(sb::Attributes{
|
||||
{-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f},
|
||||
{1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f}
|
||||
});
|
||||
|
||||
/* Map a texture to fill the plane */
|
||||
inline const static std::shared_ptr<sb::Attributes> uv = std::make_shared<sb::Attributes>(sb::Attributes{
|
||||
{0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f},
|
||||
{1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f}
|
||||
});
|
||||
|
||||
/* A gradient from magenta to yellow */
|
||||
inline const static std::shared_ptr<sb::Attributes> color = std::make_shared<sb::Attributes>(sb::Attributes{
|
||||
{1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {0.8f, 0.0f, 0.3f},
|
||||
{1.0f, 1.0f, 0.0f}, {0.8f, 0.0f, 0.3f}, {0.8f, 0.0f, 0.3f}
|
||||
|
|
23
src/VBO.cpp
23
src/VBO.cpp
|
@ -29,33 +29,18 @@ void VBO::allocate(GLsizeiptr size, GLenum usage)
|
|||
sb::Log::gl_errors(message.str());
|
||||
}
|
||||
|
||||
/* Set memory in the GPU buffer to the values of the attribute data using glBufferSubData. The memory
|
||||
* set is a contiguous area from the object's current byte offset value to the offset plus the size in
|
||||
* bytes of the attributes. After the memory is set, the offset is updated to point to the end of the
|
||||
* area.
|
||||
*
|
||||
* Define an array of vertex attribute data on the GPU by passing the attributes's index, dimensions,
|
||||
* normalization state, and type to glVertexAttribPointer, along with the buffer object's current
|
||||
* offset.
|
||||
*
|
||||
* The updated offset is returned and can be used to independently keep track of where the next
|
||||
* attributes will be stored in the buffer and apply to direct usage of glBufferSubData. */
|
||||
GLintptr VBO::add(sb::Attributes& attributes)
|
||||
{
|
||||
/* Set memory */
|
||||
glBufferSubData(target(), offset, attributes.size(), attributes);
|
||||
attributes.offset(offset);
|
||||
|
||||
/* Debug */
|
||||
std::ostringstream initialization_message;
|
||||
initialization_message << "After setting " << attributes.size() << "bytes in " << *this;
|
||||
sb::Log::gl_errors(initialization_message.str());
|
||||
/* Define array */
|
||||
glVertexAttribPointer(
|
||||
attributes.index(), attributes.dimensions(), attributes.type(), attributes.normalized(), 0, reinterpret_cast<GLvoid*>(offset));
|
||||
/* Debug */
|
||||
std::ostringstream pointer_message;
|
||||
pointer_message << "After defining pointer for " << attributes;
|
||||
sb::Log::gl_errors(pointer_message.str());
|
||||
/* Increase offset */
|
||||
|
||||
/* Increase offset and return */
|
||||
offset += attributes.size();
|
||||
return offset;
|
||||
}
|
||||
|
|
15
src/VBO.hpp
15
src/VBO.hpp
|
@ -51,7 +51,22 @@ namespace sb
|
|||
|
||||
VBO();
|
||||
void allocate(GLsizeiptr, GLenum);
|
||||
|
||||
/*!
|
||||
* Set memory in the GPU buffer to the values of the attribute data using glBufferSubData. The memory
|
||||
* is a contiguous area from the object's current byte offset value to the offset plus the size in
|
||||
* bytes of the attributes. After the memory is set, the offset is updated to point to the end of the
|
||||
* area.
|
||||
*
|
||||
* The offset is stored in the sb::Attributes object, so the object can associate the vertex data with
|
||||
* the VAO by passing the offset along when it calls glVertexAttribPointer in its sb::Attributes::bind
|
||||
* method.
|
||||
*
|
||||
* @param attributes vertices to be added to the vertex buffer, wrapped in a sb::Attributes object
|
||||
* @return the new offset that indicates the end of the vertex buffer
|
||||
*/
|
||||
GLintptr add(sb::Attributes&);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&, const VBO&);
|
||||
|
||||
};
|
||||
|
|
62
src/math.cpp
62
src/math.cpp
|
@ -1,3 +1,13 @@
|
|||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
||||
#include "math.hpp"
|
||||
|
||||
glm::vec2 sb::velocity_to_delta(float angle, float magnitude)
|
||||
|
@ -24,3 +34,55 @@ float sb::angle_ratio(float start, float end)
|
|||
{
|
||||
return sb::angle_difference(start, end) / glm::pi<float>();
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> sb::bezier(const std::vector<glm::vec2> control, int resolution)
|
||||
{
|
||||
std::vector<glm::vec2> points;
|
||||
points.reserve(resolution);
|
||||
|
||||
float b0x = control[0][0];
|
||||
float b0y = control[0][1];
|
||||
float b1x = control[1][0];
|
||||
float b1y = control[1][1];
|
||||
float b2x = control[2][0];
|
||||
float b2y = control[2][1];
|
||||
float b3x = control[3][0];
|
||||
float b3y = control[3][1];
|
||||
|
||||
float ax = -b0x + 3.0f * b1x + -3.0f * b2x + b3x;
|
||||
float ay = -b0y + 3.0f * b1y + -3.0f * b2y + b3y;
|
||||
float bx = 3.0f * b0x + -6.0f * b1x + 3.0f * b2x;
|
||||
float by = 3.0f * b0y + -6.0f * b1y + 3.0f * b2y;
|
||||
float cx = -3.0f * b0x + 3.0f * b1x;
|
||||
float cy = -3.0f * b0y + 3.0f * b1y;
|
||||
float dx = b0x;
|
||||
float dy = b0y;
|
||||
|
||||
float steps = resolution - 1;
|
||||
float h = 1.0f / steps;
|
||||
|
||||
float pointX = dx;
|
||||
float pointY = dy;
|
||||
|
||||
float firstFDX = ax * std::pow(h, 3.0f) + bx * std::pow(h, 2.0f) + cx * h;
|
||||
float firstFDY = ay * std::pow(h, 3.0f) + by * std::pow(h, 2.0f) + cy * h;
|
||||
float secondFDX = 6 * ax * std::pow(h, 3.0f) + 2 * bx * std::pow(h, 2.0f);
|
||||
float secondFDY = 6 * ay * std::pow(h, 3.0f) + 2 * by * std::pow(h, 2.0f);
|
||||
float thirdFDX = 6 * ax * std::pow(h, 3.0f);
|
||||
float thirdFDY = 6 * ay * std::pow(h, 3.0f);
|
||||
|
||||
points.push_back({pointX, pointY});
|
||||
|
||||
for (int ii = 0; ii < steps; ii++)
|
||||
{
|
||||
pointX += firstFDX;
|
||||
pointY += firstFDY;
|
||||
firstFDX += secondFDX;
|
||||
firstFDY += secondFDY;
|
||||
secondFDX += thirdFDX;
|
||||
secondFDY += thirdFDY;
|
||||
points.push_back({pointX, pointY});
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
|
68
src/math.hpp
68
src/math.hpp
|
@ -1,46 +1,46 @@
|
|||
/* /\ +--------------------------------------------------------------+
|
||||
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - originally created at [https://shampoo.ooo] |
|
||||
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+--------------+
|
||||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+--------------+
|
||||
|
||||
[math.hpp]
|
||||
[math.hpp]
|
||||
|
||||
For math helper functions that require only GLM primitives, especially trigonometric functions.
|
||||
Angle values are in radians. 0 is directly up on the screen in GL coordinates, and the angle increases
|
||||
clockwise.
|
||||
For math helper functions that require only GLM primitives, especially trigonometric functions.
|
||||
Angle values are in radians. 0 is directly up on the screen in GL coordinates, and the angle increases
|
||||
clockwise.
|
||||
|
||||
This test of points on a square and one point below the square should print the output below it:
|
||||
This test of points on a square and one point below the square should print the output below.
|
||||
|
||||
glm::vec2 a {5.0f, 5.0f}, b {1.0f, 1.0f}, c {1.0f, 5.0f}, d {5.0f, 1.0f}, e {5.0f, -1.0f};
|
||||
std::cout << glm::degrees(sb::angle_between(a, b)) << " " << glm::degrees(sb::angle_between(b, a)) << " " <<
|
||||
glm::degrees(sb::angle_between(a, c)) << " " << glm::degrees(sb::angle_between(c, a)) << " " <<
|
||||
glm::degrees(sb::angle_between(b, e)) << " " << glm::degrees(sb::angle_between(e, b)) << std::endl <<
|
||||
sb::velocity_to_delta(sb::angle_between(a, b), 4.0f * glm::sqrt(2.0f)) << " " <<
|
||||
sb::velocity_to_delta(sb::angle_between(b, a), 4.0f * glm::sqrt(2.0f)) << " " <<
|
||||
sb::velocity_to_delta(sb::angle_between(d, a), 4.0f) << " " <<
|
||||
sb::velocity_to_delta(sb::angle_between(b, e), 1.0f) << std::endl;
|
||||
glm::degrees(sb::angle_between(a, c)) << " " << glm::degrees(sb::angle_between(c, a)) << " " <<
|
||||
glm::degrees(sb::angle_between(b, e)) << " " << glm::degrees(sb::angle_between(e, b)) << std::endl <<
|
||||
sb::velocity_to_delta(sb::angle_between(a, b), 4.0f * glm::sqrt(2.0f)) << " " <<
|
||||
sb::velocity_to_delta(sb::angle_between(b, a), 4.0f * glm::sqrt(2.0f)) << " " <<
|
||||
sb::velocity_to_delta(sb::angle_between(d, a), 4.0f) << " " <<
|
||||
sb::velocity_to_delta(sb::angle_between(b, e), 1.0f) << std::endl;
|
||||
|
||||
Should print:
|
||||
Should print,
|
||||
|
||||
-135 45 -90 90 116.565 -63.435
|
||||
{-4, -4} {4, 4} {0, 4} {0.894427, -0.447214}
|
||||
|
||||
This test of angle differences should print the output below it:
|
||||
This test of angle differences should print the output below.
|
||||
|
||||
float a = 0.0f, b = glm::pi<float>(), c = glm::half_pi<float>(), d = 0.5f, e = glm::pi<float>() * 4;
|
||||
std::cout << sb::angle_difference(a, b) << " " << sb::angle_difference(a, c) << " " << sb::angle_difference(b, c) << " " <<
|
||||
sb::angle_difference(a, d) << " " << sb::angle_difference(c, d) << " " << sb::angle_difference(a, e) << " " <<
|
||||
sb::angle_difference(c, e) << " " << sb::angle_difference(d, e) << " " << sb::angle_difference(c, c) << std::endl <<
|
||||
sb::angle_ratio(a, b) << " " << sb::angle_ratio(a, c) << " " << sb::angle_ratio(b, c) << " " << sb::angle_ratio(a, d) << " " <<
|
||||
sb::angle_ratio(c, d) << " " << sb::angle_ratio(a, e) << " " << sb::angle_ratio(c, e) << " " << sb::angle_ratio(d, e) << " " <<
|
||||
sb::angle_ratio(c, c) << std::endl;
|
||||
sb::angle_difference(a, d) << " " << sb::angle_difference(c, d) << " " << sb::angle_difference(a, e) << " " <<
|
||||
sb::angle_difference(c, e) << " " << sb::angle_difference(d, e) << " " << sb::angle_difference(c, c) << std::endl <<
|
||||
sb::angle_ratio(a, b) << " " << sb::angle_ratio(a, c) << " " << sb::angle_ratio(b, c) << " " << sb::angle_ratio(a, d) << " " <<
|
||||
sb::angle_ratio(c, d) << " " << sb::angle_ratio(a, e) << " " << sb::angle_ratio(c, e) << " " << sb::angle_ratio(d, e) << " " <<
|
||||
sb::angle_ratio(c, c) << std::endl;
|
||||
|
||||
Should print:
|
||||
Should print,
|
||||
|
||||
-3.14159 1.5708 -1.5708 0.5 -1.0708 3.49691e-07 -1.5708 -0.5 0
|
||||
-1 0.5 -0.5 0.159155 -0.340845 1.1131e-07 -0.5 -0.159155 0
|
||||
|
@ -48,6 +48,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
/* GLM */
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/glm.hpp>
|
||||
|
@ -101,4 +103,14 @@ namespace sb
|
|||
* turn it is.
|
||||
*/
|
||||
float angle_ratio(float start, float end);
|
||||
|
||||
/*!
|
||||
* Calculate a 2D bezier curve from four 2D control points.
|
||||
*
|
||||
* Adapted from public domain released code, 2007 Victor Blomqvist, originally at https://www.pygame.org/wiki/BezierCurve.
|
||||
*
|
||||
* @param vertices four 2D control points
|
||||
* @param resolution number of points that will be in the computed curve
|
||||
*/
|
||||
std::vector<glm::vec2> bezier(const std::vector<glm::vec2> vertices, int resolution = 30);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue