From 580d3fb560f31e22d3040fe80642fbaea1e3a4d4 Mon Sep 17 00:00:00 2001 From: Csaba Hruska Date: Thu, 4 Feb 2016 14:34:47 +0100 Subject: add cabal file for examples --- examples/Hello.hs | 8 ++- examples/HelloEmbedded.hs | 99 +++++++++++++++++++++++++++++++++++ examples/HelloJson.hs | 97 ---------------------------------- examples/LICENSE | 30 +++++++++++ examples/Setup.hs | 2 + examples/hello.json | 2 +- examples/lambdacube-gl-examples.cabal | 43 +++++++++++++++ 7 files changed, 178 insertions(+), 103 deletions(-) create mode 100644 examples/HelloEmbedded.hs delete mode 100644 examples/HelloJson.hs create mode 100644 examples/LICENSE create mode 100644 examples/Setup.hs create mode 100644 examples/lambdacube-gl-examples.cabal diff --git a/examples/Hello.hs b/examples/Hello.hs index 89553d0..081fd93 100644 --- a/examples/Hello.hs +++ b/examples/Hello.hs @@ -8,14 +8,12 @@ import LambdaCube.GL.Mesh as LambdaCubeGL import Codec.Picture as Juicy -import LambdaCube.Compiler.Driver as LambdaCube -- compiler +import Data.Aeson +import qualified Data.ByteString as SB main :: IO () main = do - -- compile hello.lc to graphics pipeline description - pipelineDesc <- LambdaCube.compileMain ["."] OpenGL33 "hello" >>= \case - Left err -> fail $ "compile error:\n" ++ err - Right pd -> return pd + Just pipelineDesc <- decodeStrict <$> SB.readFile "hello.json" win <- initWindow "LambdaCube 3D DSL Hello World" 640 640 diff --git a/examples/HelloEmbedded.hs b/examples/HelloEmbedded.hs new file mode 100644 index 0000000..fbddb20 --- /dev/null +++ b/examples/HelloEmbedded.hs @@ -0,0 +1,99 @@ +{-# LANGUAGE PackageImports, LambdaCase, OverloadedStrings #-} +import "GLFW-b" Graphics.UI.GLFW as GLFW +import qualified Data.Map as Map +import qualified Data.Vector as V + +import LambdaCube.GL as LambdaCubeGL -- renderer +import LambdaCube.GL.Mesh as LambdaCubeGL + +import Codec.Picture as Juicy + +import LambdaCube.Compiler as LambdaCube -- compiler + +main :: IO () +main = do + -- compile hello.lc to graphics pipeline description + pipelineDesc <- LambdaCube.compileMain ["."] OpenGL33 "hello" >>= \case + Left err -> fail $ "compile error:\n" ++ err + Right pd -> return pd + + win <- initWindow "LambdaCube 3D DSL Hello World" 640 640 + + -- setup render data + let inputSchema = makeSchema $ do + defObjectArray "objects" Triangles $ do + "position" @: Attribute_V2F + "uv" @: Attribute_V2F + defUniforms $ do + "time" @: Float + "diffuseTexture" @: FTexture2D + + storage <- LambdaCubeGL.allocStorage inputSchema + + -- upload geometry to GPU and add to pipeline input + LambdaCubeGL.uploadMeshToGPU triangleA >>= LambdaCubeGL.addMeshToObjectArray storage "objects" [] + LambdaCubeGL.uploadMeshToGPU triangleB >>= LambdaCubeGL.addMeshToObjectArray storage "objects" [] + + -- load image and upload texture + Right img <- Juicy.readImage "logo.png" + textureData <- LambdaCubeGL.uploadTexture2DToGPU img + + -- allocate GL pipeline + renderer <- LambdaCubeGL.allocRenderer pipelineDesc + LambdaCubeGL.setStorage renderer storage >>= \case -- check schema compatibility + Just err -> putStrLn err + Nothing -> loop + where loop = do + -- update graphics input + GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h) + LambdaCubeGL.updateUniforms storage $ do + "diffuseTexture" @= return textureData + "time" @= do + Just t <- GLFW.getTime + return (realToFrac t :: Float) + -- render + LambdaCubeGL.renderFrame renderer + GLFW.swapBuffers win + GLFW.pollEvents + + let keyIsPressed k = fmap (==KeyState'Pressed) $ GLFW.getKey win k + escape <- keyIsPressed Key'Escape + if escape then return () else loop + + LambdaCubeGL.disposeRenderer renderer + LambdaCubeGL.disposeStorage storage + GLFW.destroyWindow win + GLFW.terminate + +-- geometry data: triangles +triangleA :: LambdaCubeGL.Mesh +triangleA = Mesh + { mAttributes = Map.fromList + [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)]) + , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0]) + ] + , mPrimitive = P_Triangles + } + +triangleB :: LambdaCubeGL.Mesh +triangleB = Mesh + { mAttributes = Map.fromList + [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1]) + , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0]) + ] + , mPrimitive = P_Triangles + } + +initWindow :: String -> Int -> Int -> IO Window +initWindow title width height = do + GLFW.init + GLFW.defaultWindowHints + mapM_ GLFW.windowHint + [ WindowHint'ContextVersionMajor 3 + , WindowHint'ContextVersionMinor 3 + , WindowHint'OpenGLProfile OpenGLProfile'Core + , WindowHint'OpenGLForwardCompat True + ] + Just win <- GLFW.createWindow width height title Nothing Nothing + GLFW.makeContextCurrent $ Just win + return win diff --git a/examples/HelloJson.hs b/examples/HelloJson.hs deleted file mode 100644 index 081fd93..0000000 --- a/examples/HelloJson.hs +++ /dev/null @@ -1,97 +0,0 @@ -{-# LANGUAGE PackageImports, LambdaCase, OverloadedStrings #-} -import "GLFW-b" Graphics.UI.GLFW as GLFW -import qualified Data.Map as Map -import qualified Data.Vector as V - -import LambdaCube.GL as LambdaCubeGL -- renderer -import LambdaCube.GL.Mesh as LambdaCubeGL - -import Codec.Picture as Juicy - -import Data.Aeson -import qualified Data.ByteString as SB - -main :: IO () -main = do - Just pipelineDesc <- decodeStrict <$> SB.readFile "hello.json" - - win <- initWindow "LambdaCube 3D DSL Hello World" 640 640 - - -- setup render data - let inputSchema = makeSchema $ do - defObjectArray "objects" Triangles $ do - "position" @: Attribute_V2F - "uv" @: Attribute_V2F - defUniforms $ do - "time" @: Float - "diffuseTexture" @: FTexture2D - - storage <- LambdaCubeGL.allocStorage inputSchema - - -- upload geometry to GPU and add to pipeline input - LambdaCubeGL.uploadMeshToGPU triangleA >>= LambdaCubeGL.addMeshToObjectArray storage "objects" [] - LambdaCubeGL.uploadMeshToGPU triangleB >>= LambdaCubeGL.addMeshToObjectArray storage "objects" [] - - -- load image and upload texture - Right img <- Juicy.readImage "logo.png" - textureData <- LambdaCubeGL.uploadTexture2DToGPU img - - -- allocate GL pipeline - renderer <- LambdaCubeGL.allocRenderer pipelineDesc - LambdaCubeGL.setStorage renderer storage >>= \case -- check schema compatibility - Just err -> putStrLn err - Nothing -> loop - where loop = do - -- update graphics input - GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h) - LambdaCubeGL.updateUniforms storage $ do - "diffuseTexture" @= return textureData - "time" @= do - Just t <- GLFW.getTime - return (realToFrac t :: Float) - -- render - LambdaCubeGL.renderFrame renderer - GLFW.swapBuffers win - GLFW.pollEvents - - let keyIsPressed k = fmap (==KeyState'Pressed) $ GLFW.getKey win k - escape <- keyIsPressed Key'Escape - if escape then return () else loop - - LambdaCubeGL.disposeRenderer renderer - LambdaCubeGL.disposeStorage storage - GLFW.destroyWindow win - GLFW.terminate - --- geometry data: triangles -triangleA :: LambdaCubeGL.Mesh -triangleA = Mesh - { mAttributes = Map.fromList - [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)]) - , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0]) - ] - , mPrimitive = P_Triangles - } - -triangleB :: LambdaCubeGL.Mesh -triangleB = Mesh - { mAttributes = Map.fromList - [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1]) - , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0]) - ] - , mPrimitive = P_Triangles - } - -initWindow :: String -> Int -> Int -> IO Window -initWindow title width height = do - GLFW.init - GLFW.defaultWindowHints - mapM_ GLFW.windowHint - [ WindowHint'ContextVersionMajor 3 - , WindowHint'ContextVersionMinor 3 - , WindowHint'OpenGLProfile OpenGLProfile'Core - , WindowHint'OpenGLForwardCompat True - ] - Just win <- GLFW.createWindow width height title Nothing Nothing - GLFW.makeContextCurrent $ Just win - return win diff --git a/examples/LICENSE b/examples/LICENSE new file mode 100644 index 0000000..a4fcec0 --- /dev/null +++ b/examples/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2016, Csaba Hruska + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Csaba Hruska nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/examples/Setup.hs b/examples/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/examples/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/examples/hello.json b/examples/hello.json index 56de247..813ae8d 100644 --- a/examples/hello.json +++ b/examples/hello.json @@ -1 +1 @@ -{"textures":[],"commands":[{"tag":"SetRenderTarget","arg0":0},{"tag":"ClearRenderTarget","arg0":[{"tag":"ClearImage","clearValue":{"tag":"VV4F","arg0":{"w":1,"z":0.4,"x":0.0,"y":0.0}},"imageSemantic":{"tag":"Color"}}]},{"tag":"SetProgram","arg0":0},{"tag":"SetSamplerUniform","arg0":"diffuseTexture","arg1":0},{"tag":"SetRasterContext","arg0":{"arg3":{"tag":"LastVertex"},"tag":"TriangleCtx","arg0":{"tag":"CullNone"},"arg1":{"tag":"PolygonFill"},"arg2":{"tag":"NoOffset"}}},{"tag":"SetAccumulationContext","arg0":{"accViewportName":null,"tag":"AccumulationContext","accOperations":[{"tag":"ColorOp","arg0":{"tag":"NoBlending"},"arg1":{"tag":"VV4B","arg0":{"w":true,"z":true,"x":true,"y":true}}}]}},{"tag":"RenderSlot","arg0":0}],"slots":[{"tag":"Slot","slotPrimitive":{"tag":"Triangles"},"slotStreams":{"uv":{"tag":"V2F"},"position":{"tag":"V2F"}},"slotName":"objects","slotUniforms":{"time":{"tag":"Float"},"diffuseTexture":{"tag":"FTexture2D"}},"slotPrograms":[0]}],"programs":[{"programInTextures":{"diffuseTexture":{"tag":"FTexture2D"}},"tag":"Program","programOutput":[{"tag":"Parameter","ty":{"tag":"V4F"},"name":"f0"}],"programStreams":{"z1":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"position"},"a2":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"uv"}},"fragmentShader":"#version 330 core\nvec4 texture2D(sampler2D s, vec2 uv){return texture(s,uv);}\nuniform sampler2D diffuseTexture ;\nsmooth in vec2 v0 ;\nout vec4 f0 ;\nvoid main() {\nf0 = texture2D ( diffuseTexture,v0 );\n}\n","vertexShader":"#version 330 core\nvec4 texture2D(sampler2D s, vec2 uv){return texture(s,uv);}\nuniform float time ;\nin vec2 z1 ;\nin vec2 a2 ;\nsmooth out vec2 v0 ;\nvoid main() {\nv0 = a2;\ngl_Position = ( mat4 ( vec4 ( cos ( time ),sin ( time ),0.0,0.0 ),vec4 ( ( 0.0 ) - ( sin ( time ) ),cos ( time ),0.0,0.0 ),vec4 ( 0.0,0.0,1.0,0.0 ),vec4 ( 0.0,0.0,0.0,1.0 ) ) ) * ( vec4 ( ( z1 ).x,( z1 ).y,-1.0,1.0 ) );\ngl_PointSize = 1.0;\n}\n","geometryShader":null,"programUniforms":{"time":{"tag":"Float"},"diffuseTexture":{"tag":"FTexture2D"}}}],"samplers":[],"tag":"Pipeline","backend":{"tag":"OpenGL33"},"streams":[],"targets":[{"tag":"RenderTarget","renderTargets":[{"tag":"TargetItem","targetSemantic":{"tag":"Color"},"targetRef":{"tag":"Framebuffer","arg0":{"tag":"Color"}}}]}]} \ No newline at end of file +{"textures":[],"commands":[{"tag":"SetRenderTarget","arg0":0},{"tag":"ClearRenderTarget","arg0":[{"tag":"ClearImage","clearValue":{"tag":"VV4F","arg0":{"w":1,"z":0.4,"x":0.0,"y":0.0}},"imageSemantic":{"tag":"Color"}}]},{"tag":"SetProgram","arg0":0},{"tag":"SetSamplerUniform","arg0":"diffuseTexture","arg1":0},{"tag":"SetRasterContext","arg0":{"arg3":{"tag":"LastVertex"},"tag":"TriangleCtx","arg0":{"tag":"CullNone"},"arg1":{"tag":"PolygonFill"},"arg2":{"tag":"NoOffset"}}},{"tag":"SetAccumulationContext","arg0":{"accViewportName":null,"tag":"AccumulationContext","accOperations":[{"tag":"ColorOp","arg0":{"tag":"NoBlending"},"arg1":{"tag":"VV4B","arg0":{"w":true,"z":true,"x":true,"y":true}}}]}},{"tag":"RenderSlot","arg0":0}],"slots":[{"tag":"Slot","slotPrimitive":{"tag":"Triangles"},"slotStreams":{"uv":{"tag":"V2F"},"position":{"tag":"V2F"}},"slotName":"objects","slotUniforms":{"time":{"tag":"Float"},"diffuseTexture":{"tag":"FTexture2D"}},"slotPrograms":[0]}],"programs":[{"programInTextures":{"diffuseTexture":{"tag":"FTexture2D"}},"tag":"Program","programOutput":[{"tag":"Parameter","ty":{"tag":"V4F"},"name":"f0"}],"programStreams":{"v1":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"position"},"w1":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"uv"}},"fragmentShader":"#version 330 core\nvec4 texture2D(sampler2D s, vec2 uv){return texture(s,uv);}\nuniform sampler2D diffuseTexture ;\nsmooth in vec2 vv0 ;\nout vec4 f0 ;\nvoid main() {\nf0 = texture2D ( diffuseTexture,vv0 );\n}\n","vertexShader":"#version 330 core\nvec4 texture2D(sampler2D s, vec2 uv){return texture(s,uv);}\nuniform float time ;\nin vec2 v1 ;\nin vec2 w1 ;\nsmooth out vec2 vv0 ;\nvoid main() {\nvv0 = w1;\ngl_Position = ( mat4 ( vec4 ( cos ( time ),sin ( time ),0.0,0.0 ),vec4 ( ( 0.0 ) - ( sin ( time ) ),cos ( time ),0.0,0.0 ),vec4 ( 0.0,0.0,1.0,0.0 ),vec4 ( 0.0,0.0,0.0,1.0 ) ) ) * ( vec4 ( ( v1 ).x,( v1 ).y,-1.0,1.0 ) );\ngl_PointSize = 1.0;\n}\n","geometryShader":null,"programUniforms":{"time":{"tag":"Float"},"diffuseTexture":{"tag":"FTexture2D"}}}],"samplers":[],"tag":"Pipeline","backend":{"tag":"OpenGL33"},"streams":[],"targets":[{"tag":"RenderTarget","renderTargets":[{"tag":"TargetItem","targetSemantic":{"tag":"Color"},"targetRef":{"tag":"Framebuffer","arg0":{"tag":"Color"}}}]}]} \ No newline at end of file diff --git a/examples/lambdacube-gl-examples.cabal b/examples/lambdacube-gl-examples.cabal new file mode 100644 index 0000000..dc5f998 --- /dev/null +++ b/examples/lambdacube-gl-examples.cabal @@ -0,0 +1,43 @@ +name: lambdacube-gl-examples +version: 0.1.0.0 +synopsis: Basic example for LambdaCube 3D Haskell OpenGL backend +-- description: +homepage: http://lambdacube3d.com/getting-started +license: BSD3 +license-file: LICENSE +author: Csaba Hruska +maintainer: csaba.hruska@gmail.com +-- copyright: +category: Graphics +build-type: Simple +extra-source-files: hello.lc + hello.json +cabal-version: >=1.10 + +executable hello-gl + main-is: Hello.hs + build-depends: base >=4.8 && <4.9, + containers >=0.5 && <0.6, + vector >=0.11 && <0.12, + JuicyPixels >=3.2 && <3.3, + aeson >=0.9 && <0.11, + bytestring >=0.10 && <0.11, + GLFW-b >=1.4 && <1.5, + lambdacube-gl >=0.4 && <0.5 + -- hs-source-dirs: + default-language: Haskell2010 + +executable hello-gl-embedded + main-is: HelloEmbedded.hs + build-depends: base >=4.8 && <4.9, + containers >=0.5 && <0.6, + vector >=0.11 && <0.12, + JuicyPixels >=3.2 && <3.3, + aeson >=0.9 && <0.11, + bytestring >=0.10 && <0.11, + GLFW-b >=1.4 && <1.5, + lambdacube-gl >=0.4 && <0.5, + lambdacube-compiler >=0.4 && <0.5 + -- hs-source-dirs: + default-language: Haskell2010 + -- cgit v1.2.3