diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 9e60d485b..6f7f9f71d 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -816,6 +816,62 @@ namespace endor sendCommandBufferRequest(req); } + void WebGLContext::vertexAttrib1fv(const WebGLAttribLocation &index, const vector values) + { + auto req = VertexAttrib1fvCommandBufferRequest(index.programId, index.name, values); + if (index.index.has_value()) + req.setLoc(index.index.value()); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib1fv(int index, const vector values) + { + auto req = VertexAttrib1fvCommandBufferRequest(0, index, values); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib2fv(const WebGLAttribLocation &index, const vector values) + { + auto req = VertexAttrib2fvCommandBufferRequest(index.programId, index.name, values); + if (index.index.has_value()) + req.setLoc(index.index.value()); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib2fv(int index, const vector values) + { + auto req = VertexAttrib2fvCommandBufferRequest(0, index, values); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib3fv(const WebGLAttribLocation &index, const vector values) + { + auto req = VertexAttrib3fvCommandBufferRequest(index.programId, index.name, values); + if (index.index.has_value()) + req.setLoc(index.index.value()); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib3fv(int index, const vector values) + { + auto req = VertexAttrib3fvCommandBufferRequest(0, index, values); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib4fv(const WebGLAttribLocation &index, const vector values) + { + auto req = VertexAttrib4fvCommandBufferRequest(index.programId, index.name, values); + if (index.index.has_value()) + req.setLoc(index.index.value()); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttrib4fv(int index, const vector values) + { + auto req = VertexAttrib4fvCommandBufferRequest(0, index, values); + sendCommandBufferRequest(req); + } + optional WebGLContext::getActiveAttrib(shared_ptr program, unsigned int index) { assert(program != nullptr && "Program is not null"); diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index 32567de43..3dddfe18f 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -392,6 +392,14 @@ namespace endor void vertexAttrib3f(int index, float v0, float v1, float v2); void vertexAttrib4f(const WebGLAttribLocation &, float v0, float v1, float v2, float v3); void vertexAttrib4f(int index, float v0, float v1, float v2, float v3); + void vertexAttrib1fv(const WebGLAttribLocation &, const std::vector values); + void vertexAttrib1fv(int index, const std::vector values); + void vertexAttrib2fv(const WebGLAttribLocation &, const std::vector values); + void vertexAttrib2fv(int index, const std::vector values); + void vertexAttrib3fv(const WebGLAttribLocation &, const std::vector values); + void vertexAttrib3fv(int index, const std::vector values); + void vertexAttrib4fv(const WebGLAttribLocation &, const std::vector values); + void vertexAttrib4fv(int index, const std::vector values); std::optional getActiveAttrib(std::shared_ptr program, unsigned int index); std::optional getActiveUniform(std::shared_ptr program, unsigned int index); std::optional getAttribLocation(std::shared_ptr program, const std::string &name); diff --git a/src/client/script_bindings/webgl/webgl_rendering_context.cpp b/src/client/script_bindings/webgl/webgl_rendering_context.cpp index 7c9351388..1b0eac4bf 100644 --- a/src/client/script_bindings/webgl/webgl_rendering_context.cpp +++ b/src/client/script_bindings/webgl/webgl_rendering_context.cpp @@ -456,6 +456,10 @@ namespace endor ADD_WEBGL1_METHOD("vertexAttrib2f", VertexAttrib2f) ADD_WEBGL1_METHOD("vertexAttrib3f", VertexAttrib3f) ADD_WEBGL1_METHOD("vertexAttrib4f", VertexAttrib4f) + ADD_WEBGL1_METHOD("vertexAttrib1fv", VertexAttrib1fv) + ADD_WEBGL1_METHOD("vertexAttrib2fv", VertexAttrib2fv) + ADD_WEBGL1_METHOD("vertexAttrib3fv", VertexAttrib3fv) + ADD_WEBGL1_METHOD("vertexAttrib4fv", VertexAttrib4fv) ADD_WEBGL1_METHOD("getActiveAttrib", GetActiveAttrib) ADD_WEBGL1_METHOD("getActiveUniform", GetActiveUniform) ADD_WEBGL1_METHOD("getAttribLocation", GetAttribLocation) @@ -4171,6 +4175,138 @@ namespace endor info.GetReturnValue().SetUndefined(); } + void WebGLRenderingContext::VertexAttrib1fv(const FunctionCallbackInfo &info) + { + Isolate *isolate = info.GetIsolate(); + HandleScope scope(isolate); + + if (info.Length() < 2) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib1fv", "2 arguments required, but fewer were provided"))); + return; + } + if (!info[0]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib1fv", "First argument must be a number"))); + return; + } + + Local context = isolate->GetCurrentContext(); + int index = info[0]->Int32Value(context).FromMaybe(0); + + std::vector values = GetFloatValuesFromValue(isolate, info[1]); + if (values.size() < 1) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib1fv", "Expected at least 1 component in the array"))); + return; + } + + handle()->vertexAttrib1fv(index, values); + info.GetReturnValue().SetUndefined(); + } + + void WebGLRenderingContext::VertexAttrib2fv(const FunctionCallbackInfo &info) + { + Isolate *isolate = info.GetIsolate(); + HandleScope scope(isolate); + + if (info.Length() < 2) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib2fv", "2 arguments required, but fewer were provided"))); + return; + } + if (!info[0]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib2fv", "First argument must be a number"))); + return; + } + + Local context = isolate->GetCurrentContext(); + int index = info[0]->Int32Value(context).FromMaybe(0); + + std::vector values = GetFloatValuesFromValue(isolate, info[1]); + if (values.size() < 2) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib2fv", "Expected at least 2 components in the array"))); + return; + } + + handle()->vertexAttrib2fv(index, values); + info.GetReturnValue().SetUndefined(); + } + + void WebGLRenderingContext::VertexAttrib3fv(const FunctionCallbackInfo &info) + { + Isolate *isolate = info.GetIsolate(); + HandleScope scope(isolate); + + if (info.Length() < 2) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib3fv", "2 arguments required, but fewer were provided"))); + return; + } + if (!info[0]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib3fv", "First argument must be a number"))); + return; + } + + Local context = isolate->GetCurrentContext(); + int index = info[0]->Int32Value(context).FromMaybe(0); + + std::vector values = GetFloatValuesFromValue(isolate, info[1]); + if (values.size() < 3) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib3fv", "Expected at least 3 components in the array"))); + return; + } + + handle()->vertexAttrib3fv(index, values); + info.GetReturnValue().SetUndefined(); + } + + void WebGLRenderingContext::VertexAttrib4fv(const FunctionCallbackInfo &info) + { + Isolate *isolate = info.GetIsolate(); + HandleScope scope(isolate); + + if (info.Length() < 2) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib4fv", "2 arguments required, but fewer were provided"))); + return; + } + if (!info[0]->IsNumber()) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib4fv", "First argument must be a number"))); + return; + } + + Local context = isolate->GetCurrentContext(); + int index = info[0]->Int32Value(context).FromMaybe(0); + + std::vector values = GetFloatValuesFromValue(isolate, info[1]); + if (values.size() < 4) + { + isolate->ThrowException(Exception::TypeError( + MakeMethodError(isolate, "vertexAttrib4fv", "Expected at least 4 components in the array"))); + return; + } + + handle()->vertexAttrib4fv(index, values); + info.GetReturnValue().SetUndefined(); + } + void WebGLRenderingContext::VertexAttribPointer(const FunctionCallbackInfo &info) { Isolate *isolate = info.GetIsolate(); diff --git a/src/client/script_bindings/webgl/webgl_rendering_context.hpp b/src/client/script_bindings/webgl/webgl_rendering_context.hpp index ba0b2553c..380601a45 100644 --- a/src/client/script_bindings/webgl/webgl_rendering_context.hpp +++ b/src/client/script_bindings/webgl/webgl_rendering_context.hpp @@ -164,6 +164,10 @@ namespace endor void VertexAttrib2f(const v8::FunctionCallbackInfo &info); void VertexAttrib3f(const v8::FunctionCallbackInfo &info); void VertexAttrib4f(const v8::FunctionCallbackInfo &info); + void VertexAttrib1fv(const v8::FunctionCallbackInfo &info); + void VertexAttrib2fv(const v8::FunctionCallbackInfo &info); + void VertexAttrib3fv(const v8::FunctionCallbackInfo &info); + void VertexAttrib4fv(const v8::FunctionCallbackInfo &info); void VertexAttribPointer(const v8::FunctionCallbackInfo &info); // Viewport & scissor diff --git a/src/common/command_buffers/details/vertex_attrib.hpp b/src/common/command_buffers/details/vertex_attrib.hpp index c54ddf3c5..d0cd1d11a 100644 --- a/src/common/command_buffers/details/vertex_attrib.hpp +++ b/src/common/command_buffers/details/vertex_attrib.hpp @@ -394,6 +394,82 @@ namespace commandbuffers float v0, v1, v2, v3; }; + // Base class for vector float vertex attribute requests + template + class VertexAttribNfvCommandBufferRequest : public SetVertexAttribCommandBufferRequest + { + public: + VertexAttribNfvCommandBufferRequest() = delete; + VertexAttribNfvCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetVertexAttribCommandBufferRequest(program, location_name) + , values(values) + { + } + VertexAttribNfvCommandBufferRequest(uint32_t program, uint32_t index, const std::vector &values) + : SetVertexAttribCommandBufferRequest(program, index) + , values(values) + { + } + VertexAttribNfvCommandBufferRequest(const Derived &that, bool clone = false) + : SetVertexAttribCommandBufferRequest(that, clone) + , values(that.values) + { + } + + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << SetVertexAttribCommandBufferRequest::toString(line_prefix) << "(["; + for (size_t i = 0; i < values.size(); ++i) + { + if (i > 0) + ss << ", "; + ss << values[i]; + } + ss << "])"; + return ss.str(); + } + + public: + std::vector values; + }; + + // VertexAttrib1fv command buffer request + class VertexAttrib1fvCommandBufferRequest final + : public VertexAttribNfvCommandBufferRequest + { + public: + using VertexAttribNfvCommandBufferRequest::VertexAttribNfvCommandBufferRequest; + }; + + // VertexAttrib2fv command buffer request + class VertexAttrib2fvCommandBufferRequest final + : public VertexAttribNfvCommandBufferRequest + { + public: + using VertexAttribNfvCommandBufferRequest::VertexAttribNfvCommandBufferRequest; + }; + + // VertexAttrib3fv command buffer request + class VertexAttrib3fvCommandBufferRequest final + : public VertexAttribNfvCommandBufferRequest + { + public: + using VertexAttribNfvCommandBufferRequest::VertexAttribNfvCommandBufferRequest; + }; + + // VertexAttrib4fv command buffer request + class VertexAttrib4fvCommandBufferRequest final + : public VertexAttribNfvCommandBufferRequest + { + public: + using VertexAttribNfvCommandBufferRequest::VertexAttribNfvCommandBufferRequest; + }; + class VertexAttribIPointerCommandBufferRequest final : public SetVertexAttribCommandBufferRequest diff --git a/src/common/command_buffers/macros.hpp b/src/common/command_buffers/macros.hpp index 00c9ad7d6..720996e27 100644 --- a/src/common/command_buffers/macros.hpp +++ b/src/common/command_buffers/macros.hpp @@ -68,6 +68,10 @@ XX(VERTEX_ATTRIB_2F, VertexAttrib2fCommandBufferRequest, "GL::VertexAttrib2f") \ XX(VERTEX_ATTRIB_3F, VertexAttrib3fCommandBufferRequest, "GL::VertexAttrib3f") \ XX(VERTEX_ATTRIB_4F, VertexAttrib4fCommandBufferRequest, "GL::VertexAttrib4f") \ + XX(VERTEX_ATTRIB_1FV, VertexAttrib1fvCommandBufferRequest, "GL::VertexAttrib1fv") \ + XX(VERTEX_ATTRIB_2FV, VertexAttrib2fvCommandBufferRequest, "GL::VertexAttrib2fv") \ + XX(VERTEX_ATTRIB_3FV, VertexAttrib3fvCommandBufferRequest, "GL::VertexAttrib3fv") \ + XX(VERTEX_ATTRIB_4FV, VertexAttrib4fvCommandBufferRequest, "GL::VertexAttrib4fv") \ XX(VERTEX_ATTRIB_IPOINTER, VertexAttribIPointerCommandBufferRequest, "GL::VertexAttribIPointer") \ XX(VERTEX_ATTRIB_DIVISOR, VertexAttribDivisorCommandBufferRequest, "GL::VertexAttribDivisor") \ XX(VERTEX_ATTRIB_I4I, VertexAttribI4iCommandBufferRequest, "GL::VertexAttribI4i") \ diff --git a/src/common/command_buffers/shared.hpp b/src/common/command_buffers/shared.hpp index edf0e7874..cf2250298 100644 --- a/src/common/command_buffers/shared.hpp +++ b/src/common/command_buffers/shared.hpp @@ -102,6 +102,10 @@ namespace commandbuffers COMMAND_BUFFER_VERTEX_ATTRIB_2F_REQ, COMMAND_BUFFER_VERTEX_ATTRIB_3F_REQ, COMMAND_BUFFER_VERTEX_ATTRIB_4F_REQ, + COMMAND_BUFFER_VERTEX_ATTRIB_1FV_REQ, + COMMAND_BUFFER_VERTEX_ATTRIB_2FV_REQ, + COMMAND_BUFFER_VERTEX_ATTRIB_3FV_REQ, + COMMAND_BUFFER_VERTEX_ATTRIB_4FV_REQ, COMMAND_BUFFER_VERTEX_ATTRIB_IPOINTER_REQ, COMMAND_BUFFER_VERTEX_ATTRIB_DIVISOR_REQ, COMMAND_BUFFER_VERTEX_ATTRIB_I4I_REQ, diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 37683c8ef..dc659b97f 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -1704,6 +1704,83 @@ 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 OnVertexAttrib1fv(VertexAttrib1fvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttrib1fv(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glVertexAttrib1fv(loc.value(), req->values.data()); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + + TR_OPENGL_FUNC void OnVertexAttrib2fv(VertexAttrib2fvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttrib2fv(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glVertexAttrib2fv(loc.value(), req->values.data()); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + + TR_OPENGL_FUNC void OnVertexAttrib3fv(VertexAttrib3fvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttrib3fv(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glVertexAttrib3fv(loc.value(), req->values.data()); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + + TR_OPENGL_FUNC void OnVertexAttrib4fv(VertexAttrib4fvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttrib4fv(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glVertexAttrib4fv(loc.value(), req->values.data()); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + TR_OPENGL_FUNC void OnUniformBlockBinding(UniformBlockBindingCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -2930,6 +3007,14 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vector