Skip to content
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6393a21
Initial plan
Copilot Oct 23, 2025
e3bbc26
Remove deprecated concat_idents feature flag
Copilot Oct 23, 2025
82ef186
Implement GLSL attribute parser with FFI bindings
Copilot Oct 23, 2025
a21a221
Add C++ wrapper for GLSL attribute parser FFI
Copilot Oct 23, 2025
304c484
Add comprehensive documentation for GLSL attribute parser
Copilot Oct 23, 2025
d099cea
Fix C++ code formatting with clang-format
Copilot Oct 23, 2025
7293390
Revert accidental formatting change in all_events.cpp
Copilot Oct 23, 2025
1710d2f
update
yorkie Oct 23, 2025
8a6189e
Refactor to use JSON serialization for GLSL attributes FFI
Copilot Oct 23, 2025
2408daa
update
yorkie Oct 23, 2025
5712fc9
Merge branch 'main' of github.com:M-CreativeLab/jsar-runtime into cop…
yorkie Oct 24, 2025
7e3a373
fix
yorkie Oct 24, 2025
1aef9bf
fix
yorkie Oct 24, 2025
a8a3c7b
Filter out inactive/unreferenced attributes from parser results
Copilot Oct 24, 2025
de2c8f7
Add uniform parsing support and rename to GLSLShaderAnalyzer
Copilot Oct 25, 2025
fa70daa
Use GL type enums, add size and active fields
Copilot Oct 25, 2025
9a4ebbb
Add combined Parse() method to parse attributes and uniforms in singl…
Copilot Oct 25, 2025
70ad563
Implement structured uniform support with array and nested struct exp…
Copilot Oct 25, 2025
bb091fc
Add support for gl_InstanceID/gl_VertexID as active attributes
Copilot Oct 25, 2025
0713c17
fix
yorkie Oct 27, 2025
a120c94
Add comprehensive tests for preprocessor and array size handling
Copilot Oct 27, 2025
1c26a6e
Add test for conditional compilation with #ifdef directives
Copilot Oct 27, 2025
5774f55
update
yorkie Oct 27, 2025
617df18
Fix single-element array notation and add variable expansion tracking
Copilot Oct 27, 2025
9ee327a
Fix stack overflow in variable alias tracking
Copilot Oct 27, 2025
5870ccd
update
yorkie Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/jsbindings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ euclid = { workspace = true }
lazy_static = "1.4.0"
log = "0.4.21"
once_cell = "1.17.1"
serde = { workspace = true }
serde_json = { workspace = true }
surfman = "0.9.2"
taffy = { workspace = true, features = ["default"] }
gl = { version = "0.14.0" }
Expand Down
108 changes: 108 additions & 0 deletions crates/jsbindings/bindings.webgl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#include <iostream>
#include <concepts>
#include <vector>
#include <string>
#include <optional>
#include <rapidjson/document.h>
#include "./holocron_webgl.autogen.hpp"

namespace crates::webgl
Expand All @@ -24,4 +28,108 @@ namespace crates::webgl
return std::string(patched);
}
};

/**
* Represents a GLSL vertex attribute.
*/
struct GLSLAttribute
{
std::string name; ///< Attribute name (e.g., "position", "normal")
std::string type_name; ///< Attribute type (e.g., "vec3", "vec4")
int32_t location; ///< Attribute location (0-based index)
};

/**
* GLSLAttributeParser parses vertex shader source code to extract attribute information.
*
* This class provides a convenient C++ interface to parse GLSL vertex shaders and
* extract all attribute declarations, including their names, types, and assigned locations.
*
* Features:
* - Supports both GLSL 100 ES (attribute) and GLSL 300 ES (in) qualifiers
* - Handles explicit layout(location = N) qualifiers
* - Auto-assigns locations based on declaration order when not explicitly specified
* - Compatible with WebGL 1.0 and WebGL 2.0 shaders
*
* Example usage:
* @code
* std::string vertexShader = R"(
* #version 300 es
* in vec3 position;
* in vec3 normal;
* void main() {
* gl_Position = vec4(position, 1.0);
* }
* )";
*
* auto attributes = GLSLAttributeParser::ParseAttributes(vertexShader);
* for (const auto& attr : attributes) {
* std::cout << attr.name << " at location " << attr.location << std::endl;
* }
*
* // Or get a specific attribute location
* auto location = GLSLAttributeParser::GetAttribLocation(vertexShader, "position");
* if (location.has_value()) {
* std::cout << "position is at location " << location.value() << std::endl;
* }
* @endcode
*/
class GLSLAttributeParser
{
public:
/**
* Parse GLSL vertex shader source and extract all attribute declarations.
*
* @param source The GLSL vertex shader source code as a string.
* @returns A vector of GLSLAttribute structs containing attribute metadata.
*/
static inline std::vector<GLSLAttribute> ParseAttributes(const std::string &source)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot A single invocation of parse should produce the parsed attribs and uniforms, rather than calling it twice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added combined Parse() method that parses shader once and returns both attributes and uniforms. Created GLSLShaderVariables struct and parseGLSLShader FFI function. The separate ParseAttributes() and ParseUniforms() methods are now marked as deprecated. (commit 9a4ebbb)

{
auto json_str = holocron::webgl::parseGLSLAttributes(source.c_str());
std::vector<GLSLAttribute> attributes;

rapidjson::Document doc;
doc.Parse(std::string(json_str).c_str());

if (!doc.IsArray())
{
return attributes;
}

attributes.reserve(doc.Size());
for (rapidjson::SizeType i = 0; i < doc.Size(); i++)
{
const auto &attr = doc[i];
if (attr.IsObject() && attr.HasMember("name") && attr.HasMember("type_name") && attr.HasMember("location"))
{
attributes.push_back(GLSLAttribute{
attr["name"].GetString(),
attr["type_name"].GetString(),
attr["location"].GetInt()});
}
}

return attributes;
}

/**
* Get the location of a specific attribute by name.
*
* @param source The GLSL vertex shader source code as a string.
* @param name The name of the attribute to look up.
* @returns An optional containing the attribute location if found, or std::nullopt if not found.
*/
static inline std::optional<int32_t> GetAttribLocation(const std::string &source, const std::string &name)
{
auto attributes = ParseAttributes(source);
for (const auto &attr : attributes)
{
if (attr.name == name)
{
return attr.location;
}
}
return std::nullopt;
}
};
}
1 change: 0 additions & 1 deletion crates/jsbindings/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![allow(unused_variables)]
#![allow(clippy::uninlined_format_args)]
#![allow(deprecated)]
#![feature(concat_idents)]

extern crate ctor;
extern crate jsar_jsbinding_macro;
Expand Down
Loading