mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 03:52:48 -05:00
Add templated wrapper objects
- Shader - Program - Buffer - VertexArray Along with template magic to deduce VertexArray formats - Format, IFormat, LFormat - AutoFormat - Binder - ATTR
This commit is contained in:
@@ -19,7 +19,13 @@ add_custom_command(
|
|||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/res ${CMAKE_CURRENT_BINARY_DIR}/res
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/res ${CMAKE_CURRENT_BINARY_DIR}/res
|
||||||
COMMENT "Copying Resources")
|
COMMENT "Copying Resources")
|
||||||
|
|
||||||
add_executable(vis src/main.cpp)
|
add_executable(vis
|
||||||
|
src/main.cpp
|
||||||
|
src/gl/debug.hpp
|
||||||
|
src/gl/shader.hpp
|
||||||
|
src/gl/buffer.hpp
|
||||||
|
src/gl/vertexarray.hpp
|
||||||
|
src/gl/types.hpp)
|
||||||
target_link_libraries(vis glfw glad imgui eigen nlohmann_json)
|
target_link_libraries(vis glfw glad imgui eigen nlohmann_json)
|
||||||
add_dependencies(vis resources)
|
add_dependencies(vis resources)
|
||||||
|
|
||||||
|
|||||||
48
src/gl/buffer.hpp
Normal file
48
src/gl/buffer.hpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
template<typename T_>
|
||||||
|
class Buffer {
|
||||||
|
public:
|
||||||
|
using Type = T_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint id = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Buffer() {
|
||||||
|
glCreateBuffers(1, &id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer(Buffer&& o) noexcept {
|
||||||
|
id = std::exchange(o.id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer(const Buffer&) = delete; // this is doable, but would be slow.
|
||||||
|
|
||||||
|
operator GLuint() const { // NOLINT(google-explicit-constructor)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RandomIt>
|
||||||
|
GLuint upload(RandomIt first, RandomIt last, GLenum mode = GL_STATIC_DRAW) {
|
||||||
|
size_t count = last - first;
|
||||||
|
|
||||||
|
// todo StaticBuffer that uses BufferStorage
|
||||||
|
glNamedBufferData(id, sizeof(Type) * count, nullptr, mode);
|
||||||
|
|
||||||
|
Type* out = (Type*) glMapNamedBuffer(id, GL_WRITE_ONLY);
|
||||||
|
std::copy(first, last, out);
|
||||||
|
glUnmapNamedBuffer(id);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Buffer() {
|
||||||
|
// delete silently ignores 0.
|
||||||
|
glDeleteBuffers(1, &id);
|
||||||
|
}
|
||||||
|
};
|
||||||
79
src/gl/shader.hpp
Normal file
79
src/gl/shader.hpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template<GLenum mode>
|
||||||
|
class Shader {
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
GLuint id = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Shader(const std::string &src) {
|
||||||
|
id = glCreateShader(mode);
|
||||||
|
|
||||||
|
const char *str = src.c_str();
|
||||||
|
glShaderSource(id, 1, &str, nullptr);
|
||||||
|
glCompileShader(id);
|
||||||
|
|
||||||
|
// todo throw if compile failed
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Shader(std::ifstream source)
|
||||||
|
: Shader(std::string(
|
||||||
|
std::istreambuf_iterator<char>(source),
|
||||||
|
std::istreambuf_iterator<char>()
|
||||||
|
)) {}
|
||||||
|
|
||||||
|
Shader(const Shader &) = delete;
|
||||||
|
|
||||||
|
Shader(Shader &&o) noexcept {
|
||||||
|
id = std::exchange(o.id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Shader() {
|
||||||
|
glDeleteShader(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator GLuint() const { // NOLINT(google-explicit-constructor)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using VertexShader = Shader<GL_VERTEX_SHADER>;
|
||||||
|
using FragmentShader = Shader<GL_FRAGMENT_SHADER>;
|
||||||
|
|
||||||
|
class Program {
|
||||||
|
private:
|
||||||
|
GLuint id = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<GLenum ...mode>
|
||||||
|
explicit Program(const Shader<mode> &...shader) {
|
||||||
|
id = glCreateProgram();
|
||||||
|
|
||||||
|
(glAttachShader(id, shader), ...);
|
||||||
|
|
||||||
|
glLinkProgram(id);
|
||||||
|
|
||||||
|
// todo throw if link failed
|
||||||
|
}
|
||||||
|
|
||||||
|
Program(const Program &) = delete;
|
||||||
|
|
||||||
|
Program(Program &&o) noexcept {
|
||||||
|
id = std::exchange(o.id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Program() {
|
||||||
|
glDeleteProgram(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator GLuint() const { // NOLINT(google-explicit-constructor)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
};
|
||||||
113
src/gl/types.hpp
Normal file
113
src/gl/types.hpp
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include <Eigen/Eigen>
|
||||||
|
|
||||||
|
template<class T_>
|
||||||
|
struct Buffer;
|
||||||
|
|
||||||
|
template<class ...Fmt_>
|
||||||
|
struct VertexArray;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ctype, GLenum type, GLint size, GLuint offset = 0, GLboolean norm = GL_FALSE>
|
||||||
|
struct Format {
|
||||||
|
using CType = ctype;
|
||||||
|
static constexpr GLenum Type = type;
|
||||||
|
static constexpr GLint Size = size;
|
||||||
|
static constexpr GLuint Offset = offset;
|
||||||
|
static constexpr GLboolean Norm = norm;
|
||||||
|
|
||||||
|
template<typename ctype_, GLint size_>
|
||||||
|
using As = Format<ctype_, type, size_, offset, norm>;
|
||||||
|
|
||||||
|
static inline constexpr void apply(GLuint vao, GLuint idx) {
|
||||||
|
glEnableVertexArrayAttrib(vao, idx);
|
||||||
|
glVertexArrayAttribFormat(vao, idx, size, type, norm, offset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ctype, GLenum type, GLint size, GLuint offset = 0>
|
||||||
|
struct IFormat {
|
||||||
|
using CType = ctype;
|
||||||
|
static constexpr GLenum Type = type;
|
||||||
|
static constexpr GLint Size = size;
|
||||||
|
static constexpr GLuint Offset = offset;
|
||||||
|
|
||||||
|
template<typename ctype_, GLint size_>
|
||||||
|
using As = IFormat<ctype_, type, size_, offset>;
|
||||||
|
|
||||||
|
static inline constexpr void apply(GLuint vao, GLuint idx) {
|
||||||
|
glEnableVertexArrayAttrib(vao, idx);
|
||||||
|
glVertexArrayAttribIFormat(vao, idx, size, type, offset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ctype, GLenum type, GLint size, GLuint offset = 0>
|
||||||
|
struct LFormat {
|
||||||
|
using CType = ctype;
|
||||||
|
static constexpr GLenum Type = type;
|
||||||
|
static constexpr GLint Size = size;
|
||||||
|
static constexpr GLuint Offset = offset;
|
||||||
|
|
||||||
|
template<typename ctype_, GLint size_>
|
||||||
|
using As = LFormat<ctype_, type, size_, offset>;
|
||||||
|
|
||||||
|
static inline constexpr void apply(GLuint vao, GLuint idx) {
|
||||||
|
glEnableVertexArrayAttrib(vao, idx);
|
||||||
|
glVertexArrayAttribLFormat(vao, idx, size, type, offset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fmt_>
|
||||||
|
struct AutoFormat {
|
||||||
|
using Fmt = Fmt_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AutoFormat<double> {
|
||||||
|
using Fmt = LFormat<double, GL_DOUBLE, 1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AutoFormat<float> {
|
||||||
|
using Fmt = Format<float, GL_FLOAT, 1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AutoFormat<int> {
|
||||||
|
using Fmt = IFormat<int, GL_INT, 1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Scalar, int Dim>
|
||||||
|
struct AutoFormat<Eigen::Vector<Scalar, Dim>> {
|
||||||
|
static_assert((Dim >= 1) && (Dim <= 4), "Dim must be in range 1-4");
|
||||||
|
|
||||||
|
using Fmt = typename AutoFormat<Scalar>::Fmt::template As<Eigen::Vector<Scalar, Dim>, Dim>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fmt_>
|
||||||
|
struct Binder {
|
||||||
|
using CType = typename AutoFormat<Fmt_>::Fmt::CType;
|
||||||
|
|
||||||
|
const GLuint buf;
|
||||||
|
const GLuint offset;
|
||||||
|
const GLuint stride;
|
||||||
|
|
||||||
|
Binder(const Buffer<CType> &buf) // NOLINT(google-explicit-constructor)
|
||||||
|
: buf((GLuint) buf), offset(0), stride(sizeof(CType)) {}
|
||||||
|
|
||||||
|
template<typename CType_>
|
||||||
|
Binder(const Buffer<CType_> &buf, GLuint offset)
|
||||||
|
: buf((GLuint) buf), offset(offset), stride(sizeof(CType_)) {}
|
||||||
|
|
||||||
|
Binder(const Binder<Fmt_> &o)
|
||||||
|
: buf(o.buf), offset(o.offset), stride(o.stride) {}
|
||||||
|
|
||||||
|
inline void bind(GLuint vao, GLuint idx) const {
|
||||||
|
glVertexArrayVertexBuffer(vao, idx, buf, offset, stride);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ATTR(buf, field) Binder<decltype(decltype(buf)::Type::field)>(buf, offsetof(decltype(buf)::Type, field))
|
||||||
67
src/gl/vertexarray.hpp
Normal file
67
src/gl/vertexarray.hpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "buffer.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
|
template<typename ...Fmt_>
|
||||||
|
class VertexArray {
|
||||||
|
public:
|
||||||
|
template<size_t idx>
|
||||||
|
using Fmt = std::tuple_element_t<idx, std::tuple<Fmt_...>>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint id = 0;
|
||||||
|
|
||||||
|
template<size_t ...idx>
|
||||||
|
inline void formatall(
|
||||||
|
std::integer_sequence<size_t, idx...>
|
||||||
|
) {
|
||||||
|
(AutoFormat<Fmt_>::Fmt::apply(id, idx), ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t ...idx>
|
||||||
|
inline void bindall(
|
||||||
|
const Binder<Fmt_> &...buf,
|
||||||
|
std::integer_sequence<size_t, idx...>
|
||||||
|
) {
|
||||||
|
(buf.bind(id, idx), ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit VertexArray() {
|
||||||
|
glCreateVertexArrays(1, &id);
|
||||||
|
formatall(std::make_index_sequence<sizeof...(Fmt_)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit VertexArray(const Binder<Fmt_> &...buf)
|
||||||
|
: VertexArray() {
|
||||||
|
bind(buf...);
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexArray(VertexArray &&o) noexcept {
|
||||||
|
id = std::exchange(o.id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexArray(const VertexArray &) = delete; // this is doable, but would be slow.
|
||||||
|
|
||||||
|
~VertexArray() {
|
||||||
|
glDeleteVertexArrays(1, &id);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator GLuint() const { // NOLINT(google-explicit-constructor)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(const Binder<Fmt_> &...buf) {
|
||||||
|
bindall(buf..., std::make_index_sequence<sizeof...(Fmt_)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t idx>
|
||||||
|
void bind(const Binder<Fmt<idx>> &buf) {
|
||||||
|
buf.bind(id, idx);
|
||||||
|
}
|
||||||
|
};
|
||||||
189
src/main.cpp
189
src/main.cpp
@@ -6,7 +6,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "gldebug.hpp"
|
#include "gl/debug.hpp"
|
||||||
|
#include "gl/buffer.hpp"
|
||||||
|
#include "gl/shader.hpp"
|
||||||
|
#include "gl/vertexarray.hpp"
|
||||||
|
|
||||||
#include <ml/meshlib.hpp>
|
#include <ml/meshlib.hpp>
|
||||||
#include <ml/meshlib_json.hpp>
|
#include <ml/meshlib_json.hpp>
|
||||||
@@ -123,145 +126,54 @@ void set_style() {
|
|||||||
int run(GLFWwindow *window, ImGuiContext *context) {
|
int run(GLFWwindow *window, ImGuiContext *context) {
|
||||||
State state;
|
State state;
|
||||||
|
|
||||||
|
Buffer<GLuint> ind_buf;
|
||||||
|
Buffer<Eigen::Vector3f> vert_buf;
|
||||||
|
Buffer<Eigen::Vector3f> vert2_buf;
|
||||||
|
|
||||||
|
VertexArray<Eigen::Vector3f> vao(vert_buf);
|
||||||
|
glVertexArrayElementBuffer(vao, ind_buf);
|
||||||
|
|
||||||
auto mesh = ml::CubeMesh(0.25f);
|
auto mesh = ml::CubeMesh(0.25f);
|
||||||
// auto mesh = ml::read("circle.pak");
|
|
||||||
|
|
||||||
auto dynamic = (ml::DynamicMesh) mesh;
|
auto ind_data = mesh.cells();
|
||||||
|
auto ind_flat = ind_data.reshaped();
|
||||||
|
auto elements = ind_buf.upload(ind_flat.begin(), ind_flat.end(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
GLuint vao;
|
// todo add <Dim, Rank> to DynamicMesh
|
||||||
glCreateVertexArrays(1, &vao);
|
// need to do weird piping because dynamicmesh returns dynamic-sized matrix, VertexArray requires a static-sized matrix
|
||||||
|
auto vert_data_dyn = mesh.points();
|
||||||
|
Eigen::Ref<Eigen::Matrix3Xf> vert_data(vert_data_dyn);
|
||||||
|
auto vert_flat = vert_data.colwise();
|
||||||
|
vert_buf.upload(vert_flat.begin(), vert_flat.end(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
GLuint vbo;
|
auto mesh2 = ml::CubeMesh(0.5f);
|
||||||
glCreateBuffers(1, &vbo);
|
auto vert2_data_dyn = mesh2.points();
|
||||||
|
Eigen::Ref<Eigen::Matrix3Xf> vert2_data(vert2_data_dyn);
|
||||||
|
auto vert2_flat = vert2_data.colwise();
|
||||||
|
vert2_buf.upload(vert2_flat.begin(), vert2_flat.end(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
constexpr size_t point_scalar_size = sizeof(ml::DynamicMesh::PointsType::Scalar);
|
auto mesh4d = ml::WireCubeMesh(4, 0.33f);
|
||||||
constexpr size_t cell_scalar_size = sizeof(ml::DynamicMesh::CellsType::Scalar);
|
|
||||||
|
|
||||||
glNamedBufferData(
|
Buffer<GLuint> ind4d_buf;
|
||||||
vbo,
|
Buffer<Eigen::Vector4f> vert4d_buf;
|
||||||
(GLsizeiptr) (point_scalar_size * dynamic.points().size()),
|
VertexArray<Eigen::Vector4f> vao4d(vert4d_buf);
|
||||||
dynamic.points().data(),
|
glVertexArrayElementBuffer(vao4d, ind4d_buf);
|
||||||
GL_STATIC_DRAW
|
|
||||||
);
|
|
||||||
glEnableVertexArrayAttrib(vao, 0);
|
|
||||||
glVertexArrayVertexBuffer(vao, 0,
|
|
||||||
vbo, 0,
|
|
||||||
(GLsizeiptr) (point_scalar_size * dynamic.points().rows())
|
|
||||||
);
|
|
||||||
glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
|
|
||||||
|
|
||||||
GLuint ibo;
|
auto ind4d_data = mesh4d.cells();
|
||||||
glCreateBuffers(1, &ibo);
|
auto ind4d_flat = ind4d_data.reshaped();
|
||||||
glGetError();
|
auto elements4d = ind4d_buf.upload(ind4d_flat.begin(), ind4d_flat.end(), GL_STATIC_DRAW);
|
||||||
glNamedBufferData(
|
|
||||||
ibo,
|
|
||||||
(GLsizeiptr) (cell_scalar_size * dynamic.cells().size()),
|
|
||||||
dynamic.cells().data(),
|
|
||||||
GL_STATIC_DRAW
|
|
||||||
);
|
|
||||||
glVertexArrayElementBuffer(vao, ibo);
|
|
||||||
|
|
||||||
auto wire_mesh = ml::WireCubeMesh(4, 0.33f);
|
auto vert4d_data_dyn = mesh4d.points();
|
||||||
auto wire_dynamic = (ml::DynamicMesh) wire_mesh;
|
Eigen::Ref<Eigen::Matrix4Xf> vert4d_data(vert4d_data_dyn);
|
||||||
|
auto vert4d_flat = vert4d_data.colwise();
|
||||||
|
vert4d_buf.upload(vert4d_flat.begin(), vert4d_flat.end(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
GLuint wire_vao;
|
VertexShader vs(std::ifstream("res/shaders/main.vert.glsl"));
|
||||||
glCreateVertexArrays(1, &wire_vao);
|
VertexShader vs4d(std::ifstream("res/shaders/4d.vert.glsl"));
|
||||||
|
FragmentShader fs(std::ifstream("res/shaders/main.frag.glsl"));
|
||||||
|
|
||||||
GLuint wire_vbo;
|
Program pgm(vs, fs);
|
||||||
glCreateBuffers(1, &wire_vbo);
|
Program pgm4d(vs4d, fs);
|
||||||
|
|
||||||
glNamedBufferData(
|
|
||||||
wire_vbo,
|
|
||||||
(GLsizeiptr) (point_scalar_size * wire_dynamic.points().size()),
|
|
||||||
wire_dynamic.points().data(),
|
|
||||||
GL_STATIC_DRAW
|
|
||||||
);
|
|
||||||
glEnableVertexArrayAttrib(wire_vao, 0);
|
|
||||||
glVertexArrayVertexBuffer(wire_vao, 0,
|
|
||||||
wire_vbo, 0,
|
|
||||||
(GLsizeiptr) (point_scalar_size * wire_dynamic.points().rows())
|
|
||||||
);
|
|
||||||
glVertexArrayAttribFormat(wire_vao, 0, 4, GL_FLOAT, GL_FALSE, 0);
|
|
||||||
|
|
||||||
GLuint wire_ibo;
|
|
||||||
glCreateBuffers(1, &wire_ibo);
|
|
||||||
glGetError();
|
|
||||||
glNamedBufferData(
|
|
||||||
wire_ibo,
|
|
||||||
(GLsizeiptr) (cell_scalar_size * wire_dynamic.cells().size()),
|
|
||||||
wire_dynamic.cells().data(),
|
|
||||||
GL_STATIC_DRAW
|
|
||||||
);
|
|
||||||
glVertexArrayElementBuffer(wire_vao, wire_ibo);
|
|
||||||
|
|
||||||
std::ifstream vs_file("res/shaders/main.vert.glsl");
|
|
||||||
std::string vs_src(
|
|
||||||
(std::istreambuf_iterator<char>(vs_file)),
|
|
||||||
std::istreambuf_iterator<char>()
|
|
||||||
);
|
|
||||||
vs_file.close();
|
|
||||||
const char *vs_str = vs_src.c_str();
|
|
||||||
|
|
||||||
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(vs, 1, &vs_str, nullptr);
|
|
||||||
glCompileShader(vs);
|
|
||||||
|
|
||||||
std::ifstream wire_vs_file("res/shaders/4d.vert.glsl");
|
|
||||||
std::string wire_vs_src(
|
|
||||||
(std::istreambuf_iterator<char>(wire_vs_file)),
|
|
||||||
std::istreambuf_iterator<char>()
|
|
||||||
);
|
|
||||||
wire_vs_file.close();
|
|
||||||
const char *wire_vs_str = wire_vs_src.c_str();
|
|
||||||
|
|
||||||
GLuint wire_vs = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(wire_vs, 1, &wire_vs_str, nullptr);
|
|
||||||
glCompileShader(wire_vs);
|
|
||||||
|
|
||||||
std::ifstream fs_file("res/shaders/main.frag.glsl");
|
|
||||||
std::string fs_src(
|
|
||||||
(std::istreambuf_iterator<char>(fs_file)),
|
|
||||||
std::istreambuf_iterator<char>()
|
|
||||||
);
|
|
||||||
fs_file.close();
|
|
||||||
const char *fs_str = fs_src.c_str();
|
|
||||||
|
|
||||||
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
glShaderSource(fs, 1, &fs_str, nullptr);
|
|
||||||
glCompileShader(fs);
|
|
||||||
|
|
||||||
GLuint pgm = glCreateProgram();
|
|
||||||
glAttachShader(pgm, vs);
|
|
||||||
glAttachShader(pgm, fs);
|
|
||||||
glLinkProgram(pgm);
|
|
||||||
|
|
||||||
GLuint wire_pgm = glCreateProgram();
|
|
||||||
glAttachShader(wire_pgm, wire_vs);
|
|
||||||
glAttachShader(wire_pgm, fs);
|
|
||||||
glLinkProgram(wire_pgm);
|
|
||||||
|
|
||||||
GLint link_status;
|
|
||||||
glGetProgramiv(pgm, GL_LINK_STATUS, &link_status);
|
|
||||||
if (!link_status) {
|
|
||||||
std::cerr << "Program link failed." << std::endl;
|
|
||||||
GLint vs_comp_status, fs_comp_status;
|
|
||||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &vs_comp_status);
|
|
||||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &fs_comp_status);
|
|
||||||
std::cerr << "vs compiled: " << std::boolalpha << (bool) vs_comp_status << std::endl;
|
|
||||||
std::cerr << "fs compiled: " << std::boolalpha << (bool) fs_comp_status << std::endl;
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
glGetProgramiv(wire_pgm, GL_LINK_STATUS, &link_status);
|
|
||||||
if (!link_status) {
|
|
||||||
std::cerr << "Wire program link failed." << std::endl;
|
|
||||||
GLint vs_comp_status, fs_comp_status;
|
|
||||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &vs_comp_status);
|
|
||||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &fs_comp_status);
|
|
||||||
std::cerr << "vs compiled: " << std::boolalpha << (bool) vs_comp_status << std::endl;
|
|
||||||
std::cerr << "fs compiled: " << std::boolalpha << (bool) fs_comp_status << std::endl;
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
@@ -291,12 +203,12 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
|||||||
glUniform1f(1, (GLfloat) glfwGetTime());
|
glUniform1f(1, (GLfloat) glfwGetTime());
|
||||||
glUniformMatrix4fv(2, 1, false, proj.data());
|
glUniformMatrix4fv(2, 1, false, proj.data());
|
||||||
glUniformMatrix4fv(3, 1, false, state.rot.data());
|
glUniformMatrix4fv(3, 1, false, state.rot.data());
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei) dynamic.cells().size(), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, elements, GL_UNSIGNED_INT, nullptr);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
glUseProgram(wire_pgm);
|
glUseProgram(pgm4d);
|
||||||
glBindVertexArray(wire_vao);
|
glBindVertexArray(vao4d);
|
||||||
glUniform4fv(0, 1, state.wf.data());
|
glUniform4fv(0, 1, state.wf.data());
|
||||||
glUniform1f(1, (GLfloat) glfwGetTime());
|
glUniform1f(1, (GLfloat) glfwGetTime());
|
||||||
glUniformMatrix4fv(2, 1, false, proj.data());
|
glUniformMatrix4fv(2, 1, false, proj.data());
|
||||||
@@ -320,8 +232,7 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glUniform4fv(0, 1, state.wf.data());
|
glUniform4fv(0, 1, state.wf.data());
|
||||||
glDrawElements(GL_LINES, (GLsizei) wire_dynamic.cells().size(), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_LINES, elements4d, GL_UNSIGNED_INT, nullptr);
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
@@ -329,14 +240,6 @@ int run(GLFWwindow *window, ImGuiContext *context) {
|
|||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteBuffers(1, &vbo);
|
|
||||||
glDeleteBuffers(1, &ibo);
|
|
||||||
glDeleteVertexArrays(1, &vao);
|
|
||||||
|
|
||||||
glDeleteBuffers(1, &wire_vbo);
|
|
||||||
glDeleteBuffers(1, &wire_ibo);
|
|
||||||
glDeleteVertexArrays(1, &wire_vao);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user