shader asset

This commit is contained in:
2018-11-28 19:22:20 +07:00
parent 27c7ce57d5
commit 8879e86c15
6 changed files with 131 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ namespace e2d
class text_asset;
class image_asset;
class binary_asset;
class shader_asset;
class texture_asset;
template < typename T >

View File

@@ -42,6 +42,12 @@ namespace e2d
static std::shared_ptr<binary_asset> load(library& library, str_view address);
};
class shader_asset final : public content_asset<shader_ptr> {
public:
using content_asset<shader_ptr>::content_asset;
static std::shared_ptr<shader_asset> load(library& library, str_view address);
};
class texture_asset final : public content_asset<texture_ptr> {
public:
using content_asset<texture_ptr>::content_asset;

View File

@@ -6,9 +6,66 @@
#include <enduro2d/high/assets.hpp>
#include <3rdparty/rapidjson/schema.h>
#include <3rdparty/rapidjson/document.h>
namespace
{
using namespace e2d;
template < typename T >
const char* asset_schema_source() noexcept;
template <>
const char* asset_schema_source<shader_asset>() noexcept {
return R"json({
"type" : "object",
"required" : [ "vertex", "fragment" ],
"properties" : {
"vertex" : { "type" : "string", "minLength" : 1 },
"fragment" : { "type" : "string", "minLength" : 1 }
}
})json";
}
template < typename T >
const rapidjson::SchemaDocument& asset_file_schema() {
static std::unique_ptr<rapidjson::SchemaDocument> schema;
if ( !schema ) {
rapidjson::Document doc;
if ( doc.Parse(asset_schema_source<T>()).HasParseError() ) {
the<debug>().error("ASSETS: Failed to parse asset file schema");
throw bad_library_operation();
}
schema = std::make_unique<rapidjson::SchemaDocument>(doc);
}
return *schema;
}
template < typename T >
bool load_json_asset_file(library& library, str_view address, rapidjson::Document& doc) {
const auto json_data = library.load_asset<text_asset>(address);
if ( !json_data ) {
return false;
}
if ( doc.Parse(json_data->content().c_str()).HasParseError() ) {
the<debug>().error("ASSETS: Failed to parse json asset file:\n"
"--> Address: %0",
address);
return false;
}
rapidjson::SchemaValidator validator(asset_file_schema<T>());
if ( !doc.Accept(validator) ) {
the<debug>().error("ASSETS: Failed to validate json asset file:\n"
"--> Address: %0",
address);
return false;
}
return true;
}
}
namespace e2d
@@ -88,6 +145,48 @@ namespace e2d
return std::make_shared<binary_asset>(std::move(content));
}
//
// shader_asset
//
std::shared_ptr<shader_asset> shader_asset::load(library& library, str_view address) {
rapidjson::Document doc;
if ( !load_json_asset_file<shader_asset>(library, address, doc) ) {
return nullptr;
}
const auto parent_address = path::parent_path(address);
E2D_ASSERT(doc.HasMember("vertex") && doc["vertex"].IsString());
const auto vertex_source_data = library.load_asset<text_asset>(
path::combine(parent_address, doc["vertex"].GetString()));
if ( !vertex_source_data ) {
return nullptr;
}
E2D_ASSERT(doc.HasMember("fragment") && doc["fragment"].IsString());
const auto fragment_source_data = library.load_asset<text_asset>(
path::combine(parent_address, doc["fragment"].GetString()));
if ( !fragment_source_data ) {
return nullptr;
}
const auto content = the<render>().create_shader(
vertex_source_data->content(),
fragment_source_data->content());
if ( !content ) {
the<debug>().error("ASSETS: Failed to create shader asset:\n"
"--> Address: %0",
address);
return nullptr;
}
return std::make_shared<shader_asset>(content);
}
//
// texture_asset
//

View File

@@ -0,0 +1,9 @@
#version 120
uniform sampler2D u_texture;
varying vec2 v_st;
void main() {
vec2 st = vec2(v_st.s, 1.0 - v_st.t);
gl_FragColor = texture2D(u_texture, st);
}

View File

@@ -0,0 +1,4 @@
{
"vertex" : "shader.vert",
"fragment" : "shader.frag"
}

View File

@@ -0,0 +1,12 @@
#version 120
attribute vec3 a_position;
attribute vec2 a_st;
uniform mat4 u_MVP;
varying vec2 v_st;
void main() {
v_st = a_st;
gl_Position = vec4(a_position, 1.0) * u_MVP;
}