need to think about resource management
This commit is contained in:
parent
d2de6d410f
commit
dd908ead95
11 changed files with 180 additions and 23 deletions
|
@ -12,6 +12,7 @@ set(hdrs
|
||||||
include/pw/core/quaternion.hpp
|
include/pw/core/quaternion.hpp
|
||||||
include/pw/core/image.hpp
|
include/pw/core/image.hpp
|
||||||
include/pw/core/point.hpp
|
include/pw/core/point.hpp
|
||||||
|
include/pw/core/resource.hpp
|
||||||
include/pw/core/rectangle.hpp
|
include/pw/core/rectangle.hpp
|
||||||
include/pw/core/serialize.hpp
|
include/pw/core/serialize.hpp
|
||||||
include/pw/core/size.hpp
|
include/pw/core/size.hpp
|
||||||
|
@ -30,10 +31,11 @@ set(misc
|
||||||
|
|
||||||
set(srcs
|
set(srcs
|
||||||
# src/buffer.cpp
|
# src/buffer.cpp
|
||||||
|
src/core.cpp
|
||||||
src/image.cpp
|
src/image.cpp
|
||||||
src/debug.cpp
|
src/debug.cpp
|
||||||
src/mesh.cpp
|
src/mesh.cpp
|
||||||
src/core.cpp
|
src/resource.cpp
|
||||||
src/serialize.cpp
|
src/serialize.cpp
|
||||||
src/time.cpp
|
src/time.cpp
|
||||||
src/image.cpp
|
src/image.cpp
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
const static double __PW_PI = 3.1415926535897932384626433832795028841971693993751058209;
|
const static double __PW_PI = 3.1415926535897932384626433832795028841971693993751058209;
|
||||||
|
const static double __PW_PI_DOUBLE = 2.0 * __PW_PI;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline const T pi() { return static_cast<T>(__PW_PI); }
|
inline const T pi() { return static_cast<T>(__PW_PI); }
|
||||||
|
@ -59,6 +60,11 @@ inline T ping_pong(const T& t,const T& length) {
|
||||||
return length - std::abs(tn - length);
|
return length - std::abs(tn - length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T wrap_angle(const T& angle_in_radian) {
|
||||||
|
using std::floor;
|
||||||
|
return angle_in_radian - __PW_PI_DOUBLE * floor( angle_in_radian / __PW_PI_DOUBLE );
|
||||||
|
}
|
||||||
|
|
||||||
//void extractRotation(const matrix &A, Quaterniond &q,const unsigned int maxIter)
|
//void extractRotation(const matrix &A, Quaterniond &q,const unsigned int maxIter)
|
||||||
//{
|
//{
|
||||||
|
|
|
@ -72,6 +72,10 @@ struct matrixbase_ {
|
||||||
return *this / this->norm() ;
|
return *this / this->norm() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void normalize() {
|
||||||
|
*this /= this->norm();
|
||||||
|
}
|
||||||
|
|
||||||
using iterator = T*;
|
using iterator = T*;
|
||||||
using const_iterator = const T*;
|
using const_iterator = const T*;
|
||||||
iterator begin() { return &derived().data[0]; }
|
iterator begin() { return &derived().data[0]; }
|
||||||
|
@ -88,8 +92,12 @@ struct matrixbase_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
static T dot(const Derived &a,const Derived &b) {
|
static T dot(const Derived &a,const Derived &b) {
|
||||||
|
#if 0
|
||||||
Derived r; for (size_t i = 0;i < a.size();i++) r[i] = a[i] * b[i];
|
Derived r; for (size_t i = 0;i < a.size();i++) r[i] = a[i] * b[i];
|
||||||
return std::accumulate(std::begin(r), std::end(r), T(0));
|
return std::accumulate(std::begin(r), std::end(r), T(0));
|
||||||
|
#else
|
||||||
|
return std::inner_product(std::begin(a),std::end(a),std::begin(b),T(0));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Derived lerp(const Derived &a,const Derived &b,const T& t) {
|
static const Derived lerp(const Derived &a,const Derived &b,const T& t) {
|
||||||
|
@ -97,16 +105,18 @@ struct matrixbase_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// inline Derived& operator *= (const T& b) { for (auto & e : *this) e *= b; return derived(); }
|
inline void operator *= (const T& b) { for (auto & e : *this) e *= b; }
|
||||||
// inline Derived& operator /= (const T& b) { for (auto & e : *this) e /= b; return derived(); }
|
inline void operator /= (const T& b) { for (auto & e : *this) e /= b; }
|
||||||
// inline Derived& operator += (const T& b) { for (auto & e : *this) e += b; return derived(); }
|
inline void operator += (const T& b) { for (auto & e : *this) e += b; }
|
||||||
// inline Derived& operator -= (const T& b) { for (auto & e : *this) e -= b; return derived(); }
|
inline void operator -= (const T& b) { for (auto & e : *this) e -= b; }
|
||||||
|
|
||||||
inline const Derived operator * (const T& b) const { Derived r(derived()); for (auto & e : r) e *= b; return r; }
|
inline const Derived operator * (const T& b) const { Derived r(derived()); for (auto & e : r) e *= b; return r; }
|
||||||
inline const Derived operator / (const T& b) const { Derived r(derived()); for (auto & e : r) e /= b; return r; }
|
inline const Derived operator / (const T& b) const { Derived r(derived()); for (auto & e : r) e /= b; return r; }
|
||||||
inline const Derived operator + (const T& b) const { Derived r(derived()); for (auto & e : r) e += b; return r; }
|
inline const Derived operator + (const T& b) const { Derived r(derived()); for (auto & e : r) e += b; return r; }
|
||||||
inline const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; }
|
inline const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <pw/core/globals.hpp>
|
#include <pw/core/globals.hpp>
|
||||||
#include <pw/core/vector.hpp>
|
#include <pw/core/vector.hpp>
|
||||||
#include <pw/core/aabb.hpp>
|
#include <pw/core/aabb.hpp>
|
||||||
|
#include <pw/core/resource.hpp>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
@ -64,6 +65,11 @@ public:
|
||||||
|
|
||||||
aabb aabb() const { return _aabb; }
|
aabb aabb() const { return _aabb; }
|
||||||
|
|
||||||
|
void compute_normals();
|
||||||
|
|
||||||
|
void set_normals(const mesh::vertex3array_t &v);
|
||||||
|
const mesh::vertex3array_t& normals() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
|
45
src/core/include/pw/core/resource.hpp
Normal file
45
src/core/include/pw/core/resource.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999-2019 Hartmut Seichter
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef PW_CORE_RESOURCE_HPP
|
||||||
|
#define PW_CORE_RESOURCE_HPP
|
||||||
|
|
||||||
|
#include <pw/core/globals.hpp>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace pw {
|
||||||
|
|
||||||
|
class resource {
|
||||||
|
public:
|
||||||
|
using change_t = std::atomic_int_fast64_t;
|
||||||
|
|
||||||
|
int64_t changecount() { return _changecount; }
|
||||||
|
void dirty() { ++_changecount; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
change_t _changecount;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -35,7 +35,7 @@ namespace pw {
|
||||||
class time {
|
class time {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> tick_t;
|
using tick_t = std::chrono::time_point<std::chrono::high_resolution_clock> ;
|
||||||
|
|
||||||
time(); /// c'tor
|
time(); /// c'tor
|
||||||
~time(); /// d'tor
|
~time(); /// d'tor
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "pw/core/mesh.hpp"
|
#include "pw/core/mesh.hpp"
|
||||||
|
#include "pw/core/debug.hpp"
|
||||||
|
#include "pw/core/serialize.hpp"
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
@ -6,6 +8,58 @@ mesh::mesh()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mesh::compute_normals()
|
||||||
|
{
|
||||||
|
|
||||||
|
// assumption is that we have some array as the vertices
|
||||||
|
vertex3array_t normals; normals.resize(_vertices.size());
|
||||||
|
|
||||||
|
// for indexed-faceset
|
||||||
|
for (auto i = 1; i < _indices.size()-1;i++)
|
||||||
|
{
|
||||||
|
// left index and right index
|
||||||
|
auto il = (i - 1 + _indices.size()) % _indices.size();
|
||||||
|
auto ir = (i + 1 + _indices.size()) % _indices.size();
|
||||||
|
|
||||||
|
// translate to actual indices
|
||||||
|
auto ci = _indices[ i];
|
||||||
|
auto li = _indices[il];
|
||||||
|
auto ri = _indices[ir];
|
||||||
|
|
||||||
|
// calculate delta vectors
|
||||||
|
auto dL = vector3( _vertices[li] - _vertices[ci] );
|
||||||
|
auto dR = vector3( _vertices[ri] - _vertices[ci] );
|
||||||
|
|
||||||
|
auto N = dR.cross(dL).normalized();
|
||||||
|
|
||||||
|
//auto dV = _vertices[idx0].cross(_vertices[idx1]);
|
||||||
|
|
||||||
|
// NOTE that addition is ugly
|
||||||
|
normals[ci] = N + normals[ci];
|
||||||
|
normals[li] = N + normals[li];
|
||||||
|
normals[ri] = N + normals[ri];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & n : normals) {
|
||||||
|
n.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->set_normals(normals);
|
||||||
|
|
||||||
|
for (auto N : normals) {
|
||||||
|
debug::s() << "( " << serialize::matrix(N.transposed()) << ") ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for triangle-strip
|
||||||
|
|
||||||
|
|
||||||
|
// for triangle-fan
|
||||||
|
|
||||||
|
|
||||||
|
// now set back
|
||||||
|
}
|
||||||
|
|
||||||
void mesh::set_vertices(const mesh::vertex3array_t &v)
|
void mesh::set_vertices(const mesh::vertex3array_t &v)
|
||||||
{
|
{
|
||||||
// first set vertices
|
// first set vertices
|
||||||
|
@ -15,12 +69,26 @@ void mesh::set_vertices(const mesh::vertex3array_t &v)
|
||||||
compute_bounds();
|
compute_bounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mesh::set_normals(const mesh::vertex3array_t &v)
|
||||||
|
{
|
||||||
|
_normals = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mesh::vertex3array_t &mesh::normals() const
|
||||||
|
{
|
||||||
|
return _normals;
|
||||||
|
}
|
||||||
|
|
||||||
void mesh::apply(const matrix4x4 &m)
|
void mesh::apply(const matrix4x4 &m)
|
||||||
{
|
{
|
||||||
// apply transformation to all vertices
|
// apply transformation to all vertices
|
||||||
for (auto &v : _vertices)
|
for (auto &v : _vertices)
|
||||||
v = vector4(m * v.homogenous()).project();
|
v = vector4(m * v.homogenous()).project();
|
||||||
|
|
||||||
|
// apply to normals
|
||||||
|
for(auto &n : _normals)
|
||||||
|
n = vector4(m * n.homogenous(0)).xyz();
|
||||||
|
|
||||||
// recompute bounds
|
// recompute bounds
|
||||||
compute_bounds();
|
compute_bounds();
|
||||||
}
|
}
|
||||||
|
|
5
src/core/src/resource.cpp
Normal file
5
src/core/src/resource.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "pw/core/resource.hpp"
|
||||||
|
|
||||||
|
namespace pw {
|
||||||
|
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ struct triangle_renderer
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
mesh::vertex3array_t vertices = {
|
mesh::vertex3array_t vertices = {
|
||||||
{ 0.0f, 0.5f, z_val} // 0
|
{ 0.0f, 0.5f, z_val} // 0
|
||||||
,{ 0.5f, 0.0f, z_val} // 1
|
,{ 0.5f, 0.0f, z_val} // 1
|
||||||
,{-0.5f, 0.0f, z_val} // 2
|
,{-0.5f, 0.0f, z_val} // 2
|
||||||
};
|
};
|
||||||
|
@ -74,7 +74,7 @@ struct triangle_renderer
|
||||||
|
|
||||||
// geometry
|
// geometry
|
||||||
mesh::vertex3array_t vertices = {
|
mesh::vertex3array_t vertices = {
|
||||||
{-s, s, z_val} // 0
|
{-s, s, z_val} // 0
|
||||||
,{ s, s, z_val} // 1
|
,{ s, s, z_val} // 1
|
||||||
,{-s, -s, z_val} // 2
|
,{-s, -s, z_val} // 2
|
||||||
,{ s, -s, z_val} // 3
|
,{ s, -s, z_val} // 3
|
||||||
|
@ -90,6 +90,8 @@ struct triangle_renderer
|
||||||
amesh.set_indices(indices);
|
amesh.set_indices(indices);
|
||||||
amesh.set_vertices(vertices);
|
amesh.set_vertices(vertices);
|
||||||
|
|
||||||
|
amesh.compute_normals();
|
||||||
|
|
||||||
amesh_renderer.create(amesh);
|
amesh_renderer.create(amesh);
|
||||||
|
|
||||||
const char* vertex_shader_2 = R"(
|
const char* vertex_shader_2 = R"(
|
||||||
|
@ -101,8 +103,8 @@ struct triangle_renderer
|
||||||
in vec3 vertex_p;
|
in vec3 vertex_p;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * view * model * vec4(vertex_p, 1.0);
|
gl_Position = projection * view * model * vec4(vertex_p, 1.0);
|
||||||
// gl_Position = model * vec4(vertex_p, 1.0);
|
// gl_Position = model * vec4(vertex_p, 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
@ -111,7 +113,7 @@ struct triangle_renderer
|
||||||
uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0);
|
uniform vec4 input_color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
out vec4 frag_colour;
|
out vec4 frag_colour;
|
||||||
void main() {
|
void main() {
|
||||||
frag_colour = input_color;
|
frag_colour = input_color;
|
||||||
})";
|
})";
|
||||||
|
|
||||||
shader_p.set_source(vertex_shader_2,shader::code_type::vertex);
|
shader_p.set_source(vertex_shader_2,shader::code_type::vertex);
|
||||||
|
@ -138,8 +140,8 @@ struct triangle_renderer
|
||||||
model_mat = rot.to_matrix();
|
model_mat = rot.to_matrix();
|
||||||
|
|
||||||
matrix4x4f view_mat = matrix_transform<float>::look_at(vector3({0,0,0}),
|
matrix4x4f view_mat = matrix_transform<float>::look_at(vector3({0,0,0}),
|
||||||
vector3::forward(),
|
vector3::forward(),
|
||||||
vector3::up());
|
vector3::up());
|
||||||
// materials should carry this
|
// materials should carry this
|
||||||
#if 1
|
#if 1
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
@ -148,15 +150,15 @@ struct triangle_renderer
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
auto proj_mat = matrix_transform<float>::orthographic_projection(1.3,1.0,
|
auto proj_mat = matrix_transform<float>::orthographic_projection(1.3,1.0,
|
||||||
0.2f,100.f);
|
0.2f,100.f);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
auto proj_mat = matrix_transform<float>::perspective_projection(deg_to_rad(60.f),
|
auto proj_mat = matrix_transform<float>::perspective_projection(deg_to_rad(60.f),
|
||||||
1.3f,
|
1.3f,
|
||||||
0.2f,1000.f);
|
0.2f,1000.f);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// highly inefficient - should be cached -
|
// highly inefficient - should be cached -
|
||||||
|
@ -165,11 +167,17 @@ struct triangle_renderer
|
||||||
shader_p.set("view",view_mat);
|
shader_p.set("view",view_mat);
|
||||||
shader_p.set("projection",proj_mat);
|
shader_p.set("projection",proj_mat);
|
||||||
|
|
||||||
|
#if 0
|
||||||
// new version with ...
|
// new version with ...
|
||||||
shader::uniform_set us;
|
shader::uniform_set us;
|
||||||
us["input_color"] = col;
|
us["input_color"] = col;
|
||||||
|
us["model"] = model_mat;
|
||||||
|
us["view"] = view_mat;
|
||||||
|
us["projection"] = proj_mat;
|
||||||
|
|
||||||
// shader_p.set_uniforms(us);
|
shader_p.set_uniforms(us);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
amesh_renderer.draw();
|
amesh_renderer.draw();
|
||||||
|
|
||||||
|
@ -274,10 +282,10 @@ void pipeline::impl::draw()
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo_msaa);
|
||||||
|
|
||||||
// glClearColor(0,0,0,1);
|
// glClearColor(0,0,0,1);
|
||||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// glViewport(0,0,800,600);
|
// glViewport(0,0,800,600);
|
||||||
|
|
||||||
//
|
//
|
||||||
// draw pass
|
// draw pass
|
||||||
|
|
|
@ -220,6 +220,7 @@ void shader::set_uniforms(shader::uniform_set s)
|
||||||
std::visit([u](auto&& arg) {
|
std::visit([u](auto&& arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, vector4f>)
|
if constexpr (std::is_same_v<T, vector4f>)
|
||||||
|
// set(arg);
|
||||||
std::cout << "vec4f with type " << typeid(arg).name() << " " << serialize::matrix(arg) << '\n';
|
std::cout << "vec4f with type " << typeid(arg).name() << " " << serialize::matrix(arg) << '\n';
|
||||||
else
|
else
|
||||||
std::cout << "can't" << std::endl;
|
std::cout << "can't" << std::endl;
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct vertex_array::impl {
|
||||||
|
|
||||||
GLuint _vao = 0;
|
GLuint _vao = 0;
|
||||||
std::vector<GLuint> _vbos;
|
std::vector<GLuint> _vbos;
|
||||||
std::size_t _mesh_elements = {0};
|
GLint _mesh_elements = {0};
|
||||||
|
|
||||||
impl()
|
impl()
|
||||||
{
|
{
|
||||||
|
@ -37,6 +37,8 @@ struct vertex_array::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenVertexArrays(1,&_vao);
|
glGenVertexArrays(1,&_vao);
|
||||||
|
|
||||||
|
|
||||||
glBindVertexArray(_vao);
|
glBindVertexArray(_vao);
|
||||||
|
|
||||||
size_t arrays_needed = 0;
|
size_t arrays_needed = 0;
|
||||||
|
@ -56,7 +58,9 @@ struct vertex_array::impl {
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
|
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m.vertices().front()) * m.vertices().size(), m.vertices().data(),
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
sizeof(m.vertices().front()) * m.vertices().size(),
|
||||||
|
m.vertices().data(),
|
||||||
GL_STATIC_DRAW);
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
@ -86,6 +90,8 @@ struct vertex_array::impl {
|
||||||
{
|
{
|
||||||
glBindVertexArray(_vao);
|
glBindVertexArray(_vao);
|
||||||
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLint get_mode(vertex_array::)
|
// GLint get_mode(vertex_array::)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue