func loadMapToNode(model *editorModels.NodeModel) chan MapLoadUpdate { out := make(chan MapLoadUpdate) geomsLoaded := 0 var updateNode func(srcModel *editorModels.NodeModel, destNode *renderer.Node) updateNode = func(srcModel *editorModels.NodeModel, destNode *renderer.Node) { srcModel.SetNode(destNode) if srcModel.Geometry != nil { geometry, material, err := assets.ImportObjCached(*srcModel.Geometry) if err == nil { destNode.Material = material destNode.Add(geometry) } geomsLoaded++ out <- MapLoadUpdate{nil, geomsLoaded} } destNode.SetScale(srcModel.Scale) destNode.SetTranslation(srcModel.Translation) destNode.SetOrientation(srcModel.Orientation) if srcModel.Reference != nil { if refModel, _ := findNodeById(*srcModel.Reference, model); refModel != nil { for _, childModel := range refModel.Children { refNode := childModel.GetNode() if refNode != nil { destNode.Add(refNode) } } } } for _, childModel := range srcModel.Children { newNode := renderer.NewNode() destNode.Add(newNode) updateNode(childModel, newNode) } } node := renderer.NewNode() go func() { updateNode(model, node) out <- MapLoadUpdate{node, geomsLoaded} }() return out }
func (e *Editor) initSelectSprite() { img, _ := assets.DecodeImage(bytes.NewBuffer(util.Base64ToBytes(GeometryIconData))) mat := renderer.NewMaterial(renderer.NewTexture("diffuseMap", img, false)) selectSprite := effects.CreateSprite(1, 1, 1, mat) spriteNode := renderer.NewNode() spriteNode.RendererParams = &renderer.RendererParams{Unlit: true} spriteNode.Add(selectSprite) e.selectSprite = selectSprite e.gameEngine.AddSpatialTransparent(spriteNode) }
func NewWindow() *Window { node := renderer.NewNode() elementNode := renderer.NewNode() background := renderer.NewNode() background.Material = renderer.NewMaterial() box := renderer.CreateBoxWithOffset(1, 1, 0, 0) box.SetColor(color.NRGBA{255, 255, 255, 255}) background.Add(box) node.Add(background) node.Add(elementNode) return &Window{ node: node, backgroundBox: box, background: background, elementNode: elementNode, size: mgl32.Vec2{500, 1}, Tabs: []Activatable{}, } }
func NewParticleGroup(camera *renderer.Camera, particles ...*ParticleSystem) *ParticleGroup { node := renderer.NewNode() for _, particle := range particles { node.Add(particle) } return &ParticleGroup{ Node: node, camera: camera, particles: particles, } }
func NewImageElement(img image.Image) *ImageElement { imageElement := &ImageElement{ rotation: 0, Hitbox: NewHitbox(), node: renderer.NewNode(), } box := renderer.CreateBoxWithOffset(1, 1, 0, 0) imageElement.node.Add(box) imageElement.SetImage(img) return imageElement }
func NewContainer() *Container { node := renderer.NewNode() elementsNode := renderer.NewNode() background := renderer.NewNode() box := renderer.CreateBoxWithOffset(1, 1, 0, 0) box.SetColor(color.NRGBA{0, 0, 0, 0}) background.Material = renderer.NewMaterial() background.Add(box) node.Add(background) node.Add(elementsNode) return &Container{ node: node, elementsNode: elementsNode, background: background, backgroundBox: box, children: make([]Element, 0), Hitbox: NewHitbox(), padding: NewMargin(0), margin: NewMargin(0), } }
func New(assetDir string) *Editor { return &Editor{ assetDir: assetDir, uiAssets: ui.NewHtmlAssets(), rootMapNode: renderer.NewNode(), currentMap: &editorModels.MapModel{ Name: "default", Root: editorModels.NewNodeModel("root"), }, mouseMode: "scale", } }
func (loader *Loader) LoadMap(path string, callback func(node *renderer.Node, model *editorModels.NodeModel)) { go func() { srcModel := LoadMap(path) destNode := renderer.NewNode() loadedModel := LoadMapToNode(srcModel.Root, destNode) loader.maps <- mapImport{ node: destNode, model: loadedModel, callback: callback, } }() }
func CreateSprite(totalFrames, framesX, framesY int, material *renderer.Material) *Sprite { sprite := Sprite{ frame: 0, FaceCamera: true, totalFrames: totalFrames, framesX: framesX, framesY: framesY, } geometry := renderer.CreateBox(1, 1) sprite.geometry = geometry sprite.Node = renderer.NewNode() sprite.Node.Material = material sprite.Node.Add(sprite.geometry) return &sprite }
func CreateParticleSystem(settings ParticleSettings) *ParticleSystem { geometry := renderer.CreateGeometry(make([]uint32, 0, 0), make([]float32, 0, 0)) node := renderer.NewNode() node.Add(geometry) ps := ParticleSystem{ Settings: settings, FaceCamera: true, Node: node, geometry: geometry, particles: make([]*Particle, settings.MaxParticles), } ps.initParitcles() return &ps }
func NewTextElement(text string, textColor color.Color, textSize float32, textFont *truetype.Font) *TextElement { img := NewImageElement(image.NewAlpha(image.Rect(0, 0, 1, 1))) node := renderer.NewNode() node.Add(img.Spatial()) textElem := &TextElement{ img: img, node: node, props: textProps{ text: text, textColor: textColor, textSize: textSize, textFont: textFont, }, } if textFont == nil { defaultFont, _ := LoadFont(getDefaultFont()) textElem.SetFont(defaultFont) } return textElem }
func loadMapRecursive(model, srcModel *editorModels.NodeModel, destNode *renderer.Node) { model.SetNode(destNode) if model.Geometry != nil { geometry, material, err := ImportObjCached(*model.Geometry) if err == nil { destNode.Add(geometry) destNode.Material = material } } destNode.SetScale(model.Scale) destNode.SetTranslation(model.Translation) destNode.SetOrientation(model.Orientation) if model.Reference != nil { copyRef(model, srcModel) } for _, childModel := range model.Children { newNode := renderer.NewNode() destNode.Add(newNode) loadMapRecursive(childModel, srcModel, newNode) } }
func NewTextField(text string, textColor color.Color, textSize float32, textFont *truetype.Font) *TextField { cursor := renderer.CreateBoxWithOffset(0.07, 1.1, 0, 0.1) cursor.SetColor(color.NRGBA{0, 0, 0, 255}) cursorNode := renderer.NewNode() cursorNode.Material = renderer.NewMaterial() cursorNode.Add(cursor) tf := &TextField{ container: NewContainer(), text: NewTextElement(text, textColor, textSize, textFont), cursor: cursorNode, cursorPos: len(text), } tf.text.node.Add(cursorNode) tf.container.AddChildren(tf.text) tf.GetHitbox().AddOnClick(func(button int, release bool, position mgl32.Vec2) { if !release { tf.Activate() } }) tf.SetBackgroundColor(0, 0, 0, 0) tf.SetHeight(textSize * 1.5) tf.SetPadding(NewMargin(2)) return tf }
func main() { server := len(os.Args) > 1 && os.Args[1] == "server" var gameEngine engine.Engine var glRenderer *opengl.OpenglRenderer network := networking.NewNetwork() // Start server or connect to server if server { gameEngine = engine.NewHeadlessEngine() network.StartServer(serverPort) } else { glRenderer = opengl.NewOpenglRenderer("Networking example", 800, 800, false) gameEngine = engine.NewEngine(glRenderer) network.ConnectClient(fmt.Sprintf("%v:%v", serverAddr, serverPort)) } gameEngine.AddUpdatable(network) // map containing each player's entity players := make(map[string]*Player) //Networked Game events network.ClientJoinedEvent(func(clientId string) { fmt.Println("client joined, clientId: ", clientId) network.TriggerOnServerAndClients("spawn", util.SerializeArgs(clientId, startingPosition)) for _, player := range players { network.TriggerEvent("spawn", clientId, util.SerializeArgs(player.clientId, player.position)) } }) network.RegisterEvent("spawn", func(clientId string, data []byte) { buf := bytes.NewBuffer(data) playerID := util.Stringfrombytes(buf) position := util.Vector2frombytes(buf) if _, ok := players[playerID]; !ok { player := &Player{clientId: playerID} players[player.clientId] = player player.node = renderer.NewNode() player.position = position gameEngine.AddUpdatable(player) if network.IsClient() { boxGeometry := renderer.CreateBox(30, 30) boxGeometry.SetColor(color.NRGBA{254, 0, 0, 254}) player.node.Add(boxGeometry) gameEngine.AddOrtho(player.node) } } }) network.RegisterEvent("move", func(clientId string, data []byte) { buf := bytes.NewBuffer(data) playerID := util.Stringfrombytes(buf) velocity := util.Vector2frombytes(buf) if network.IsServer() && clientId != playerID { return // client is only allowed to control the player assigned to them. } if player, ok := players[playerID]; ok { player.velocity = velocity if network.IsServer() { network.BroadcastEvent("updatePlayer", util.SerializeArgs(playerID, player.position, player.velocity)) network.FlushAllWriteBuffers() } } }) network.RegisterEvent("updatePlayer", func(clientId string, data []byte) { if network.IsClient() { // This is a server to client update only buf := bytes.NewBuffer(data) playerID := util.Stringfrombytes(buf) position := util.Vector2frombytes(buf) velocity := util.Vector2frombytes(buf) if player, ok := players[playerID]; ok { player.position = position player.velocity = velocity } } }) // client setup gameEngine.Start(func() { if network.IsClient() { gameEngine.InitFpsDial() if shader, err := assets.ImportShader("shaders/build/basic.vert", "shaders/build/basic.frag"); err == nil { gameEngine.DefaultShader(shader) } glRenderer.BackGroundColor(0, 0.4, 0, 0) // input/controller manager controllerManager := glfwController.NewControllerManager(glRenderer.Window) // networked movement controls move := func(velocity mgl32.Vec2) { network.TriggerOnServerAndClients("move", util.SerializeArgs(network.ClientToken(), velocity)) } customController := controller.CreateController() controllerManager.AddController(customController.(glfwController.Controller)) customController.BindKeyAction(func() { move(mgl32.Vec2{0, -100}) }, controller.KeyW, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{-100, 0}) }, controller.KeyA, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{0, 100}) }, controller.KeyS, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{100, 0}) }, controller.KeyD, controller.Press) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyW, controller.Release) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyA, controller.Release) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyS, controller.Release) customController.BindKeyAction(func() { move(mgl32.Vec2{}) }, controller.KeyD, controller.Release) } }) }
func (e *Editor) Start() { glRenderer := opengl.NewOpenglRenderer("GoEngine Editor", 1800, 900, false) e.renderer = glRenderer e.gameEngine = engine.NewEngine(e.renderer) e.gameEngine.Start(func() { shader, err := assets.ImportShader( filepath.Join(e.assetDir, "shaders/build/pbr.vert"), filepath.Join(e.assetDir, "shaders/build/pbr.frag"), ) if err != nil { panic("error importing shader") } e.gameEngine.DefaultShader(shader) // Sky cubemap skyImg, err := assets.ImportImage(filepath.Join(e.assetDir, "resources/cubemap.png")) if err == nil { geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) e.gameEngine.AddSpatial(skyNode) // create an environmentMap using the skybox texture envCubeMap := renderer.NewCubemap("environmentMap", skyImg, true) e.gameEngine.DefaultCubeMap(envCubeMap) } l := renderer.NewLight(renderer.DIRECTIONAL) l.Color = [3]float32{0.7, 0.7, 0.8} e.gameEngine.AddLight(l) //root node e.gameEngine.AddSpatial(e.rootMapNode) //input/controller manager e.controllerManager = glfwController.NewControllerManager(glRenderer.Window) //camera + player camera := e.gameEngine.Camera() freeMoveActor := actor.NewFreeMoveActor(camera) freeMoveActor.MoveSpeed = 20.0 freeMoveActor.LookSpeed = 0.002 mainController := controller.NewBasicMovementController(freeMoveActor, true) e.controllerManager.AddController(mainController.(glfwController.Controller)) e.gameEngine.AddUpdatable(freeMoveActor) e.initSelectSprite() e.gameEngine.AddUpdatable(engine.UpdatableFunc(e.updateSelectSprite)) //editor controller e.controllerManager.AddController(NewEditorController(e).(glfwController.Controller)) //custom controller e.customController = controller.CreateController() e.controllerManager.AddController(e.customController.(glfwController.Controller)) e.setupUI() }) }
func main() { //renderer and game engine glRenderer := opengl.NewOpenglRenderer("Platformer", 800, 800, false) gameEngine := engine.NewEngine(glRenderer) gameEngine.InitFpsDial() // physics engine (Chipmonk) physicsSpace := chipmunkPhysics.NewChipmonkSpace() physicsSpace.SetGravity(mgl32.Vec2{0, 400}) gameEngine.AddUpdatable(physicsSpace) gameEngine.Start(func() { glRenderer.BackGroundColor(0.7, 0.7, 0.9, 0.0) // load in default shader shader := renderer.NewShader() shader.FragSrc = fragShader shader.VertSrc = vertShader gameEngine.DefaultShader(shader) // The player object character := NewCharacter() character.body.SetPosition(mgl32.Vec2{400, 400}) // Add the character to all the things physicsSpace.AddBody(character.body) gameEngine.AddOrtho(character.sprite) gameEngine.AddUpdatable(character) // terrain terrainGeometry := renderer.CreateBoxWithOffset(800, 800-floorHeight, 0, floorHeight) terrainGeometry.SetColor(color.NRGBA{0, 80, 0, 254}) gameEngine.AddOrtho(terrainGeometry) // terrain physics body terrainBody := chipmunkPhysics.NewChipmunkBodyStatic() segment := chipmunk.NewSegment(vect.Vect{0, floorHeight}, vect.Vect{4000, floorHeight}, 0) terrainBody.Body.AddShape(segment) physicsSpace.AddBody(terrainBody) particleNode := renderer.NewNode() gameEngine.AddOrtho(particleNode) // create a new timed particle system spawnParticles := func(load func() *effects.ParticleGroup, position mgl32.Vec2) { particleGroup := load() particleGroup.SetTranslation(position.Vec3(0)) effects.TriggerTimedParticleGroup( effects.TimedParticleGroup{ Particles: particleGroup, GameEngine: gameEngine, TargetNode: particleNode, Life: 0.2, Cleanup: 10, }, ) } // input/controller manager controllerManager := glfwController.NewControllerManager(glRenderer.Window) // key bindings customController := controller.CreateController() controllerManager.AddController(customController.(glfwController.Controller)) // Walk customController.BindKeyAction(func() { character.body.SetVelocity(mgl32.Vec2{-200, character.body.GetVelocity().Y()}) }, controller.KeyA, controller.Press) customController.BindKeyAction(func() { character.body.SetVelocity(mgl32.Vec2{200, character.body.GetVelocity().Y()}) }, controller.KeyD, controller.Press) //Stop walking customController.BindKeyAction(func() { character.body.SetVelocity(mgl32.Vec2{0, character.body.GetVelocity().Y()}) }, controller.KeyA, controller.Release) customController.BindKeyAction(func() { character.body.SetVelocity(mgl32.Vec2{0, character.body.GetVelocity().Y()}) }, controller.KeyD, controller.Release) // Jump customController.BindKeyAction(func() { character.body.SetVelocity(character.body.GetVelocity().Add(mgl32.Vec2{0, -300})) spawnParticles(dustParticles, character.body.GetPosition().Add(mgl32.Vec2{0, 0.5 * characterSize})) }, controller.KeySpace, controller.Press) // shoot customController.BindMouseAction(func() { spawnParticles(majicParticles, character.body.GetPosition()) }, controller.MouseButtonLeft, controller.Press) // create sparks when player collides with somthing var collisionTimer time.Time physicsSpace.SetOnCollision(func(shapeA, shapeB *chipmunk.Shape) { if time.Since(collisionTimer) > 200*time.Millisecond { spawnParticles(sparkParticles, character.body.GetPosition().Add(mgl32.Vec2{0, 0.5 * characterSize})) } collisionTimer = time.Now() }) }) }
func setupScene(gameEngine engine.Engine, shader *renderer.Shader) { camera := gameEngine.Camera() transparentNode := renderer.NewNode() gameEngine.AddSpatialTransparent(transparentNode) transparentNode.RendererParams = &renderer.RendererParams{ DepthTest: true, Unlit: true, Transparency: renderer.EMISSIVE, } // Sky cubemap skyImg, err := assets.ImportImage("TestAssets/cloudSky.jpg") if err == nil { skyImg = imaging.AdjustBrightness(skyImg, -30) skyImg = imaging.AdjustContrast(skyImg, 30) geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) gameEngine.AddSpatial(skyNode) // create an environmentMap using the skybox texture envCubeMap := renderer.NewCubemap("environmentMap", skyImg, true) gameEngine.DefaultCubeMap(envCubeMap) } // load scene objs objs := []string{ "TestAssets/wellScene/floor.obj", "TestAssets/wellScene/frame1.obj", "TestAssets/wellScene/frame2.obj", "TestAssets/wellScene/well.obj", "TestAssets/wellScene/torches.obj", } for _, objFile := range objs { if geom, mat, err := assets.ImportObjCached(objFile); err == nil { sceneNode := renderer.NewNode() sceneNode.Add(geom) sceneNode.Material = mat sceneNode.RendererParams = renderer.NewRendererParams() sceneNode.RendererParams.CullBackface = false gameEngine.AddSpatial(sceneNode) } } for i := 0; i < 2; i++ { torchLocation := mgl32.Vec3{0.86, 1.76, 1.05} if i == 1 { torchLocation = mgl32.Vec3{0.86, 1.76, -1.05} } fire := fireParticles() spark := sparkParticles() torchParticles := effects.NewParticleGroup(camera, fire, spark) torchParticles.SetTranslation(torchLocation) transparentNode.Add(torchParticles) gameEngine.AddUpdatable(torchParticles) light := renderer.NewLight(renderer.POINT) light.SetTranslation(torchLocation.Add(mgl32.Vec3{0, 0.05, 0})) gameEngine.AddLight(light) var x float64 gameEngine.AddUpdatable(engine.UpdatableFunc(func(dt float64) { x += dt mag := float32(math.Abs(0.6*math.Sin(3*x)+0.3*math.Sin(4*x)+0.15*math.Sin(7*x)+0.1*math.Sin(15*x))) + 0.5 mag *= 0.05 light.Color = [3]float32{1 * mag, 0.6 * mag, 0.4 * mag} })) } }
func (engine *EngineImpl) initNodes() { engine.opaqueNode, engine.transparentNode, engine.orthoNode = renderer.NewNode(), renderer.NewNode(), renderer.NewNode() }
func main() { glRenderer := opengl.NewOpenglRenderer("Simple", 800, 800, false) gameEngine := engine.NewEngine(glRenderer) gameEngine.InitFpsDial() gameEngine.Start(func() { if shader, err := assets.ImportShader("shaders/build/basic.vert", "shaders/build/basic.frag"); err == nil { gameEngine.DefaultShader(shader) } // sky cube skyImg, err := assets.ImportImage("resources/cubemap.png") if err == nil { geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) gameEngine.AddSpatial(skyNode) } // Add some light to the scene ambientLight := renderer.NewLight(renderer.AMBIENT) ambientLight.Color = [3]float32{0.3, 0.3, 0.3} gameEngine.AddLight(ambientLight) // Create a red box geometry, attach to a node, add the node to the scenegraph boxGeometry := renderer.CreateBox(10, 10) boxGeometry.SetColor(color.NRGBA{254, 0, 0, 254}) boxNode := renderer.NewNode() boxNode.RendererParams = renderer.NewRendererParams() boxNode.RendererParams.CullBackface = false boxNode.Material = renderer.NewMaterial() boxNode.SetTranslation(mgl32.Vec3{30, 0}) boxNode.Add(boxGeometry) gameEngine.AddSpatial(boxNode) // make the box spin var angle float64 gameEngine.AddUpdatable(engine.UpdatableFunc(func(dt float64) { angle += dt q := mgl32.QuatRotate(float32(angle), mgl32.Vec3{0, 1, 0}) boxNode.SetOrientation(q) })) // input/controller manager controllerManager := glfwController.NewControllerManager(glRenderer.Window) // camera + wasd controls camera := gameEngine.Camera() freeMoveActor := actor.NewFreeMoveActor(camera) freeMoveActor.Location = mgl32.Vec3{} mainController := controller.NewBasicMovementController(freeMoveActor, false) controllerManager.AddController(mainController.(glfwController.Controller)) gameEngine.AddUpdatable(freeMoveActor) //lock the cursor glRenderer.LockCursor(true) // custom key bindings customController := controller.CreateController() controllerManager.AddController(customController.(glfwController.Controller)) // close window and exit on escape customController.BindKeyAction(func() { glRenderer.Window.SetShouldClose(true) }, controller.KeyEscape, controller.Press) }) }