added proper texturing support

This commit is contained in:
Hartmut Seichter 2021-02-04 22:56:27 +01:00
parent 749bb67c6c
commit b25ab14587
9 changed files with 108 additions and 61 deletions

View file

@ -236,7 +236,7 @@ void register_core_function(sol::state& lua,sol::table& ns)
ns.new_usertype<rectangle>("rectangle" ns.new_usertype<rectangle>("rectangle"
,sol::constructors<rectangle(),rectangle(const point_<float>&,const size_<float>&)>() ,sol::call_constructor,sol::constructors<rectangle(),rectangle(const point_<float>&,const size_<float>&)>()
); );
auto mathf_table = ns.create_named("mathf"); auto mathf_table = ns.create_named("mathf");

View file

@ -38,12 +38,14 @@ struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
using matrixbase_<T, matrix_<R, C, T>>::matrixbase_; using matrixbase_<T, matrix_<R, C, T>>::matrixbase_;
static const std::size_t rows = R; static constexpr std::size_t rows { R };
static const std::size_t cols = C; static constexpr std::size_t cols { C };
typedef matrix_<R,1,T> col_type; static constexpr std::size_t coefficients { R * C };
typedef matrix_<1,C,T> row_type;
typedef matrix_<C,R,T> transpose_type; using col_type = matrix_<R,1,T>;
using row_type = matrix_<1,C,T>;
using transpose_type = matrix_<C,R,T>;
matrix_(const matrix_<R,C,T>& other) matrix_(const matrix_<R,C,T>& other)
{ {

View file

@ -68,7 +68,7 @@ struct matrixbase_ {
return std::sqrt(squared_norm()); return std::sqrt(squared_norm());
} }
inline const Derived normalized() const { inline constexpr Derived normalized() const {
return *this / this->norm() ; return *this / this->norm() ;
} }

View file

@ -17,47 +17,33 @@ namespace pw {
void geometry::compute_normals() void geometry::compute_normals()
{ {
// assumption is that we have some array as the vertices // assumption is that we have some array as the vertices
vector3_array normals; _normals.resize(_vertices.size()); vector3_array new_normals(_vertices.size());
if (_primitive_topology == primitive_topology_type::triangle_list)
{
// for indexed-faceset // for indexed-faceset
for (size_t i = 1; i < _indices.size()-1;i++) for (std::size_t i = 0; i < _indices.size();i += 3)
{ {
// 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 // translate to actual indices
auto ci = _indices[ i]; auto li = _indices[i ];
auto li = _indices[il]; auto ci = _indices[i+1];
auto ri = _indices[ir]; auto ri = _indices[i+2];
// calculate edges between vertices // calculate edges between vertices
auto edgeLeft = vector3( _vertices[li] - _vertices[ci] ); auto edgeLeft = vector3( _vertices[li] - _vertices[ci] );
auto edgeRight = vector3( _vertices[ri] - _vertices[ci] ); auto edgeRight = vector3( _vertices[ri] - _vertices[ci] );
// calculate counter clockwise and normalize // calculate counter clockwise and normalize
auto N = vector3::cross(edgeRight,edgeLeft).normalized(); auto N = vector3(vector3::cross(edgeRight,edgeLeft)).normalized();
// NOTE that addition is ugly new_normals[li] = new_normals[ci] = new_normals[ri] = N.normalized();
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); this->set_normals(new_normals);
// for triangle-strip
// for triangle-fan
// now set back
} }
void geometry::compute_tangent_space() void geometry::compute_tangent_space()

View file

@ -10,11 +10,23 @@ int main(int argc,char **argv) {
pw::geometry geo; pw::geometry geo;
pw::vector3_array vs = { {-1,-1,0},{1,-1,0},{0,1,0} }; pw::vector3_array vs = {
{ -1, 1, 0 },
{ -1,-1, 0 },
{ 1,-1, 0 },
{ 1, 1, 0 }
};
pw::geometry::indices_t idx = {
0, 1, 2,
0, 2, 3
};
geo.set_vertices(vs); geo.set_vertices(vs);
geo.set_indices(idx);
geo.compute_normals();

View file

@ -36,6 +36,16 @@ int main(int ,char **) {
std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl; std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl;
auto e1 = pw::vector3 { 2.0, 0.0, 0.0 };
auto e2 = pw::vector3 { 0.0, 0.0, 2.0 };
auto e2_e1 = e1 - e2;
auto n_e1_e2 = pw::vector3::cross(e1,e2);
std::cout << "e1xe2 " << pw::serialize::matrix(n_e1_e2) << std::endl;
std::cout << "e1xe2 " << pw::serialize::matrix(e2_e1) << std::endl;
return 0; return 0;
} }

View file

@ -53,8 +53,8 @@ s = 1
-- indices -- indices
g.indices = { g.indices = {
0, 1, 2, 0, 1, 2, -- triangle #1
2, 3, 0 2, 3, 0 -- triangle #2
} }
print(g.indices,#g.indices) print(g.indices,#g.indices)
@ -64,15 +64,15 @@ print(g.indices,#g.indices)
g.vertices = { g.vertices = {
{ -s,-s, z }, { -s,-s, z },
{ s,-s, z }, { s,-s, z },
{ s, s, z } { s, s, z },
{ -s, s, z }
} }
-- 0 --- 3 -- 0 --- 3
-- | \ | -- | \ |
-- 1 --- 2 -- 1 --- 2
g:compute_normals()
local mm = pw.matrix4x4.identity local mm = pw.matrix4x4.identity
@ -83,27 +83,36 @@ local s = pw.shader:new()
s:set_source(pw.shader_type.vertex,[[ s:set_source(pw.shader_type.vertex,[[
#version 400 #version 400
layout (location = 0) in vec3 vertices;
layout (location = 1) in vec3 normals;
layout (location = 2) in vec2 texture_coords;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
uniform mat4 projection; uniform mat4 projection;
in vec3 vertex_p;
in vec2 texture_coord; out vec2 tex_c;
void main() { void main() {
gl_Position = projection * view * model * vec4(vertex_p, 1.0); tex_c = texture_coords;
gl_Position = projection * view * model * vec4(vertices, 1.0);
} }
]]) ]])
s:set_source(pw.shader_type.fragment,[[ s:set_source(pw.shader_type.fragment,[[
#version 400 #version 400
uniform vec4 color = vec4(1.0, 0.0, 0.0, 1.0); uniform vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
uniform sampler2D tex_color; uniform sampler2D tex_color;
in vec2 tex_c;
out vec4 frag_color; out vec4 frag_color;
void main() { void main() {
frag_color = texture(tex_color,vec2(1.0,1.0)) * color; frag_color = texture(tex_color,tex_c) * color;
} }
]]) ]])
@ -132,7 +141,7 @@ tx:create(img)
w.on_resize = function(self) w.on_resize = function(self)
-- use client_size to resize the viewport -- use client_size to resize the viewport
ctx:set_viewport(pw.rectangle:new(pw.point:new(0,0),self.client_size:cast_to_float())) ctx:set_viewport(pw.rectangle(pw.point(0,0),self.client_size:cast_to_float()))
end end

View file

@ -15,7 +15,7 @@ struct renderer::impl {
uint32_t _vao { 0 }; uint32_t _vao { 0 };
uint32_t _ebo { 0 }; uint32_t _ebo { 0 };
uint32_t _vbo { 0 }; std::vector<uint32_t> _vbos { };
GLint _mesh_elements = { 0 }; GLint _mesh_elements = { 0 };
@ -42,10 +42,10 @@ struct renderer::impl {
// //
glGenVertexArrays(1,&_vao); glGenVertexArrays(1,&_vao);
glGenBuffers(1, &_vbo); glBindVertexArray(_vao);
glGenBuffers(1, &_ebo); glGenBuffers(1, &_ebo);
glBindVertexArray(_vao);
// TODO binding separate VBOs to the // TODO binding separate VBOs to the
// vertexarray should be avoided // vertexarray should be avoided
@ -58,31 +58,58 @@ struct renderer::impl {
GL_STATIC_DRAW); GL_STATIC_DRAW);
_vbos.resize(_vbos.size()+1);
glGenBuffers(1, &_vbos.back());
// vertices // vertices
glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBindBuffer(GL_ARRAY_BUFFER, _vbos.back());
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glVertexAttribPointer(_vbos.size()-1, vector3::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr);
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER,
m.vertices().size() * sizeof(vector3), m.vertices().size() * sizeof(vector3),
m.vertices().data(), m.vertices().data(),
GL_STATIC_DRAW); GL_STATIC_DRAW);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(_vbos.size()-1);
debug::d() << "vertices at " << _vbos.size()-1;
if (!m.normals().empty()) if (!m.normals().empty())
{ {
_vbos.resize(_vbos.size()+1);
glGenBuffers(1, &_vbos.back());
// normals // normals
glBindBuffer(GL_ARRAY_BUFFER,_vbo); glBindBuffer(GL_ARRAY_BUFFER,_vbos.back());
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glVertexAttribPointer(_vbos.size()-1, vector3::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr);
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER,
m.normals().size() * sizeof(vector3), m.normals().size() * sizeof(vector3),
m.normals().data(), m.normals().data(),
GL_STATIC_DRAW); GL_STATIC_DRAW);
glEnableVertexAttribArray(1); glEnableVertexAttribArray(_vbos.size()-1);
// debug::d() << "normals at " << _vbos.size()-1;
} }
if (!m.texture_coordinates().empty())
{
for (const auto& tc : m.texture_coordinates())
{
_vbos.resize(_vbos.size()+1);
glGenBuffers(1, &_vbos.back());
// texture coordinates
glBindBuffer(GL_ARRAY_BUFFER,_vbos.back());
glVertexAttribPointer(_vbos.size()-1, vector2::coefficients, GL_FLOAT, GL_FALSE, 0, nullptr);
glBufferData(GL_ARRAY_BUFFER,
tc.size() * sizeof(vector2),
tc.data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(_vbos.size()-1);
debug::d() << "texture coordinates at " << _vbos.size()-1;
}
}
// stop binding // stop binding
glBindVertexArray(0); glBindVertexArray(0);
@ -104,7 +131,8 @@ struct renderer::impl {
void release() void release()
{ {
glDeleteBuffers(1,&_vbo); for (auto vbo : _vbos)
glDeleteBuffers(1,&vbo);
glDeleteBuffers(1,&_ebo); glDeleteBuffers(1,&_ebo);
glDeleteVertexArrays(1,&_vao); glDeleteVertexArrays(1,&_vao);

View file

@ -154,8 +154,8 @@ texture::texture()
} }
texture::texture(const image &i, texture::data_layout s) texture::texture(const image &i, texture::data_layout s)
: texture()
{ {
texture();
this->create(i); this->create(i);
} }