use custom enum to represent metadata of GL objects
This commit is contained in:
parent
f869f191f2
commit
d5b5e664d7
@ -14,12 +14,12 @@
|
||||
namespace nf7::gl {
|
||||
|
||||
nf7::Future<std::shared_ptr<Obj<Obj_BufferMeta>>> Obj_BufferMeta::Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx, GLenum type) noexcept {
|
||||
const std::shared_ptr<nf7::Context>& ctx, gl::BufferTarget target) noexcept {
|
||||
nf7::Future<std::shared_ptr<Obj<Obj_BufferMeta>>>::Promise pro {ctx};
|
||||
ctx->env().ExecGL(ctx, [=]() mutable {
|
||||
GLuint id;
|
||||
glGenBuffers(1, &id);
|
||||
pro.Return(std::make_shared<Obj<Obj_BufferMeta>>(ctx, id, type));
|
||||
pro.Return(std::make_shared<Obj<Obj_BufferMeta>>(ctx, id, target));
|
||||
});
|
||||
return pro.future();
|
||||
}
|
||||
@ -27,29 +27,29 @@ nf7::Future<std::shared_ptr<Obj<Obj_BufferMeta>>> Obj_BufferMeta::Create(
|
||||
|
||||
nf7::Future<std::shared_ptr<Obj<Obj_TextureMeta>>> Obj_TextureMeta::Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx,
|
||||
GLenum type, GLint fmt, std::array<GLsizei, 3> size) noexcept {
|
||||
gl::TextureTarget target, GLint fmt, std::array<GLsizei, 3> size) noexcept {
|
||||
nf7::Future<std::shared_ptr<Obj<Obj_TextureMeta>>>::Promise pro {ctx};
|
||||
ctx->env().ExecGL(ctx, [=]() mutable {
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
|
||||
glBindTexture(type, id);
|
||||
glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
switch (type) {
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_RECTANGLE:
|
||||
glTexImage2D(type, 0, fmt, size[0], size[1], 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
|
||||
const auto t = gl::ToEnum(target);
|
||||
glBindTexture(t, id);
|
||||
glTexParameteri(t, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(t, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(t, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(t, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
switch (gl::GetDimension(target)) {
|
||||
case 2:
|
||||
glTexImage2D(t, 0, fmt, size[0], size[1], 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
|
||||
break;
|
||||
default:
|
||||
assert(false && "unknown texture type");
|
||||
assert(false && "unknown texture target");
|
||||
break;
|
||||
}
|
||||
glBindTexture(type, 0);
|
||||
glBindTexture(t, 0);
|
||||
|
||||
pro.Return(std::make_shared<Obj<Obj_TextureMeta>>(ctx, id, type, fmt, size));
|
||||
pro.Return(std::make_shared<Obj<Obj_TextureMeta>>(ctx, id, target, fmt, size));
|
||||
});
|
||||
return pro.future();
|
||||
}
|
||||
@ -57,11 +57,12 @@ nf7::Future<std::shared_ptr<Obj<Obj_TextureMeta>>> Obj_TextureMeta::Create(
|
||||
|
||||
nf7::Future<std::shared_ptr<Obj<Obj_ShaderMeta>>> Obj_ShaderMeta::Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx,
|
||||
GLenum type,
|
||||
gl::ShaderType type,
|
||||
const std::string& src) noexcept {
|
||||
nf7::Future<std::shared_ptr<Obj<Obj_ShaderMeta>>>::Promise pro {ctx};
|
||||
ctx->env().ExecGL(ctx, [=]() mutable {
|
||||
const auto id = glCreateShader(type);
|
||||
const auto t = gl::ToEnum(type);
|
||||
const auto id = glCreateShader(t);
|
||||
if (id == 0) {
|
||||
pro.Throw<nf7::Exception>("failed to allocate new shader");
|
||||
return;
|
||||
@ -146,7 +147,7 @@ try {
|
||||
// check all buffers
|
||||
assert(attrs.size() == bufs.size());
|
||||
for (auto& buf : bufs) {
|
||||
if ((*buf.value()).meta().type != GL_ARRAY_BUFFER) {
|
||||
if ((*buf.value()).meta().target != gl::BufferTarget::Array) {
|
||||
throw nf7::Exception {"buffer is not Array"};
|
||||
}
|
||||
}
|
||||
@ -164,7 +165,7 @@ try {
|
||||
glVertexAttribPointer(
|
||||
attr.index,
|
||||
attr.size,
|
||||
attr.type,
|
||||
gl::ToEnum(attr.type),
|
||||
attr.normalize,
|
||||
attr.stride,
|
||||
reinterpret_cast<GLvoid*>(static_cast<GLintptr>(attr.offset)));
|
||||
@ -194,28 +195,7 @@ try {
|
||||
// calculate size required to the buffer
|
||||
size_t required = 0;
|
||||
if (attr.divisor == 0 && vcnt > 0) {
|
||||
required = static_cast<size_t>(attr.size)*vcnt;
|
||||
switch (attr.type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
case GL_BYTE:
|
||||
required *= 1;
|
||||
break;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
case GL_SHORT:
|
||||
case GL_HALF_FLOAT:
|
||||
required *= 2;
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_INT:
|
||||
case GL_FLOAT:
|
||||
required *= 4;
|
||||
break;
|
||||
case GL_DOUBLE:
|
||||
required *= 8;
|
||||
break;
|
||||
default:
|
||||
throw nf7::Exception {"unknown attribute type"};
|
||||
}
|
||||
required = static_cast<size_t>(attr.size)*vcnt*gl::GetByteSize(attr.type);
|
||||
} else if (attr.divisor > 0 && icnt > 0) {
|
||||
required = static_cast<size_t>(attr.stride)*(icnt-1) + attr.offset;
|
||||
}
|
||||
@ -230,7 +210,7 @@ try {
|
||||
return v;
|
||||
});
|
||||
|
||||
// register a future of the validation
|
||||
// register the validation future
|
||||
apro.Add(pro.future());
|
||||
fus.emplace_back(pro.future());
|
||||
}
|
||||
@ -264,7 +244,7 @@ nf7::Future<std::shared_ptr<Obj<Obj_FramebufferMeta>>> Obj_FramebufferMeta::Crea
|
||||
const char* err = nullptr;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, id);
|
||||
for (size_t i = 0; i < atts.size() && !err; ++i) {
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, atts[i].slot, (*texs[i])->id(), 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, gl::ToEnum(atts[i].slot), (*texs[i])->id(), 0);
|
||||
if (0 != glGetError()) {
|
||||
err = "failed to attach texture";
|
||||
}
|
||||
@ -296,7 +276,7 @@ try {
|
||||
auto fu = ctx->env().GetFileOrThrow(attachment.tex).
|
||||
interfaceOrThrow<nf7::gl::TextureFactory>().Create().
|
||||
Chain(nf7::Env::kGL, ctx, pro, [](auto& tex) {
|
||||
if ((*tex)->meta().type != GL_TEXTURE_2D) {
|
||||
if ((*tex)->meta().target != gl::TextureTarget::Tex2D) {
|
||||
throw nf7::Exception {"only 2D texture is allowed"};
|
||||
}
|
||||
return tex;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "common/factory.hh"
|
||||
#include "common/future.hh"
|
||||
#include "common/gl_enum.hh"
|
||||
#include "common/mutex.hh"
|
||||
|
||||
|
||||
@ -57,17 +58,17 @@ struct Obj_BufferMeta final {
|
||||
public:
|
||||
// must be called from main or sub task
|
||||
static nf7::Future<std::shared_ptr<Obj<Obj_BufferMeta>>> Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx, GLenum type) noexcept;
|
||||
const std::shared_ptr<nf7::Context>& ctx, gl::BufferTarget target) noexcept;
|
||||
|
||||
static void Delete(GLuint id) noexcept {
|
||||
glDeleteBuffers(1, &id);
|
||||
}
|
||||
|
||||
Obj_BufferMeta() = delete;
|
||||
Obj_BufferMeta(GLenum t) noexcept : type(t) {
|
||||
Obj_BufferMeta(gl::BufferTarget t) noexcept : target(t) {
|
||||
}
|
||||
|
||||
const GLenum type;
|
||||
const gl::BufferTarget target;
|
||||
|
||||
size_t size = 0;
|
||||
};
|
||||
@ -80,18 +81,18 @@ struct Obj_TextureMeta final {
|
||||
// must be called from main or sub task
|
||||
static nf7::Future<std::shared_ptr<Obj<Obj_TextureMeta>>> Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx,
|
||||
GLenum type, GLint fmt, std::array<GLsizei, 3> size) noexcept;
|
||||
gl::TextureTarget target, GLint fmt, std::array<GLsizei, 3> size) noexcept;
|
||||
|
||||
static void Delete(GLuint id) noexcept {
|
||||
glDeleteTextures(1, &id);
|
||||
}
|
||||
|
||||
Obj_TextureMeta() = delete;
|
||||
Obj_TextureMeta(GLenum t, GLint f, std::array<GLsizei, 3> s) noexcept :
|
||||
type(t), format(f), size(s) {
|
||||
Obj_TextureMeta(gl::TextureTarget t, GLint f, std::array<GLsizei, 3> s) noexcept :
|
||||
target(t), format(f), size(s) {
|
||||
}
|
||||
|
||||
const GLenum type;
|
||||
const gl::TextureTarget target;
|
||||
const GLint format;
|
||||
const std::array<GLsizei, 3> size;
|
||||
};
|
||||
@ -104,7 +105,7 @@ struct Obj_ShaderMeta final {
|
||||
// must be called from main or sub task
|
||||
static nf7::Future<std::shared_ptr<Obj<Obj_ShaderMeta>>> Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx,
|
||||
GLenum type,
|
||||
gl::ShaderType type,
|
||||
const std::string& src) noexcept;
|
||||
|
||||
static void Delete(GLuint id) noexcept {
|
||||
@ -112,10 +113,10 @@ struct Obj_ShaderMeta final {
|
||||
}
|
||||
|
||||
Obj_ShaderMeta() = delete;
|
||||
Obj_ShaderMeta(GLenum t) noexcept : type(t) {
|
||||
Obj_ShaderMeta(gl::ShaderType t) noexcept : type(t) {
|
||||
}
|
||||
|
||||
const GLenum type;
|
||||
const gl::ShaderType type;
|
||||
};
|
||||
using Shader = Obj<Obj_ShaderMeta>;
|
||||
using ShaderFactory = AsyncFactory<nf7::Mutex::Resource<std::shared_ptr<Shader>>>;
|
||||
@ -144,14 +145,14 @@ struct Obj_VertexArrayMeta final {
|
||||
nf7::Future<std::vector<nf7::Mutex::Resource<std::shared_ptr<gl::Buffer>>>>;
|
||||
|
||||
struct Attr {
|
||||
nf7::File::Id buffer;
|
||||
GLuint index;
|
||||
GLint size;
|
||||
GLenum type;
|
||||
bool normalize;
|
||||
GLsizei stride;
|
||||
uint64_t offset;
|
||||
GLuint divisor;
|
||||
nf7::File::Id buffer;
|
||||
GLuint index;
|
||||
GLint size;
|
||||
gl::NumericType type;
|
||||
bool normalize;
|
||||
GLsizei stride;
|
||||
uint64_t offset;
|
||||
GLuint divisor;
|
||||
};
|
||||
|
||||
// must be called from main or sub task
|
||||
@ -189,8 +190,8 @@ struct Obj_FramebufferMeta final {
|
||||
nf7::Future<std::vector<nf7::Mutex::Resource<std::shared_ptr<gl::Texture>>>>;
|
||||
|
||||
struct Attachment {
|
||||
nf7::File::Id tex;
|
||||
GLenum slot;
|
||||
nf7::File::Id tex;
|
||||
gl::FramebufferSlot slot;
|
||||
};
|
||||
|
||||
// must be called from main or sub task
|
||||
|
@ -273,7 +273,7 @@ struct Buffer {
|
||||
}
|
||||
|
||||
nf7::Future<std::shared_ptr<Product>> Create(const std::shared_ptr<nf7::Context>& ctx) noexcept {
|
||||
return Product::Create(ctx, gl::ToEnum(target_));
|
||||
return Product::Create(ctx, target_);
|
||||
}
|
||||
|
||||
bool Handle(const std::shared_ptr<nf7::Node::Lambda>& handler,
|
||||
@ -289,16 +289,17 @@ struct Buffer {
|
||||
|
||||
auto& buf = **res;
|
||||
auto& m = buf.meta();
|
||||
glBindBuffer(m.type, buf.id());
|
||||
const auto t = gl::ToEnum(m.target);
|
||||
glBindBuffer(t, buf.id());
|
||||
{
|
||||
if (m.size != vec->size()) {
|
||||
m.size = vec->size();
|
||||
glBufferData(m.type, n, vec->data(), usage);
|
||||
glBufferData(t, n, vec->data(), usage);
|
||||
} else {
|
||||
glBufferSubData(m.type, 0, n, vec->data());
|
||||
glBufferSubData(t, 0, n, vec->data());
|
||||
}
|
||||
}
|
||||
glBindBuffer(m.type, 0);
|
||||
glBindBuffer(t, 0);
|
||||
assert(0 == glGetError());
|
||||
});
|
||||
return true;
|
||||
@ -409,7 +410,7 @@ struct Texture {
|
||||
[](auto x) { return static_cast<GLsizei>(x); });
|
||||
// FIXME cast is unnecessary
|
||||
return Product::Create(
|
||||
ctx, gl::ToEnum(target_), static_cast<GLint>(gl::ToInternalFormat(numtype_, comp_)), size);
|
||||
ctx, target_, static_cast<GLint>(gl::ToInternalFormat(numtype_, comp_)), size);
|
||||
} catch (nf7::Exception&) {
|
||||
return {std::current_exception()};
|
||||
}
|
||||
@ -449,12 +450,12 @@ struct Texture {
|
||||
const auto fmt = gl::ToEnum(comp_);
|
||||
const auto type = gl::ToEnum(numtype_);
|
||||
handler->env().ExecGL(handler, [=, &tex]() {
|
||||
const auto target = tex.meta().type;
|
||||
glBindTexture(target, tex.id());
|
||||
switch (target) {
|
||||
const auto t = gl::ToEnum(tex.meta().target);
|
||||
glBindTexture(t, tex.id());
|
||||
switch (t) {
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_RECTANGLE:
|
||||
glTexSubImage2D(target, 0,
|
||||
glTexSubImage2D(t, 0,
|
||||
static_cast<GLint>(offset[0]),
|
||||
static_cast<GLint>(offset[1]),
|
||||
static_cast<GLsizei>(size[0]),
|
||||
@ -465,7 +466,7 @@ struct Texture {
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
glBindTexture(target, 0);
|
||||
glBindTexture(t, 0);
|
||||
assert(0 == glGetError());
|
||||
});
|
||||
return true;
|
||||
@ -486,10 +487,10 @@ struct Texture {
|
||||
const auto bsize = static_cast<size_t>(texel)*GetCompCount(comp)*GetByteSize(numtype);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, static_cast<GLsizeiptr>(bsize), nullptr, GL_DYNAMIC_READ);
|
||||
|
||||
const auto target = tex.meta().type;
|
||||
glBindTexture(target, tex.id());
|
||||
glGetTexImage(target, 0, gl::ToEnum(comp), gl::ToEnum(numtype), nullptr);
|
||||
glBindTexture(target, 0);
|
||||
const auto t = gl::ToEnum(tex.meta().target);
|
||||
glBindTexture(t, tex.id());
|
||||
glGetTexImage(t, 0, gl::ToEnum(comp), gl::ToEnum(numtype), nullptr);
|
||||
glBindTexture(t, 0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
assert(0 == glGetError());
|
||||
|
||||
@ -543,7 +544,7 @@ struct Texture {
|
||||
const auto& m = prod->meta();
|
||||
ImGui::Text("id: %" PRIiPTR, id);
|
||||
|
||||
if (m.type == GL_TEXTURE_2D) {
|
||||
if (m.target == gl::TextureTarget::Tex2D) {
|
||||
ImGui::Spacing();
|
||||
ImGui::TextUnformatted("preview:");
|
||||
ImGui::Image(reinterpret_cast<void*>(id),
|
||||
@ -615,7 +616,7 @@ struct Shader {
|
||||
nf7::Future<std::shared_ptr<Product>> Create(
|
||||
const std::shared_ptr<nf7::Context>& ctx) noexcept {
|
||||
// TODO: preprocessing GLSL source
|
||||
return Product::Create(ctx, gl::ToEnum(type_), src_);
|
||||
return Product::Create(ctx, type_, src_);
|
||||
}
|
||||
|
||||
bool Handle(const std::shared_ptr<nf7::Node::Lambda>&,
|
||||
@ -1012,7 +1013,7 @@ struct VertexArray {
|
||||
.buffer = base.ResolveOrThrow(attr.buffer).id(),
|
||||
.index = attr.index,
|
||||
.size = attr.size,
|
||||
.type = gl::ToEnum(attr.type),
|
||||
.type = attr.type,
|
||||
.normalize = attr.normalize,
|
||||
.stride = attr.stride,
|
||||
.offset = attr.offset,
|
||||
@ -1123,7 +1124,7 @@ struct Framebuffer {
|
||||
}
|
||||
attachments.push_back({
|
||||
.tex = fid,
|
||||
.slot = gl::ToEnum(attachment.slot),
|
||||
.slot = attachment.slot,
|
||||
});
|
||||
}
|
||||
return Product::Create(ctx, std::move(attachments));
|
||||
|
Loading…
x
Reference in New Issue
Block a user