diff options
Diffstat (limited to 'gfx/gl')
-rw-r--r-- | gfx/gl/camera.cpp | 59 | ||||
-rw-r--r-- | gfx/gl/camera.h | 87 | ||||
-rw-r--r-- | gfx/gl/sceneProvider.cpp | 4 | ||||
-rw-r--r-- | gfx/gl/sceneProvider.h | 5 | ||||
-rw-r--r-- | gfx/gl/sceneRenderer.cpp | 22 | ||||
-rw-r--r-- | gfx/gl/sceneRenderer.h | 5 | ||||
-rw-r--r-- | gfx/gl/sceneShader.cpp | 13 | ||||
-rw-r--r-- | gfx/gl/sceneShader.h | 12 | ||||
-rw-r--r-- | gfx/gl/shaders/landmass.fs | 6 | ||||
-rw-r--r-- | gfx/gl/shaders/landmass.vs | 3 | ||||
-rw-r--r-- | gfx/gl/shaders/uiShader.fs | 11 | ||||
-rw-r--r-- | gfx/gl/shaders/uiShader.vs | 13 | ||||
-rw-r--r-- | gfx/gl/shaders/uiShaderFont.fs | 12 | ||||
-rw-r--r-- | gfx/gl/shadowMapper.cpp | 44 | ||||
-rw-r--r-- | gfx/gl/uiShader.cpp | 27 | ||||
-rw-r--r-- | gfx/gl/uiShader.h | 47 | ||||
-rw-r--r-- | gfx/gl/vertexArrayObject.h | 12 |
17 files changed, 85 insertions, 297 deletions
diff --git a/gfx/gl/camera.cpp b/gfx/gl/camera.cpp deleted file mode 100644 index 82b11a6..0000000 --- a/gfx/gl/camera.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "camera.h" -#include <collections.h> -#include <glm/gtx/transform.hpp> -#include <maths.h> -#include <ray.h> - -Camera::Camera(GlobalPosition3D pos, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar) : - position {pos}, forward {::north}, up {::up}, near {zNear}, far {zFar}, - projection { - glm::perspective(fov, aspect, static_cast<RelativeDistance>(zNear), static_cast<RelativeDistance>(zFar))}, - viewProjection {}, inverseViewProjection {} -{ - updateView(); -} - -Ray<GlobalPosition3D> -Camera::unProject(const ScreenRelCoord & mouse) const -{ - static constexpr const glm::vec4 screen {0, 0, 1, 1}; - const auto mouseProjection = glm::lookAt({}, forward, up); - return {position, glm::normalize(glm::unProject(mouse || 1.F, mouseProjection, projection, screen))}; -} - -void -Camera::updateView() -{ - viewProjection = projection * glm::lookAt({}, forward, up); - inverseViewProjection = glm::inverse(viewProjection); -} - -Direction3D -Camera::upFromForward(const Direction3D & forward) -{ - const auto right = crossProduct(forward, ::down); - return crossProduct(forward, right); -} - -std::array<GlobalPosition4D, 4> -Camera::extentsAtDist(const GlobalDistance dist) const -{ - const auto clampToSeaFloor = [this, dist](GlobalPosition3D target) -> GlobalPosition4D { - target += position; - if (target.z < -1500) { - const CalcPosition3D diff = target - position; - const CalcDistance limit = -1500 - position.z; - return {position + ((limit * diff) / diff.z), (limit * dist) / diff.z}; - } - return {target, dist}; - }; - const auto depth = -(2.F * (static_cast<float>(dist - near)) * static_cast<float>(far)) - / (static_cast<float>(dist) * (static_cast<float>(near - far))) - - 1.F; - static constexpr const std::array extents {-1.F, 1.F}; - static constexpr const auto cartesianExtents = extents * extents; - return cartesianExtents * [&depth, this, &clampToSeaFloor](const auto & extent) { - const glm::vec4 in {extent.first, extent.second, depth, 1.F}; - return clampToSeaFloor(perspective_divide(inverseViewProjection * in)); - }; -} diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h deleted file mode 100644 index 8d53261..0000000 --- a/gfx/gl/camera.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "config/types.h" -#include <glm/glm.hpp> -#include <maths.h> -#include <ray.h> - -class Camera { -public: - Camera(GlobalPosition3D, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar); - - [[nodiscard]] glm::mat4 - getViewProjection() const - { - return viewProjection; - } - - [[nodiscard]] Ray<GlobalPosition3D> unProject(const ScreenRelCoord &) const; - - void - setPosition(const GlobalPosition3D & p) - { - position = p; - updateView(); - } - - void - setForward(const Direction3D & f) - { - setForward(f, upFromForward(f)); - } - - void - setForward(const Direction3D & f, const Direction3D & u) - { - forward = f; - up = u; - updateView(); - } - - void - setView(const GlobalPosition3D & p, const Direction3D & f) - { - position = p; - setForward(f); - } - - void - setView(const GlobalPosition3D & p, const Direction3D & f, const Direction3D & u) - { - position = p; - setView(f, u); - } - - void - lookAt(const GlobalPosition3D & target) - { - setForward(glm::normalize(RelativePosition3D(target - position))); - } - - [[nodiscard]] auto - getForward() const - { - return forward; - } - - [[nodiscard]] auto - getPosition() const - { - return position; - } - - [[nodiscard]] std::array<GlobalPosition4D, 4> extentsAtDist(GlobalDistance) const; - - [[nodiscard]] static Direction3D upFromForward(const Direction3D & forward); - -private: - void updateView(); - - GlobalPosition3D position; - Direction3D forward; - Direction3D up; - - GlobalDistance near, far; - glm::mat4 projection; - glm::mat4 viewProjection, inverseViewProjection; -}; diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp index 4e271db..3681c60 100644 --- a/gfx/gl/sceneProvider.cpp +++ b/gfx/gl/sceneProvider.cpp @@ -5,10 +5,10 @@ void SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer) const { renderer.setAmbientLight({0.5F, 0.5F, 0.5F}); - renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {{-quarter_pi, -quarter_pi}}, *this); + renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {{-quarter_pi, quarter_pi}}, *this); } void -SceneProvider::shadows(const ShadowMapper &) const +SceneProvider::shadows(const ShadowMapper &, const Frustum &) const { } diff --git a/gfx/gl/sceneProvider.h b/gfx/gl/sceneProvider.h index f5e8e99..f6b7009 100644 --- a/gfx/gl/sceneProvider.h +++ b/gfx/gl/sceneProvider.h @@ -5,6 +5,7 @@ class SceneRenderer; class ShadowMapper; class SceneShader; +class Frustum; class SceneProvider { public: @@ -12,8 +13,8 @@ public: virtual ~SceneProvider() = default; DEFAULT_MOVE_COPY(SceneProvider); - virtual void content(const SceneShader &) const = 0; + virtual void content(const SceneShader &, const Frustum &) const = 0; virtual void environment(const SceneShader &, const SceneRenderer &) const; virtual void lights(const SceneShader &) const = 0; - virtual void shadows(const ShadowMapper &) const; + virtual void shadows(const ShadowMapper &, const Frustum &) const; }; diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index b2a7d78..9a4d153 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -39,7 +39,7 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); configuregdata(gPosition, {GL_RGB32I}, GL_RGB_INTEGER, GL_COLOR_ATTACHMENT0); - configuregdata(gNormal, {GL_RGB8_SNORM, GL_RGB16F}, GL_RGB, GL_COLOR_ATTACHMENT1); + normaliFormat = configuregdata(gNormal, {GL_RGB8_SNORM, GL_RGB16F}, GL_RGB, GL_COLOR_ATTACHMENT1); configuregdata(gAlbedoSpec, {GL_RGB8}, GL_RGB, GL_COLOR_ATTACHMENT2); constexpr std::array<unsigned int, 3> attachments { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; @@ -57,6 +57,24 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : } void +SceneRenderer::resize(ScreenAbsCoord newSize) +{ + size = newSize; + camera.setAspect(ratio(size)); + const auto configuregdata = [this](const GLuint data, const GLint iformat, const GLenum format) { + glBindTexture(GL_TEXTURE_2D, data); + glTexImage2D(GL_TEXTURE_2D, 0, iformat, size.x, size.y, 0, format, GL_BYTE, nullptr); + }; + configuregdata(gPosition, GL_RGB32I, GL_RGB_INTEGER); + configuregdata(gNormal, normaliFormat, GL_RGB); + configuregdata(gAlbedoSpec, GL_RGB8, GL_RGB); + configuregdata(gIllumination, GL_RGB8, GL_RGB); + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x, size.y); + shader.setViewPort({0, 0, size.x, size.y}); +} + +void SceneRenderer::render(const SceneProvider & scene) const { shader.setViewProjection(camera.getPosition(), camera.getViewProjection()); @@ -71,7 +89,7 @@ SceneRenderer::render(const SceneProvider & scene) const glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - scene.content(shader); + scene.content(shader, camera); // Environment pass - // * ambient - clears illumination texture - see setAmbientLight diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index 93470f5..31f0cda 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -1,18 +1,20 @@ #pragma once -#include "camera.h" #include "gfx/lightDirection.h" #include "glArrays.h" #include "program.h" #include "sceneProvider.h" #include "sceneShader.h" #include "shadowMapper.h" +#include <gfx/camera.h> #include <glm/fwd.hpp> class SceneRenderer { public: explicit SceneRenderer(ScreenAbsCoord size, GLuint output); + void resize(ScreenAbsCoord size); + void render(const SceneProvider &) const; void setAmbientLight(const RGB & colour) const; void setDirectionalLight(const RGB & colour, const LightDirection & direction, const SceneProvider &) const; @@ -25,6 +27,7 @@ protected: ScreenAbsCoord size; GLuint output; glFrameBuffer gBuffer, gBufferIll; + GLint normaliFormat; glTexture gPosition, gNormal, gAlbedoSpec, gIllumination; glRenderBuffer depth; diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 571538a..4b82ae4 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -34,9 +34,9 @@ SceneShader::allPrograms(auto member, auto &&... ps) const } SceneShader::SceneShader() : - basicInst {dynamicPointInst_vs, material_fs}, landmass {landmass_vs, landmass_fs}, - absolute {fixedPoint_vs, material_fs}, spotLightInst {spotLight_vs, spotLight_gs, spotLight_fs}, - pointLightInst {pointLight_vs, pointLight_gs, pointLight_fs}, + basicInst {dynamicPointInst_vs, material_fs}, absolute {fixedPoint_vs, material_fs}, + spotLightInst {spotLight_vs, spotLight_gs, spotLight_fs}, + pointLightInst {pointLight_vs, pointLight_gs, pointLight_fs}, landmass {landmass_vs, landmass_fs}, networkStraight {networkStraight_vs, networkStraight_gs, network_fs}, networkCurve {networkCurve_vs, networkCurve_gs, network_fs} { @@ -88,6 +88,13 @@ SceneShader::BasicProgram::use(Location const & location) const } void +SceneShader::LandmassProgram::use(const glm::vec3 colourBias) const +{ + Program::use(); + glUniform(colourBiasLos, colourBias); +} + +void SceneShader::NetworkProgram::use( const std::span<const glm::vec3> profile, const std::span<const float> texturePos) const { diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h index 51f0e21..47d4397 100644 --- a/gfx/gl/sceneShader.h +++ b/gfx/gl/sceneShader.h @@ -50,6 +50,15 @@ class SceneShader { RequiredUniformLocation profileLengthLoc {*this, "profileLength"}; }; + class LandmassProgram : public AbsolutePosProgram { + public: + using AbsolutePosProgram::AbsolutePosProgram; + void use(const glm::vec3) const; + + private: + RequiredUniformLocation colourBiasLos {*this, "colourBias"}; + }; + class WaterProgram : public SceneProgram { public: WaterProgram(); @@ -64,7 +73,8 @@ public: BasicProgram basic; WaterProgram water; - AbsolutePosProgram basicInst, landmass, absolute, spotLightInst, pointLightInst; + AbsolutePosProgram basicInst, absolute, spotLightInst, pointLightInst; + LandmassProgram landmass; NetworkProgram networkStraight, networkCurve; void setViewProjection(const GlobalPosition3D & viewPoint, const glm::mat4 & viewProjection) const; diff --git a/gfx/gl/shaders/landmass.fs b/gfx/gl/shaders/landmass.fs index 55e3c24..382260e 100644 --- a/gfx/gl/shaders/landmass.fs +++ b/gfx/gl/shaders/landmass.fs @@ -3,10 +3,10 @@ include(`materialOut.glsl') in vec3 FragPos; in vec3 Normal; -flat in vec3 ColourBias; uniform sampler2D texture0; uniform ivec3 viewPoint; +uniform vec3 colourBias; const vec3 grass = vec3(.1, .4, .05); const vec3 slope = vec3(.6, .6, .4); @@ -35,8 +35,8 @@ main() vec3 color = texture(texture0, vec2(position.xy % 10000) / 10000.0).rgb; int height = position.z; - if (ColourBias.r >= 0) { - color *= ColourBias; + if (colourBias.r >= 0) { + color *= colourBias; } else if (height < beachline) { // Sandy beach color *= sand; diff --git a/gfx/gl/shaders/landmass.vs b/gfx/gl/shaders/landmass.vs index 9617cb9..44cb879 100644 --- a/gfx/gl/shaders/landmass.vs +++ b/gfx/gl/shaders/landmass.vs @@ -3,11 +3,9 @@ layout(location = 0) in ivec3 position; layout(location = 1) in vec3 normal; -layout(location = 2) in vec3 colourBias; out vec3 FragPos; out vec3 Normal; -flat out vec3 ColourBias; uniform mat4 viewProjection; uniform ivec3 viewPoint; @@ -17,7 +15,6 @@ main() { FragPos = position - viewPoint; Normal = normal; - ColourBias = colourBias; gl_Position = viewProjection * vec4(FragPos, 1); } diff --git a/gfx/gl/shaders/uiShader.fs b/gfx/gl/shaders/uiShader.fs deleted file mode 100644 index c5f4e92..0000000 --- a/gfx/gl/shaders/uiShader.fs +++ /dev/null @@ -1,11 +0,0 @@ -#version 330 core - -in vec2 texCoord0; - -uniform sampler2D sampler; - -void -main() -{ - gl_FragColor = texture(sampler, texCoord0); -} diff --git a/gfx/gl/shaders/uiShader.vs b/gfx/gl/shaders/uiShader.vs deleted file mode 100644 index e9e4373..0000000 --- a/gfx/gl/shaders/uiShader.vs +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core - -in vec4 position; - -out vec2 texCoord0; -uniform mat4 uiProjection; - -void -main() -{ - gl_Position = uiProjection * vec4(position.xy, 0.0, 1.0); - texCoord0 = position.zw; -} diff --git a/gfx/gl/shaders/uiShaderFont.fs b/gfx/gl/shaders/uiShaderFont.fs deleted file mode 100644 index a1ef6ef..0000000 --- a/gfx/gl/shaders/uiShaderFont.fs +++ /dev/null @@ -1,12 +0,0 @@ -#version 330 core - -in vec2 texCoord0; - -uniform sampler2D sampler; -uniform vec3 colour; - -void -main() -{ - gl_FragColor = vec4(colour, texture(sampler, texCoord0).r); -} diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 1b95aa3..3cb73f7 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -1,7 +1,7 @@ #include "shadowMapper.h" -#include "camera.h" #include "collections.h" #include "game/gamestate.h" +#include "gfx/aabb.h" #include "gfx/gl/shaders/fs-shadowDynamicPointInstWithTextures.h" #include "gfx/gl/shaders/fs-shadowDynamicPointStencil.h" #include "gfx/gl/shaders/gs-commonShadowPoint.h" @@ -20,7 +20,7 @@ #include "maths.h" #include "sceneProvider.h" #include "sceneShader.h" -#include "sorting.h" +#include <gfx/camera.h> #include <glm/gtc/type_ptr.hpp> #include <glm/gtx/transform.hpp> #include <glm/matrix.hpp> @@ -56,7 +56,7 @@ constexpr auto shadowBands = []<GlobalDistance... ints>(const float scaleFactor, std::integer_sequence<GlobalDistance, ints...>) { const auto base = 10'000'000 / pow(scaleFactor, sizeof...(ints) - 1); return std::array {1, static_cast<GlobalDistance>((base * pow(scaleFactor, ints)))...}; - }(6.6F, std::make_integer_sequence<GlobalDistance, ShadowMapper::SHADOW_BANDS>()); + }(4.6F, std::make_integer_sequence<GlobalDistance, ShadowMapper::SHADOW_BANDS>()); static_assert(shadowBands.front() == 1); static_assert(shadowBands.back() == 10'000'000); @@ -88,7 +88,7 @@ ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, co shadowStenciller.setLightDirection(dir); for (const auto & [id, asset] : gameState->assets) { - if (const auto r = std::dynamic_pointer_cast<const Renderable>(asset)) { + if (const auto r = asset.getAs<const Renderable>()) { r->updateStencil(shadowStenciller); } } @@ -102,30 +102,30 @@ ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, co const auto bandViewExtents = getBandViewExtents(camera, lightViewDir); Definitions out; Sizes sizes; - std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()), - std::back_inserter(out), - [bands = bandViewExtents.size() - 2, &lightViewDir, &sizes](const auto & near, const auto & far) mutable { - const auto extents_minmax - = [extents = std::span {near.begin(), far.end()}](auto && comp, RelativeDistance extra) { - const auto mm = std::minmax_element(extents.begin(), extents.end(), comp); - return std::make_pair(comp.get(*mm.first) - extra, comp.get(*mm.second) + extra); - }; - const std::array extents = {extents_minmax(CompareBy {0}, 0), extents_minmax(CompareBy {1}, 0), - extents_minmax(CompareBy {2}, 10'000)}; - - const auto lightProjection = [](const auto & x, const auto & y, const auto & z) { - return glm::ortho(x.first, x.second, y.first, y.second, -z.second, -z.first); - }(extents[0], extents[1], extents[2]); - - sizes.emplace_back(extents[0].second - extents[0].first, extents[1].second - extents[1].first, - extents[2].second - extents[2].first); + using ExtentsBoundingBox = AxisAlignedBoundingBox<RelativeDistance>; + std::ranges::transform(bandViewExtents | std::views::pairwise, std::back_inserter(out), + [&lightViewDir, &sizes](const auto & band) mutable { + const auto & [near, far] = band; + auto extents = ExtentsBoundingBox::fromPoints(std::span {near.begin(), far.end()}); + extents.min.z -= 10'000.F; + extents.max.z += 10'000.F; + const auto lightProjection = glm::ortho( + extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z); + sizes.emplace_back(extents.max - extents.min); return lightProjection * lightViewDir; }); for (const auto p : std::initializer_list<const ShadowProgram *> { &landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures, &stencilShadowProgram}) { p->setView(out, sizes, lightViewPoint); } - scene.shadows(*this); + ExtentsBoundingBox extents {lightViewPoint, lightViewPoint}; + for (const auto & point : bandViewExtents.back()) { + extents += point; + } + const auto lightProjection + = glm::ortho(extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z); + Frustum frustum {lightViewPoint, lightViewDir, lightProjection}; + scene.shadows(*this, frustum); glCullFace(GL_BACK); diff --git a/gfx/gl/uiShader.cpp b/gfx/gl/uiShader.cpp deleted file mode 100644 index 23da9dc..0000000 --- a/gfx/gl/uiShader.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "uiShader.h" -#include "gl_traits.h" -#include <gfx/gl/program.h> -#include <gfx/gl/shader.h> -#include <gfx/gl/shaders/fs-uiShader.h> -#include <gfx/gl/shaders/fs-uiShaderFont.h> -#include <gfx/gl/shaders/vs-uiShader.h> -#include <glm/glm.hpp> -#include <glm/gtc/type_ptr.hpp> - -UIShader::IconProgram::IconProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShader_fs} { } - -UIShader::TextProgram::TextProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShaderFont_fs} { } - -UIShader::UIShader(size_t width, size_t height) : - UIShader {glm::ortho<float>(0, static_cast<float>(width), 0, static_cast<float>(height))} -{ -} - -UIShader::UIShader(const glm::mat4 & viewProjection) : icon {viewProjection}, text {viewProjection} { } - -void -UIShader::TextProgram::use(const RGB & colour) const -{ - Program::use(); - glUniform(colorLoc, colour); -} diff --git a/gfx/gl/uiShader.h b/gfx/gl/uiShader.h deleted file mode 100644 index 6d00166..0000000 --- a/gfx/gl/uiShader.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "config/types.h" -#include "gl_traits.h" -#include "program.h" -#include <cstddef> -#include <glad/gl.h> -#include <glm/glm.hpp> -#include <glm/gtc/type_ptr.hpp> - -class UIShader { -public: - UIShader(std::size_t width, std::size_t height); - -private: - explicit UIShader(const glm::mat4 & viewProjection); - - class UIProgram : public Program { - public: - template<typename... S> - explicit UIProgram(const glm::mat4 & vp, S &&... srcs) : Program {std::forward<S>(srcs)...} - { - const RequiredUniformLocation uiProjectionLoc {*this, "uiProjection"}; - glUseProgram(*this); - glUniform(uiProjectionLoc, vp); - } - }; - - class IconProgram : public UIProgram { - public: - explicit IconProgram(const glm::mat4 & vp); - using Program::use; - }; - - class TextProgram : public UIProgram { - public: - explicit TextProgram(const glm::mat4 & vp); - void use(const RGB & colour) const; - - private: - RequiredUniformLocation colorLoc {*this, "colour"}; - }; - -public: - IconProgram icon; - TextProgram text; -}; diff --git a/gfx/gl/vertexArrayObject.h b/gfx/gl/vertexArrayObject.h index 57daaf3..d008897 100644 --- a/gfx/gl/vertexArrayObject.h +++ b/gfx/gl/vertexArrayObject.h @@ -21,14 +21,15 @@ public: NO_COPY(VertexArrayObject); template<typename m, typename T> struct MP { - constexpr MP(m T::*p) : P {p} { } + constexpr MP(m T::* p) : P {p} { } + constexpr operator void *() const { return &(static_cast<T *>(nullptr)->*P); } - m T::*P; + m T::* P; using value_type = m; }; @@ -69,6 +70,13 @@ public: return *this; } + VertexArrayObject & + data(const GLuint arrayBuffer, GLenum target) + { + glBindBuffer(target, arrayBuffer); + return *this; + } + template<typename Data> static void data(const Data & data, const GLuint arrayBuffer, GLenum target) |