diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 9e60d485b..2893b4cc0 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -1936,7 +1936,12 @@ namespace endor int level, int layer) { - NOT_IMPLEMENTED(); + auto req = FramebufferTextureLayerCommandBufferRequest(static_cast(target), + static_cast(attachment), + texture != nullptr ? texture->id : 0, + level, + layer); + sendCommandBufferRequest(req); } string WebGL2Context::getActiveUniformBlockName(shared_ptr program, int uniformBlockIndex) diff --git a/src/client/script_bindings/webgl/webgl2_rendering_context.cpp b/src/client/script_bindings/webgl/webgl2_rendering_context.cpp index 8bace804f..f6797d1d1 100644 --- a/src/client/script_bindings/webgl/webgl2_rendering_context.cpp +++ b/src/client/script_bindings/webgl/webgl2_rendering_context.cpp @@ -3,6 +3,7 @@ #include "./buffer.hpp" #include "./program.hpp" #include "./vertex_array.hpp" +#include "./texture.hpp" namespace endor { @@ -417,6 +418,7 @@ namespace endor // Enhanced framebuffer operations ADD_WEBGL2_METHOD("blitFramebuffer", BlitFramebuffer) ADD_WEBGL2_METHOD("renderbufferStorageMultisample", RenderbufferStorageMultisample) + ADD_WEBGL2_METHOD("framebufferTextureLayer", FramebufferTextureLayer) // Enhanced texture operations ADD_WEBGL2_METHOD("texImage3D", TexImage3D) @@ -1701,6 +1703,81 @@ namespace endor args.GetReturnValue().SetUndefined(); } + void WebGL2RenderingContext::FramebufferTextureLayer(const v8::FunctionCallbackInfo &args) + { + Isolate *isolate = args.GetIsolate(); + HandleScope scope(isolate); + Local context = isolate->GetCurrentContext(); + + if (args.Length() < 5) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodArgCountError(isolate, "framebufferTextureLayer", 5, args.Length()))); + return; + } + if (!args[0]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodArgTypeError(isolate, "framebufferTextureLayer", 0, "number", args[0]))); + return; + } + if (!args[1]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodArgTypeError(isolate, "framebufferTextureLayer", 1, "number", args[1]))); + return; + } + if (!args[2]->IsNull() && !WebGLTexture::IsInstanceOf(isolate, args[2])) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodArgTypeError(isolate, "framebufferTextureLayer", 2, "WebGLTexture or null", args[2]))); + return; + } + if (!args[3]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodArgTypeError(isolate, "framebufferTextureLayer", 3, "number", args[3]))); + return; + } + if (!args[4]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodArgTypeError(isolate, "framebufferTextureLayer", 4, "number", args[4]))); + return; + } + + client_graphics::WebGLFramebufferBindingTarget target; + { + int value = args[0]->Int32Value(context).ToChecked(); + target = static_cast(value); + } + client_graphics::WebGLFramebufferAttachment attachment; + { + int value = args[1]->Int32Value(context).ToChecked(); + attachment = static_cast(value); + } + int level = args[3]->Int32Value(context).ToChecked(); + int layer = args[4]->Int32Value(context).ToChecked(); + + if (args[2]->IsNull()) + { + handle()->framebufferTextureLayer(target, attachment, nullptr, level, layer); + } + else + { + auto textureObj = args[2].As(); + auto textureBinding = WebGLTexture::Unwrap(isolate, textureObj); + if (textureBinding == nullptr || !textureBinding->hasData()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "framebufferTextureLayer", "Invalid WebGLTexture object"))); + return; + } + handle()->framebufferTextureLayer(target, attachment, textureBinding->handle(), level, layer); + } + args.GetReturnValue().SetUndefined(); + } + // Enhanced texture operations void WebGL2RenderingContext::TexImage3D(const FunctionCallbackInfo &args) { diff --git a/src/client/script_bindings/webgl/webgl2_rendering_context.hpp b/src/client/script_bindings/webgl/webgl2_rendering_context.hpp index bc7cbbea7..faf38623b 100644 --- a/src/client/script_bindings/webgl/webgl2_rendering_context.hpp +++ b/src/client/script_bindings/webgl/webgl2_rendering_context.hpp @@ -100,6 +100,7 @@ namespace endor // Enhanced framebuffer operations void BlitFramebuffer(const v8::FunctionCallbackInfo &args); void RenderbufferStorageMultisample(const v8::FunctionCallbackInfo &args); + void FramebufferTextureLayer(const v8::FunctionCallbackInfo &args); // Enhanced texture operations void TexImage3D(const v8::FunctionCallbackInfo &args); diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index a116ecdd7..ce4c1dfec 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -557,6 +557,52 @@ namespace commandbuffers uint32_t level; }; + class FramebufferTextureLayerCommandBufferRequest final + : public TrCommandBufferSimpleRequest + { + public: + FramebufferTextureLayerCommandBufferRequest() = delete; + FramebufferTextureLayerCommandBufferRequest(uint32_t target, uint32_t attachment, uint32_t texture, uint32_t level, uint32_t layer) + : TrCommandBufferSimpleRequest() + , target(target) + , attachment(attachment) + , texture(texture) + , level(level) + , layer(layer) + { + } + FramebufferTextureLayerCommandBufferRequest(const FramebufferTextureLayerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , attachment(that.attachment) + , texture(that.texture) + , level(that.level) + , layer(that.layer) + { + } + + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << "attachment=" << WebGLHelper::WebGLFramebufferAttachmentToString(attachment) << ", " + << "texture=" << texture << ", " + << "level=" << level << ", " + << "layer=" << layer + << ")"; + return ss.str(); + } + + public: + uint32_t target; + uint32_t attachment; + uint32_t texture; + uint32_t level; + uint32_t layer; + }; + class CheckFramebufferStatusCommandBufferRequest final : public TrCommandBufferSimpleRequest diff --git a/src/common/command_buffers/macros.hpp b/src/common/command_buffers/macros.hpp index 00c9ad7d6..15bad43b4 100644 --- a/src/common/command_buffers/macros.hpp +++ b/src/common/command_buffers/macros.hpp @@ -32,6 +32,7 @@ XX(BIND_FRAMEBUFFER, BindFramebufferCommandBufferRequest, "GL::BindFramebuffer") \ XX(FRAMEBUFFER_RENDERBUFFER, FramebufferRenderbufferCommandBufferRequest, "GL::FramebufferRenderbuffer") \ XX(FRAMEBUFFER_TEXTURE2D, FramebufferTexture2DCommandBufferRequest, "GL::FramebufferTexture2D") \ + XX(FRAMEBUFFER_TEXTURE_LAYER, FramebufferTextureLayerCommandBufferRequest, "GL::FramebufferTextureLayer") \ XX(CHECK_FRAMEBUFFER_STATUS, CheckFramebufferStatusCommandBufferRequest, "GL::CheckFramebufferStatus") \ XX(CREATE_RENDERBUFFER, CreateRenderbufferCommandBufferRequest, "GL::CreateRenderbuffer") \ XX(DELETE_RENDERBUFFER, DeleteRenderbufferCommandBufferRequest, "GL::DeleteRenderbuffer") \ diff --git a/src/common/command_buffers/shared.hpp b/src/common/command_buffers/shared.hpp index edf0e7874..a6a240567 100644 --- a/src/common/command_buffers/shared.hpp +++ b/src/common/command_buffers/shared.hpp @@ -75,6 +75,7 @@ namespace commandbuffers COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ, COMMAND_BUFFER_FRAMEBUFFER_RENDERBUFFER_REQ, COMMAND_BUFFER_FRAMEBUFFER_TEXTURE2D_REQ, + COMMAND_BUFFER_FRAMEBUFFER_TEXTURE_LAYER_REQ, COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_REQ, COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_RES, COMMAND_BUFFER_CREATE_RENDERBUFFER_REQ, diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 37683c8ef..39e5a4e4e 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -1028,6 +1028,23 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } + + TR_OPENGL_FUNC void OnFramebufferTextureLayer(FramebufferTextureLayerCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); + auto target = req->target; + auto attachment = req->attachment; + auto texture = glObjectManager.FindTexture(req->texture); + auto level = req->level; + auto layer = req->layer; + + glFramebufferTextureLayer(target, attachment, texture, level, layer); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + TR_OPENGL_FUNC void OnCheckFramebufferStatus(CheckFramebufferStatusCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -2899,6 +2916,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vector