diff --git a/examples/PerlinNoise.cgl b/examples/PerlinNoise.cgl new file mode 100644 index 00000000..385c454b --- /dev/null +++ b/examples/PerlinNoise.cgl @@ -0,0 +1,29 @@ +shader PerlinNoise { + vertex { + input vec3 position; + output vec2 vUV; + + void main() { + vUV = position.xy * 10.0; + gl_Position = vec4(position, 1.0); + } + } + + // Perlin Noise Function + float perlinNoise(vec2 p) { + return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); + } + + // Fragment Shader + fragment { + input vec2 vUV; + output vec4 fragColor; + + void main() { + float noise = perlinNoise(vUV); + float height = noise * 10.0; + vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0); + fragColor = vec4(color, 1.0); + } + } +} diff --git a/examples/PerlinNoise.glsl b/examples/PerlinNoise.glsl new file mode 100644 index 00000000..98d3e138 --- /dev/null +++ b/examples/PerlinNoise.glsl @@ -0,0 +1,28 @@ +#version 450 core + +//vertex shader +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 texCoord; + +out vec2 vTexCoord; + +void main() +{ + vTexCoord = texCoord; + gl_Position = vec4(position, 1.0); +} + +in vec2 vTexCoord; +out vec4 fragColor; + +// fragment shader + +float marblePattern(vec2 uv) { + return 0.5 + 0.5 * sin(10.0 * uv.x + iTime); +} + +void main() +{ + vec3 color = vec3(marblePattern(vTexCoord), 0.0, 0.0); + fragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/examples/PerlinNoise.hlsl b/examples/PerlinNoise.hlsl new file mode 100644 index 00000000..81343f44 --- /dev/null +++ b/examples/PerlinNoise.hlsl @@ -0,0 +1,38 @@ +float perlinNoise(float2 p) { + return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453)); +} + +struct Vertex_INPUT { + float3 position : POSITION; +}; + +struct Vertex_OUTPUT { + float4 position : SV_POSITION; + float2 vUV : TEXCOORD0; +}; + +Vertex_OUTPUT VSMain(Vertex_INPUT input) { + Vertex_OUTPUT output; + output.vUV = (input.position.xy * 10.0); + output.position = float4(input.position, 1.0); + return output; +} + +struct Fragment_INPUT { + float2 vUV : TEXCOORD0; +}; + +struct Fragment_OUTPUT { + float4 fragColor : SV_TARGET0; +}; + +Fragment_OUTPUT PSMain(Fragment_INPUT input) { + Fragment_OUTPUT output; + float noise = perlinNoise(input.vUV); + float height = (noise * 10.0); + float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0); + output.fragColor = float4(color, 1.0); + return output; +} + + \ No newline at end of file diff --git a/examples/PerlinNoise.metal b/examples/PerlinNoise.metal new file mode 100644 index 00000000..1cf9e337 --- /dev/null +++ b/examples/PerlinNoise.metal @@ -0,0 +1,39 @@ +#include +using namespace metal; + +float perlinNoise(float2 p) { + return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453)); +} + +struct Vertex_INPUT { + float3 position [[attribute(0)]]; +}; + +struct Vertex_OUTPUT { + float4 position [[position]]; + float2 vUV; +}; + +vertex Vertex_OUTPUT vertex_main(Vertex_INPUT input [[stage_in]]) { + Vertex_OUTPUT output; + output.vUV = (input.position.xy * 10.0); + output.position = float4(input.position, 1.0); + return output; +} + +struct Fragment_INPUT { + float2 vUV [[stage_in]]; +}; + +struct Fragment_OUTPUT { + float4 fragColor [[color(0)]]; +}; + +fragment Fragment_OUTPUT fragment_main(Fragment_INPUT input [[stage_in]]) { + Fragment_OUTPUT output; + float noise = perlinNoise(input.vUV); + float height = (noise * 10.0); + float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0); + output.fragColor = float4(color, 1.0); + return output; +} diff --git a/examples/example_program.cgl b/examples/example_program.cgl deleted file mode 100644 index 3fa42914..00000000 --- a/examples/example_program.cgl +++ /dev/null @@ -1,8 +0,0 @@ -shader main { - input vec3 position; - output vec4 color; - - void main() { - color = vec4(position, 1.0); - } -} diff --git a/getting_start.ipynb b/getting_start.ipynb new file mode 100644 index 00000000..2c2f5e78 --- /dev/null +++ b/getting_start.ipynb @@ -0,0 +1,811 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CrossGL: Revolutionizing Shader Development\n", + "\n", + "## 🌟 The Universal Shader Language\n", + "\n", + "In the ever-evolving world of graphics programming, **CrossGL** emerges as a game-changing solution, bridging the gap between diverse graphics APIs.\n", + "\n", + "### 🚀 Write Once, Run Everywhere\n", + "\n", + "Imagine writing a shader _once_ and deploying it across:\n", + "\n", + "- 🍎 Metal\n", + "- 🎮 DirectX\n", + "- 🖥️ OpenGL\n", + "\n", + "...all without changing a single line of code!\n", + "\n", + "## 💡 Key Benefits\n", + "\n", + "1. **⏱️ Time-Saving**: Slash development time by eliminating the need for multiple shader versions.\n", + "2. **🛠️ Consistency**: Ensure uniform behavior across all platforms.\n", + "3. **🧠 Simplified Learning Curve**: Master one language instead of many.\n", + "4. **🔍 Enhanced Debugging**: Develop universal tools for shader analysis.\n", + "5. **🔮 Future-Proof**: Easily adapt to new graphics APIs as they emerge.\n", + "\n", + "\n", + "📚 **Documentation**\n", + "Comprehensive documentation is available to help you get started and master CrossGL:\n", + "\n", + "🔗 [CrossGL Documentation](https://crossgl.github.io/language.html)\n", + "📘 [Contribution Guidelines](https://crossgl.github.io/contribution.html)\n", + "\n", + "\n", + "🤝 **Community & Social Media**\n", + "Join our vibrant community of developers and graphics enthusiasts:\n", + "\n", + "💬 [Discord Channel](https://discord.gg/mYH45zZ9)\n", + "- Get real-time support\n", + "- Share your projects\n", + "- Collaborate with other CrossGL users\n", + "\n", + "🐙 [GitHub](https://github.com/CrossGL)\n", + "- Access the source code\n", + "- Report issues\n", + "- Contribute to the project\n", + "\n", + "🐦 [X](https://x.com/crossGL_)\n", + "- Stay updated with the latest news\n", + "- Join discussions about graphics programming\n", + "\n", + "\n", + "👥 [LinkedIn](https://www.linkedin.com/company/crossgl/?viewAsMember=true)\n", + "- Connect with the CrossGL team\n", + "- Explore career opportunities\n", + "- Network with industry professionals\n", + "\n", + "\n", + "## 🌈 CrossGL Shader \n", + "\n", + "```cpp\n", + "shader main {\n", + "\n", + "vertex {\n", + "\n", + "input vec3 position;\n", + "output vec2 vUV;\n", + "\n", + "void main()\n", + "{\n", + " vUV = position.xy * 10.0;\n", + " gl_Position = vec4(position, 1.0);\n", + "}\n", + "\n", + "}\n", + "\n", + "float perlinNoise(vec2 p) {\n", + " return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);\n", + "}\n", + "\n", + "fragment {\n", + "\n", + "input vec2 vUV;\n", + "output vec4 fragColor;\n", + "\n", + "\n", + "void main()\n", + "{\n", + " float noise = perlinNoise(vUV);\n", + " float height = noise * 10.0;\n", + " vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0);\n", + " fragColor = vec4(color, 1.0);\n", + "}\n", + "\n", + "\n", + "}\n", + "\n", + "}\n", + "```\n", + "\n", + "## 🤝 Unifying the Developer Community\n", + "\n", + "CrossGL isn't just a language; it's a bridge connecting developers across different platforms, fostering collaboration and innovation.\n", + "\n", + "### 📈 The CrossGL Advantage\n", + "\n", + "| Feature | Without CrossGL | With CrossGL |\n", + "|---------|-----------------|--------------|\n", + "| Platforms Supported | Single | Multiple |\n", + "| Code Reusability | Low | High |\n", + "| Learning Curve | Steep | Gentle |\n", + "| Time to Market | Slower | Faster |\n", + "\n", + "## 🎨 Unleash Your Creativity\n", + "\n", + "With CrossGL, you're no longer bound by platform limitations. Your imagination is the only limit!\n", + "\n", + "> \"CrossGL is not just a tool; it's a canvas for your graphics ambitions.\" - Graphics Guru\n", + "\n", + "---\n", + "\n", + "Are you ready to transform your shader development workflow? Dive into CrossGL and experience the future of graphics programming today! 🚀✨\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CrossGL Translator: A Step-by-Step Journey\n", + "\n", + "## 🚀 Embark on a Cross-Platform Shader Adventure\n", + "\n", + "Let's walk through the magic of CrossGL translation, step by step!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 1: The CrossGL Source 📝\n", + "\n", + "We begin with a CrossGL shader that generates Perlin noise for terrain:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "shader PerlinNoise {\n", + " vertex {\n", + " input vec3 position;\n", + " output vec2 vUV;\n", + "\n", + " void main() {\n", + " vUV = position.xy * 10.0;\n", + " gl_Position = vec4(position, 1.0);\n", + " }\n", + " }\n", + "\n", + " // Perlin Noise Function\n", + " float perlinNoise(vec2 p) {\n", + " return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);\n", + " }\n", + "\n", + " // Fragment Shader\n", + " fragment {\n", + " input vec2 vUV;\n", + " output vec4 fragColor;\n", + "\n", + " void main() {\n", + " float noise = perlinNoise(vUV);\n", + " float height = noise * 10.0;\n", + " vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0);\n", + " fragColor = vec4(color, 1.0);\n", + " }\n", + " }\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "with open(\"examples/PerlinNoise.cgl\",'r') as f:\n", + " cgl_code = f.read()\n", + "print(cgl_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 2: Parsing the Code 🧩\n", + "\n", + "Our lexer and parser spring into action:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Parsing complete. AST created.\n" + ] + } + ], + "source": [ + "from src.translator.lexer import Lexer\n", + "from src.translator.parser import Parser\n", + "from src.translator.codegen import directx_codegen, metal_codegen, opengl_codegen\n", + "from src.translator.ast import ASTNode\n", + "lexer = Lexer(cgl_code)\n", + "parser = Parser(lexer.tokens)\n", + "ast = parser.parse()\n", + "\n", + "print(\"Parsing complete. AST created.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 3: The Translation Magic ✨\n", + "\n", + "Now, we unleash our code generators:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.1 Metal Transformation 🍎" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#include \n", + "using namespace metal;\n", + "\n", + "float perlinNoise(float2 p) {\n", + " return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453));\n", + "}\n", + "\n", + "struct Vertex_INPUT {\n", + " float3 position [[attribute(0)]];\n", + "};\n", + "\n", + "struct Vertex_OUTPUT {\n", + " float4 position [[position]];\n", + " float2 vUV;\n", + "};\n", + "\n", + "vertex Vertex_OUTPUT vertex_main(Vertex_INPUT input [[stage_in]]) {\n", + " Vertex_OUTPUT output;\n", + " output.vUV = (input.position.xy * 10.0);\n", + " output.position = float4(input.position, 1.0);\n", + " return output;\n", + "}\n", + "\n", + "struct Fragment_INPUT {\n", + " float2 vUV [[stage_in]];\n", + "};\n", + "\n", + "struct Fragment_OUTPUT {\n", + " float4 fragColor [[color(0)]];\n", + "};\n", + "\n", + "fragment Fragment_OUTPUT fragment_main(Fragment_INPUT input [[stage_in]]) {\n", + " Fragment_OUTPUT output;\n", + " float noise = perlinNoise(input.vUV);\n", + " float height = (noise * 10.0);\n", + " float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0);\n", + " output.fragColor = float4(color, 1.0);\n", + " return output;\n", + "}\n", + "\n", + "\n" + ] + } + ], + "source": [ + "metal_codegen = metal_codegen.MetalCodeGen()\n", + "metal_code = metal_codegen.generate(ast)\n", + "print(metal_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.2 DirectX (HLSL) Transformation 🎮" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "float perlinNoise(float2 p) {\n", + " return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453));\n", + "}\n", + "\n", + "struct Vertex_INPUT {\n", + " float3 position : POSITION;\n", + "};\n", + "\n", + "struct Vertex_OUTPUT {\n", + " float4 position : SV_POSITION;\n", + " float2 vUV : TEXCOORD0;\n", + "};\n", + "\n", + "Vertex_OUTPUT main(Vertex_INPUT input) {\n", + " Vertex_OUTPUT output;\n", + " output.vUV = (input.position.xy * 10.0);\n", + " output.position = float4(input.position, 1.0);\n", + " return output;\n", + "}\n", + "\n", + "struct Fragment_INPUT {\n", + " float2 vUV : TEXCOORD0;\n", + "};\n", + "\n", + "struct Fragment_OUTPUT {\n", + " float4 fragColor : SV_TARGET0;\n", + "};\n", + "\n", + "Fragment_OUTPUT main(Fragment_INPUT input) {\n", + " Fragment_OUTPUT output;\n", + " float noise = perlinNoise(input.vUV);\n", + " float height = (noise * 10.0);\n", + " float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0);\n", + " output.fragColor = float4(color, 1.0);\n", + " return output;\n", + "}\n", + "\n", + "\n" + ] + } + ], + "source": [ + "hlsl_codegen = directx_codegen.HLSLCodeGen()\n", + "hlsl_code = hlsl_codegen.generate(ast)\n", + "print(hlsl_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.3 OpenGL (GLSL) Transformation 🖥️" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#version 450\n", + "\n", + "\n", + "float perlinNoise(vec2 p) {\n", + " return fract((sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453));\n", + "}\n", + "\n", + "// Vertex shader\n", + "\n", + "layout(location = 0) in vec3 position;\n", + "out vec2 vUV;\n", + "\n", + "void main() {\n", + " vUV = (position.xy * 10.0);\n", + " gl_Position = vec4(position, 1.0);\n", + "}\n", + "\n", + "// Fragment shader\n", + "\n", + "in vec2 vUV;\n", + "layout(location = 0) out vec4 fragColor;\n", + "\n", + "void main() {\n", + " float noise = perlinNoise(vUV);\n", + " float height = (noise * 10.0);\n", + " vec3 color = vec3((height / 10.0), (1.0 - (height / 10.0)), 0.0);\n", + " fragColor = vec4(color, 1.0);\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "glsl_codegen = opengl_codegen.GLSLCodeGen()\n", + "glsl_code = glsl_codegen.generate(ast)\n", + "print(glsl_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 4: Marvel at the Results 🎉\n", + "\n", + "From a single CrossGL source, we've generated shaders for three major graphics APIs!\n", + "\n", + "## 🌟 The Power of CrossGL\n", + "\n", + "This demo showcases the true potential of CrossGL:\n", + "- **One Source, Multiple Targets**: Write once, run everywhere.\n", + "- **Seamless Translation**: Automatic adaptation to platform-specific syntax and features.\n", + "- **Consistency Across Platforms**: Ensure your shaders behave identically on all supported backends.\n", + "\n", + "By leveraging CrossGL, developers can focus on crafting amazing shaders without worrying about platform-specific intricacies. It's not just a translator; it's a bridge to unlimited creative possibilities in the world of graphics programming! 🚀🎨" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## 🔄 Two-Way Translation: From Platform-Specific to CrossGL\n", + "\n", + "CrossGL doesn't just translate from a universal language to platform-specific shaders - it also works in reverse! This powerful feature allows developers to convert existing shaders from various platforms into CrossGL.\n", + "\n", + "### Step 5: Reverse Translation 🔀\n", + "\n", + "Let's explore how we can convert shaders from Metal, DirectX, and OpenGL back into CrossGL.\n", + "\n", + "#### 5.1 OpenGL (GLSL) to CrossGL 🖥️➡️🌐" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#version 450 core\n", + "\n", + "//vertex shader\n", + "layout(location = 0) in vec3 position;\n", + "layout(location = 1) in vec2 texCoord;\n", + "\n", + "out vec2 vTexCoord;\n", + "\n", + "void main()\n", + "{\n", + " vTexCoord = texCoord;\n", + " gl_Position = vec4(position, 1.0);\n", + "}\n", + "\n", + "in vec2 vTexCoord;\n", + "out vec4 fragColor;\n", + "\n", + "// fragment shader \n", + "\n", + "float marblePattern(vec2 uv) {\n", + " return 0.5 + 0.5 * sin(10.0 * uv.x + iTime);\n", + "}\n", + "\n", + "void main()\n", + "{\n", + " vec3 color = vec3(marblePattern(vTexCoord), 0.0, 0.0);\n", + " fragColor = vec4(color, 1.0);\n", + "}\n" + ] + } + ], + "source": [ + "with open(\"examples/PerlinNoise.glsl\",'r') as f:\n", + " glsl_code = f.read()\n", + "print(glsl_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.2 DirectX (HLSL) to CrossGL 🎮➡️🌐" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "float perlinNoise(float2 p) {\n", + " return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453));\n", + "}\n", + "\n", + "struct Vertex_INPUT {\n", + " float3 position : POSITION;\n", + "};\n", + "\n", + "struct Vertex_OUTPUT {\n", + " float4 position : SV_POSITION;\n", + " float2 vUV : TEXCOORD0;\n", + "};\n", + "\n", + "Vertex_OUTPUT VSMain(Vertex_INPUT input) {\n", + " Vertex_OUTPUT output;\n", + " output.vUV = (input.position.xy * 10.0);\n", + " output.position = float4(input.position, 1.0);\n", + " return output;\n", + "}\n", + "\n", + "struct Fragment_INPUT {\n", + " float2 vUV : TEXCOORD0;\n", + "};\n", + "\n", + "struct Fragment_OUTPUT {\n", + " float4 fragColor : SV_TARGET0;\n", + "};\n", + "\n", + "Fragment_OUTPUT PSMain(Fragment_INPUT input) {\n", + " Fragment_OUTPUT output;\n", + " float noise = perlinNoise(input.vUV);\n", + " float height = (noise * 10.0);\n", + " float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0);\n", + " output.fragColor = float4(color, 1.0);\n", + " return output;\n", + "}\n", + "\n", + " \n" + ] + } + ], + "source": [ + "with open(\"examples/PerlinNoise.hlsl\",'r') as f:\n", + " hlsl_code = f.read()\n", + "print(hlsl_code)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from src.backend.DirectX import *" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "lexer = HLSLLexer(hlsl_code)\n", + "parser = HLSLParser(lexer.tokens)\n", + "ast = parser.parse()\n", + "codegen_engin = HLSLToCrossGLConverter()\n", + "cross = codegen_engin.convert(ast)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "shader main {\n", + " // Vertex Shader\n", + " vertex {\n", + "\n", + " void main() {\n", + " vUV = (position.xy * 10.0);\n", + " gl_Position = vec4(position, 1.0);\n", + " }\n", + " }\n", + "\n", + " float perlinNoise(vec2 p) {\n", + " return fract((sin(dot( p, vec2(12.9898, 78.233))) * 43758.5453));\n", + " }\n", + "\n", + " // Fragment Shader\n", + " fragment {\n", + "\n", + " void main() {\n", + " float noise = perlinNoise(vUV);\n", + " float height = ( noise * 10.0);\n", + " float3 color = vec3(( height / 10.0), (1.0 - ( height / 10.0)), 0.0);\n", + " fragColor = vec4( color, 1.0);\n", + " }\n", + " }\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "print(crossgl_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5.3 Metal to CrossGL 🍎➡️🌐" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#include \n", + "using namespace metal;\n", + "\n", + "float perlinNoise(float2 p) {\n", + " return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453));\n", + "}\n", + "\n", + "struct Vertex_INPUT {\n", + " float3 position [[attribute(0)]];\n", + "};\n", + "\n", + "struct Vertex_OUTPUT {\n", + " float4 position [[position]];\n", + " float2 vUV;\n", + "};\n", + "\n", + "vertex Vertex_OUTPUT vertex_main(Vertex_INPUT input [[stage_in]]) {\n", + " Vertex_OUTPUT output;\n", + " output.vUV = (input.position.xy * 10.0);\n", + " output.position = float4(input.position, 1.0);\n", + " return output;\n", + "}\n", + "\n", + "struct Fragment_INPUT {\n", + " float2 vUV [[stage_in]];\n", + "};\n", + "\n", + "struct Fragment_OUTPUT {\n", + " float4 fragColor [[color(0)]];\n", + "};\n", + "\n", + "fragment Fragment_OUTPUT fragment_main(Fragment_INPUT input [[stage_in]]) {\n", + " Fragment_OUTPUT output;\n", + " float noise = perlinNoise(input.vUV);\n", + " float height = (noise * 10.0);\n", + " float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0);\n", + " output.fragColor = float4(color, 1.0);\n", + " return output;\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "with open(\"examples/PerlinNoise.metal\",'r') as f:\n", + " metal_code = f.read()\n", + "print(metal_code)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "from src.backend.Metal import *" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "lexer = MetalLexer(metal_code)\n", + "parser = MetalParser(lexer.tokens)\n", + "ast = parser.parse()\n", + "codegen_engin = MetalCrossGLCodeGen.MetalToCrossGLConverter()\n", + "crossgl_code = codegen_engin.generate(ast)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "shader main {\n", + " // Vertex Shader\n", + " vertex {\n", + "\n", + " void main() {\n", + " vUV = (position.xy * 10.0);\n", + " gl_Position = vec4(position, 1.0);\n", + " }\n", + " }\n", + "\n", + " float perlinNoise(vec2 p) {\n", + " return fract((sin(dot( p, vec2(12.9898, 78.233))) * 43758.5453));\n", + " }\n", + "\n", + " // Fragment Shader\n", + " fragment {\n", + "\n", + " void main() {\n", + " float noise = perlinNoise(vUV);\n", + " float height = ( noise * 10.0);\n", + " float3 color = vec3(( height / 10.0), (1.0 - ( height / 10.0)), 0.0);\n", + " fragColor = vec4( color, 1.0);\n", + " }\n", + " }\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "print(crossgl_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Power of Two-Way Translation 💪\n", + "\n", + "This bidirectional translation capability offers several key advantages:\n", + "\n", + "1. **Legacy Code Integration**: Easily incorporate existing shaders from various platforms into your CrossGL workflow.\n", + "2. **Migration Assistance**: Smoothly transition projects from platform-specific implementations to the universal CrossGL standard.\n", + "3. **Learning Tool**: Use the translator to understand how platform-specific constructs map to CrossGL, aiding in the learning process.\n", + "\n", + "By providing this two-way translation, CrossGL establishes itself as a comprehensive solution for cross-platform shader development, bridging the gap between different graphics APIs and simplifying the shader writing process.\n", + "\n", + "## 🎉 Conclusion: The Full Circle of Shader Development\n", + "\n", + "We've now seen the complete cycle of CrossGL's capabilities:\n", + "1. Writing shaders in the universal CrossGL language\n", + "2. Translating CrossGL to platform-specific shaders (Metal, DirectX, OpenGL)\n", + "3. Converting existing platform-specific shaders back to CrossGL\n", + "\n", + "This full-circle approach empowers developers to work seamlessly across different graphics APIs, promoting code reuse, simplifying multi-platform development, and accelerating the shader creation process.\n", + "\n", + "With CrossGL, the future of graphics programming is not just cross-platform - it's boundaryless! 🚀✨\n", + "```\n", + "\n", + "This addition to the notebook showcases CrossGL's ability to convert shaders from different graphics APIs back into its universal language, completing the circle of its translation capabilities. It provides concrete examples for each major platform and explains the benefits of this two-way translation feature." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/samples.txt b/samples.txt deleted file mode 100644 index c20fa1ab..00000000 --- a/samples.txt +++ /dev/null @@ -1,453 +0,0 @@ -*****************************************EXAMPLES************************************** - -1. Perlin Noise Terrain Generation -shader main { - input vec3 position; - output vec4 fragColor; - - float perlinNoise(vec2 p) { - return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); - } - - void main() { - vec2 uv = position.xy * 10.0; - float noise = perlinNoise(uv); - float height = noise * 10.0; - vec3 color = vec3(height / 10.0, 1.0 - height / 10.0, 0.0); - fragColor = vec4(color, 1.0); - } -} -**************************************************************************************** -2. Real-Time Water Simulation -shader main { - input vec3 position; - output vec4 fragColor; - - float waveFunction(vec2 p) { - return sin(p.x * 10.0 + iTime) * 0.1; - } - - void main() { - vec2 uv = position.xy; - float wave = waveFunction(uv); - vec3 waterColor = vec3(0.0, 0.3, 0.8) * (1.0 - wave); - fragColor = vec4(waterColor, 1.0); - } -} - -****************************************************************************************** -3. Atmospheric Scattering -shader main { - input vec3 position; - output vec4 fragColor; - - vec3 rayleighScattering(float theta) { - return vec3(0.5, 0.7, 1.0) * pow(max(0.0, 1.0 - theta * theta), 3.0); - } - - void main() { - float theta = position.y; - vec3 color = rayleighScattering(theta); - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -4. Procedural Texturing with Complex Patterns -shader main { - input vec2 texCoord; - output vec4 fragColor; - - float marblePattern(vec2 uv) { - return 0.5 + 0.5 * sin(10.0 * uv.x + iTime); - } - - void main() { - vec3 color = vec3(marblePattern(texCoord), 0.0, 0.0); - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -5. Advanced Post-Processing Effects (Bloom Example) -shader main { - input vec2 texCoord; - output vec4 fragColor; - - float brightness = texture2D(iChannel0, texCoord).r; - float bloom = max(0.0, brightness - 0.5); - vec3 color = texture2D(iChannel0, texCoord).rgb + vec3(bloom); - fragColor = vec4(color, 1.0); -} -****************************************************************************************** -6. Realistic Skin Shader (Subsurface Scattering) -shader main { - input vec3 position; - output vec4 fragColor; - - float subsurfaceScattering(vec3 position) { - return exp(-length(position) * 2.0); - } - - void main() { - vec3 baseColor = vec3(1.0, 0.8, 0.6); - float sss = subsurfaceScattering(position); - vec3 color = baseColor * sss; - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -7. Dynamic Day-Night Cycle -shader main { - input vec3 position; - output vec4 fragColor; - - vec3 dayNightColor(float timeOfDay) { - return mix(vec3(0.0, 0.5, 1.0), vec3(0.0, 0.0, 0.2), timeOfDay); - } - - void main() { - float timeOfDay = mod(iTime / 24.0, 1.0); - vec3 color = dayNightColor(timeOfDay); - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -8. Fluid Dynamics Simulation -shader main { - input vec3 position; - output vec4 fragColor; - - float fluidMotion(vec3 p) { - return sin(p.x * 10.0 + iTime) * 0.5 + 0.5; - } - - void main() { - float motion = fluidMotion(position); - vec3 color = vec3(0.0, 0.0, 1.0) * motion; - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -9. Dynamic Water Shader -shader main { - input vec2 position; - output vec4 fragColor; - - float wave(vec2 p, float time) { - return sin(p.x * 10.0 + time * 2.0) * 0.1 + sin(p.y * 10.0 + time * 2.0) * 0.1; - } - - - void main() { - vec2 uv = position; - float waterHeight = wave(uv, iTime); - vec3 color = vec3(0.0, 0.3, 0.8) * (1.0 + waterHeight); - - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -10. Procedural Terrain Generation -shader main { - input vec2 position; - output vec4 fragColor; - - float noise(vec2 p) { - return sin(p.x * 10.0) * cos(p.y * 10.0); - } - - float heightMap(vec2 p) { - float n = noise(p * 10.0); - return p.y + n * 0.1; - } - - void main() { - vec2 uv = position; - float height = heightMap(uv); - vec3 color = vec3(0.5, 0.5, 0.5) * (1.0 - height * 0.5); - - fragColor = vec4(color, 1.0); - } -} -****************************************************************************************** -11.random code -shader complexShader { - input vec3 position; - input vec2 texCoord; - output vec4 fragColor; - - float calculateLighting(vec3 normal, vec3 lightDir) { - float diff = max(dot(normal, lightDir), 0.0); - return diff; - } - - vec4 textureColor(vec2 coord) { - return texture2D(textureSampler, coord); - } - - void main() { - vec3 normal = normalize(vec3(0.0, 0.0, 1.0)); - vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0)); - float lightIntensity = calculateLighting(normal, lightDir); - - vec4 color = textureColor(texCoord); - color *= lightIntensity; //error for color.rgb - - fragColor = color; - } -} -****************************************************************************************** -12] - -shader complexShader { - input vec3 position; - input vec2 texCoord; - output vec4 fragColor; - - uniform sampler2D textureSampler; - uniform float time; - uniform vec3 lightColor; - uniform mat4 modelMatrix; - - vec3 calculateLighting(vec3 normal, vec3 lightDir, vec3 viewDir) { - float ambientStrength = 0.1; - vec3 ambient = ambientStrength * lightColor; - - float diff = max(dot(normal, lightDir), 0.0); - vec3 diffuse = diff * lightColor; - - float specularStrength = 0.5; - vec3 reflectDir = reflect(-lightDir, normal); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0); - vec3 specular = specularStrength * spec * lightColor; - - return ambient + diffuse + specular; - } - - void main() { - vec4 texColor = texture(textureSampler, texCoord); - vec3 normal = normalize(cross(dFdx(position), dFdy(position))); - vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0)); - vec3 viewDir = normalize(-position); - - vec3 lighting = calculateLighting(normal, lightDir, viewDir); - vec4 color = vec4(lighting, 1.0) * texColor; - - fragColor = color; - } -} - -****************************************************************************************** -13] - -shader advancedShader { - input vec3 position; - input vec2 texCoord; - output vec4 fragColor; - - uniform sampler2D textureSampler; - uniform vec3 ambientColor; - uniform vec3 lightPos; - uniform vec3 viewPos; - uniform float shininess; - - vec3 calculateSpecular(vec3 normal, vec3 lightDir, vec3 viewDir) { - vec3 reflectDir = reflect(-lightDir, normal); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); - return spec * vec3(1.0, 1.0, 1.0); // White specular highlight - } - - void main() { - vec4 texColor = texture(textureSampler, texCoord); - - vec3 norm = normalize(cross(dFdx(position), dFdy(position))); - vec3 lightDir = normalize(lightPos - position); - vec3 viewDir = normalize(viewPos - position); - - // Ambient component - vec3 ambient = ambientColor; - - // Diffuse component - float diff = max(dot(norm, lightDir), 0.0); - vec3 diffuse = diff * vec3(1.0, 1.0, 1.0); // White diffuse light - - // Specular component - vec3 specular = calculateSpecular(norm, lightDir, viewDir); - - vec3 lighting = ambient + diffuse + specular; - vec4 color = vec4(lighting, 1.0) * texColor; - - fragColor = color; - } -} - - -****************************************************************************************** -14] -shader complexShader { - input vec3 position; - input vec2 texCoord; - input vec3 normal; - output vec4 fragColor; - - uniform sampler2D diffuseTexture; - uniform sampler2D specularTexture; - uniform sampler2D normalMap; - uniform vec3 lightPos; - uniform vec3 viewPos; - uniform vec3 ambientColor; - uniform float shininess; - uniform float specularIntensity; - - vec3 calculateSpecular(vec3 normal, vec3 lightDir, vec3 viewDir) { - vec3 reflectDir = reflect(-lightDir, normal); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); - return spec * vec3(1.0, 1.0, 1.0) * specularIntensity; - } - - vec3 applyNormalMapping(vec3 normal, vec3 mapNormal) { - return normalize(normal * mapNormal); - } - - void main() { - vec4 diffuseColor = texture(diffuseTexture, texCoord); - vec4 specularColor = texture(specularTexture, texCoord); - vec4 normalMapColor = texture(normalMap, texCoord); - - vec3 mapNormal = normalize(normalMapColor.rgb * 2.0 - 1.0); - vec3 perturbedNormal = applyNormalMapping(normal, mapNormal); - - vec3 lightDir = normalize(lightPos - position); - vec3 viewDir = normalize(viewPos - position); - - // Ambient component - vec3 ambient = ambientColor; - - // Diffuse component - float diff = max(dot(perturbedNormal, lightDir), 0.0); - vec3 diffuse = diff * diffuseColor.rgb; - - // Specular component - vec3 specular = calculateSpecular(perturbedNormal, lightDir, viewDir); - - vec3 lighting = ambient + diffuse + specular; - vec4 color = vec4(lighting, 1.0) * diffuseColor; - - fragColor = color; - } -} - -****************************************************************************************** -15] -shader complexShader { - input vec3 position; - input vec2 texCoord; - input vec3 normal; - output vec4 fragColor; - - uniform sampler2D diffuseTexture; - uniform sampler2D specularTexture; - uniform sampler2D normalMap; - uniform vec3 lightPos; - uniform vec3 viewPos; - uniform vec3 ambientColor; - uniform float shininess; - uniform float specularIntensity; - uniform int iterations; - - vec3 calculateSpecular(vec3 normal, vec3 lightDir, vec3 viewDir) { - vec3 reflectDir = reflect(-lightDir, normal); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); - return spec * vec3(1.0, 1.0, 1.0) * specularIntensity; - } - - vec3 applyNormalMapping(vec3 normal, vec3 mapNormal) { - return normalize(normal * mapNormal); - } - - void main() { - vec4 diffuseColor = texture(diffuseTexture, texCoord); - vec4 specularColor = texture(specularTexture, texCoord); - vec4 normalMapColor = texture(normalMap, texCoord); - - vec3 mapNormal = normalize(normalMapColor.rgb * 2.0 - 1.0); - vec3 perturbedNormal = applyNormalMapping(normal, mapNormal); - - vec3 lightDir = normalize(lightPos - position); - vec3 viewDir = normalize(viewPos - position); - - // Ambient component - vec3 ambient = ambientColor; - - // Diffuse component - float diff = max(dot(perturbedNormal, lightDir), 0.0); - vec3 diffuse = diff * diffuseColor.rgb; - - // Specular component - vec3 specular = calculateSpecular(perturbedNormal, lightDir, viewDir); - - // Loop to modify lighting based on iterations - vec3 lighting = ambient + diffuse + specular; - for (int i = 0; i < iterations; i++) { - lighting *= 0.9; - } - - // Ternary operator to conditionally modify color - vec4 color = (diff > 0.5) ? vec4(lighting, 1.0) * diffuseColor : vec4(lighting * 0.5, 1.0) * diffuseColor; - - fragColor = color; - } -} - -****************************************************************************************** -16] -shader nestedLoopsShader { - input vec3 position; - input vec2 texCoord; - input vec3 normal; - output vec4 fragColor; - - uniform sampler2D texture; - uniform vec3 lightPos; - uniform vec3 viewPos; - uniform vec3 ambientColor; - uniform float shininess; - uniform float specularIntensity; - uniform int outerIterations; - uniform int innerIterations; - - vec3 calculateSpecular(vec3 normal, vec3 lightDir, vec3 viewDir) { - vec3 reflectDir = reflect(-lightDir, normal); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); - return spec * vec3(1.0, 1.0, 1.0) * specularIntensity; - } - - void main() { - vec4 texColor = texture(texture, texCoord); - vec3 lightDir = normalize(lightPos - position); - vec3 viewDir = normalize(viewPos - position); - - vec3 ambient = ambientColor; - vec3 diffuse = texColor.rgb; - vec3 specular = vec3(0.0); - - // Outer loop - for (int i = 0; i < outerIterations; i++) { - // Inner loop - for (int j = 0; j < innerIterations; j++) { - // Compute lighting - vec3 tempSpecular = calculateSpecular(normal, lightDirModified, viewDirModified); - specular += tempSpecular; - } - - // Reduce diffuse intensity progressively - diffuse *= 0.9; - } - - vec3 lighting = ambient + diffuse + specular; - fragColor = vec4(lighting, 1.0); - } -} - -****************************************************************************************** - -****************************************************************************************** \ No newline at end of file diff --git a/src/backend/DirectX/DirectxCrossGLCodeGen.py b/src/backend/DirectX/DirectxCrossGLCodeGen.py index 5e5e7aa7..68993a7a 100644 --- a/src/backend/DirectX/DirectxCrossGLCodeGen.py +++ b/src/backend/DirectX/DirectxCrossGLCodeGen.py @@ -155,56 +155,3 @@ def generate_expression(self, expr, is_main=False): def map_type(self, hlsl_type): return self.type_map.get(hlsl_type, hlsl_type) - - -# Usage -if __name__ == "__main__": - code = """ -float perlinNoise(float2 p) { - return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453)); -} - -struct Vertex_INPUT { - float3 position : POSITION; -}; - -struct Vertex_OUTPUT { - float4 position : SV_POSITION; - float2 vUV : TEXCOORD0; -}; - -Vertex_OUTPUT VSMain(Vertex_INPUT input) { - Vertex_OUTPUT output; - output.vUV = (input.position.xy * 10.0); - output.position = float4(input.position, 1.0); - return output; -} - -struct Fragment_INPUT { - float2 vUV : TEXCOORD0; -}; - -struct Fragment_OUTPUT { - float4 fragColor : SV_TARGET0; -}; - -Fragment_OUTPUT PSMain(Fragment_INPUT input) { - Fragment_OUTPUT output; - float noise = perlinNoise(input.vUV); - float height = (noise * 10.0); - float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0); - output.fragColor = float4(color, 1.0); - return output; -} - - - """ - - lexer = HLSLLexer(code) - parser = HLSLParser(lexer.tokens) - ast = parser.parse() - print("Parsing completed successfully!") - print(ast) - codegen = HLSLToCrossGLConverter() - hlsl_code = codegen.convert(ast) - print(hlsl_code) diff --git a/src/backend/DirectX/DirectxLexer.py b/src/backend/DirectX/DirectxLexer.py index 395ed784..95ca21dc 100644 --- a/src/backend/DirectX/DirectxLexer.py +++ b/src/backend/DirectX/DirectxLexer.py @@ -101,55 +101,3 @@ def tokenize(self): ) self.tokens.append(("EOF", "")) - - -if __name__ == "__main__": - hlsl_code = """ -struct VS_INPUT { - float3 position : POSITION; - float2 texCoord : TEXCOORD0; -}; - -struct PS_INPUT { - float4 position : SV_POSITION; - float2 texCoord : TEXCOORD0; -}; - -Texture2D mainTexture : register(t0); -SamplerState mainSampler : register(s0); - -float4 BlurPixel(float2 texCoord, float2 texelSize, float blurAmount) -{ - float4 color = float4(0.0, 0.0, 0.0, 0.0); - - for (int x = -3; x <= 3; ++x) - { - for (int y = -3; y <= 3; ++y) - { - float2 offset = float2(float(x), float(y)) * texelSize * blurAmount; - color += mainTexture.Sample(mainSampler, texCoord + offset); - } - } - - return color / 49.0; -} - -PS_INPUT VSMain(VS_INPUT input) -{ - PS_INPUT output; - output.position = float4(input.position, 1.0); - output.texCoord = input.texCoord; - return output; -} - -float4 PSMain(PS_INPUT input) : SV_TARGET -{ - float2 texelSize = 1.0 / float2(1920, 1080); // Assume 1920x1080 resolution - float blurAmount = 1.0; - return BlurPixel(input.texCoord, texelSize, blurAmount); -} -""" - - lexer = HLSLLexer(hlsl_code) - for token in lexer.tokens: - print(token) diff --git a/src/backend/DirectX/DirectxParser.py b/src/backend/DirectX/DirectxParser.py index 674f9048..c02ee065 100644 --- a/src/backend/DirectX/DirectxParser.py +++ b/src/backend/DirectX/DirectxParser.py @@ -29,7 +29,6 @@ def skip_comments(self): def eat(self, token_type): if self.current_token[0] == token_type: - print(f"Eating {self.current_token}") self.pos += 1 self.current_token = ( self.tokens[self.pos] if self.pos < len(self.tokens) else ("EOF", None) @@ -397,68 +396,3 @@ def parse_member_access(self, object): return self.parse_member_access(MemberAccessNode(object, member)) return MemberAccessNode(object, member) - - -# Usage example -if __name__ == "__main__": - hlsl_code = """ - // This is a single-line comment - /* This is a - multi-line comment */ - struct VS_INPUT { - float3 position : POSITION; - float2 texCoord : TEXCOORD0; - }; - - float4 calculateNormal(float3 position, float3 normal) - { - float4 result = float4(normal, 1.0); - return result; - } - - struct VS_OUTPUT { - float4 position : SV_POSITION; - float2 texCoord : TEXCOORD0; - }; - - VS_OUTPUT VSMain(VS_INPUT input) - { - VS_OUTPUT output; - output.texCoord = input.texCoord; - for (int i = 0; i < 10; i=i+1){ - output.position = float4(input.position, 1.0); - } - - if (output.position.x > 0.0) { - output.position.y = 0.0; - } else { - output.position.y = 1.0; - } - - output.position = float4(input.position, 1.0); - return output; - } - - struct PS_OUTPUT { - float4 color : SV_TARGET; - }; - - PS_OUTPUT PSMain(VS_OUTPUT input) : SV_TARGET - { - PS_OUTPUT output; - output.color = float4(1.0, 0.0, 0.0, 1.0); - return output; - } - - - - """ - - lexer = HLSLLexer(hlsl_code) - for token in lexer.tokens: - print(token) - parser = HLSLParser(lexer.tokens) - ast = parser.parse() - - print("Parsing completed successfully!") - print(ast) diff --git a/src/backend/DirectX/__init__.py b/src/backend/DirectX/__init__.py index cdaec841..f4cfd7bf 100644 --- a/src/backend/DirectX/__init__.py +++ b/src/backend/DirectX/__init__.py @@ -1,3 +1,3 @@ from .DirectxLexer import HLSLLexer from .DirectxParser import HLSLParser -from .DirecxCrossGLCodeGen import HLSLToCrossGLConverter +from .DirectxCrossGLCodeGen import HLSLToCrossGLConverter diff --git a/src/backend/Metal/MetalCrossGLCodeGen.py b/src/backend/Metal/MetalCrossGLCodeGen.py index 14c7d94a..1a908cb9 100644 --- a/src/backend/Metal/MetalCrossGLCodeGen.py +++ b/src/backend/Metal/MetalCrossGLCodeGen.py @@ -174,58 +174,3 @@ def generate_expression(self, expr, is_main=False): def map_type(self, metal_type): return self.type_map.get(metal_type, metal_type) - - -# Usage -if __name__ == "__main__": - code = """ -#include -using namespace metal; - -float perlinNoise(float2 p) { - return fract((sin(dot(p, float2(12.9898, 78.233))) * 43758.5453)); -} - -struct Vertex_INPUT { - float3 position [[attribute(0)]]; -}; - -struct Vertex_OUTPUT { - float4 position [[position]]; - float2 vUV; -}; - -vertex Vertex_OUTPUT vertex_main(Vertex_INPUT input [[stage_in]]) { - Vertex_OUTPUT output; - output.vUV = (input.position.xy * 10.0); - output.position = float4(input.position, 1.0); - return output; -} - -struct Fragment_INPUT { - float2 vUV [[stage_in]]; -}; - -struct Fragment_OUTPUT { - float4 fragColor [[color(0)]]; -}; - -fragment Fragment_OUTPUT fragment_main(Fragment_INPUT input [[stage_in]]) { - Fragment_OUTPUT output; - float noise = perlinNoise(input.vUV); - float height = (noise * 10.0); - float3 color = float3((height / 10.0), (1.0 - (height / 10.0)), 0.0); - output.fragColor = float4(color, 1.0); - return output; -} - - """ - - lexer = MetalLexer(code) - parser = MetalParser(lexer.tokens) - ast = parser.parse() - print("Parsing completed successfully!") - print(ast) - codegen = MetalToCrossGLConverter() - metal_code = codegen.generate(ast) - print(metal_code) diff --git a/src/backend/Metal/MetalLexer.py b/src/backend/Metal/MetalLexer.py index e5c50f95..9323179b 100644 --- a/src/backend/Metal/MetalLexer.py +++ b/src/backend/Metal/MetalLexer.py @@ -117,24 +117,3 @@ def tokenize(self): ) self.tokens.append(("EOF", "")) - - -if __name__ == "__main__": - metal_code = """ - #include - using namespace metal; - - struct VertexInput { - float3 position [[attribute(0)]]; - float2 texCoord [[attribute(1)]]; - }; - - vertex float4 vertexShader(VertexInput input [[stage_in]]) - { - return float4(input.position, 1.0); - } - """ - - lexer = MetalLexer(metal_code) - for token in lexer.tokens: - print(token) diff --git a/src/backend/Metal/MetalParser.py b/src/backend/Metal/MetalParser.py index b65dd50d..a162cc2f 100644 --- a/src/backend/Metal/MetalParser.py +++ b/src/backend/Metal/MetalParser.py @@ -15,7 +15,6 @@ def skip_comments(self): def eat(self, token_type): if self.current_token[0] == token_type: - print(f"Eating {self.current_token}") self.pos += 1 self.current_token = ( self.tokens[self.pos] if self.pos < len(self.tokens) else ("EOF", None) @@ -510,70 +509,3 @@ def parse_texture_sample(self): coordinates = self.parse_expression() self.eat("RPAREN") return TextureSampleNode(texture, sampler, coordinates) - - -# Usage example -if __name__ == "__main__": - metal_code = """ - // This is a single-line comment - /* This is a - multi-line comment */ - #include - using namespace metal; - - struct VertexInput { - float3 position [[attribute(0)]]; - float2 texCoord [[attribute(1)]]; - }; - - struct FragmentInput { - float4 position [[position]]; - float2 texCoord; - }; - - float4 calculateNormal(float3 position, float3 normal) - { - float4 result = float4(normal, 1.0); - return result; - } - - vertex FragmentInput vertexShader(VertexInput input [[stage_in]]) - { - FragmentInput output; - output.texCoord = input.texCoord; - for (int i = 0; i < 10; i = i + 1) { - output.position = float4(input.position, 1.0); - } - - if (output.position.x > 0.0) { - output.position.y = 0.0; - } else { - output.position.y = 1.0; - } - - output.position = float4(input.position, 1.0); - return output; - } - - fragment float4 fragmentShader(FragmentInput input [[stage_in]]) - { - float4 color = input.texCoord; - return float4(color.rgb, 1.0); - } - - """ - - # First, create the lexer - lexer = MetalLexer(metal_code) - - # Print all tokens - print("Tokens:") - for token in lexer.tokens: - print(token) - - # Then, create the parser and parse the tokens - parser = MetalParser(lexer.tokens) - ast = parser.parse() - - print("\nParsing completed successfully!") - print(ast)