core icon indicating copy to clipboard operation
core copied to clipboard

3d scene didn't work with GoStartEventLoop

Open runsys opened this issue 5 years ago • 6 comments

3d scene didn't work with GoStartEventLoop

runsys avatar Dec 05 '19 03:12 runsys

need more details in issue reports for these to be useful. Thanks!

rcoreilly avatar Dec 05 '19 07:12 rcoreilly

It can only work with event loop function StartEventLoop in main window.

runsys avatar Dec 06 '19 00:12 runsys

sorry I didn't quite remember what this was all about -- if you use GoStartEventLoop you need to use a wait group -- otherwise it just terminates immediately. did you do that? the goki/gide/cmd/gide app is an example of using GoStartEventLoop. If you opened another scene within an already-running app using GoStart* and it didn't work, please report the behavior and ideally post a simple example that demonstrates the problem.

rcoreilly avatar Dec 07 '19 07:12 rcoreilly

I have checked the gide example. I used that way. But it also didn't show up with 3d scene. this is my code: // Copyright (c) 2018, The GoKi Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.

package main

import ( "github.com/goki/gi/gi" "github.com/goki/gi/gi3d" "github.com/goki/gi/gimain" "github.com/goki/gi/mat32" "github.com/goki/ki/ki" )

func main() { gimain.Main(func() { mainrun() }) }

func mainrun() { width := 1280 height := 920 wnm := "gogi-editor" wti := "GoGi Editor"

rec := ki.Node{}          // receiver for events
rec.InitName(&rec, "rec") // this is essential for root objects not owned by other Ki tree nodes

win := gi.NewWindow2D(wnm, wti, width, height, true)

vp := win.WinViewport2D()
updt := vp.UpdateStart()

vp.Render.Paint.DrawCircle(&vp.Render, 0, 0, 1)

mfr := win.SetMainFrame()
mfr.Lay = gi.LayoutVert

graphtoolbar := gi.AddNewToolBar(mfr, "graphtoolbar")
graphtoolbar.Viewport = vp
graphtoolbar.SetStretchMaxWidth()
playbtn := graphtoolbar.AddAction(gi.ActOpts{Label: "Play", Icon: "play"}, win.This(),
	func(recv, send ki.Ki, sig int64, data interface{}) {
		NewWin(vp)
	})
playbtn.SetProp("margin", 0)
playbtn.SetProp("padding", 0)

//graphrunstartbtn := gi.AddNewButton(mfr, "graphrunstartbtn")
//graphrunstartbtn.Viewport = vp

scrow := gi.AddNewLayout(mfr, "scrow", gi.LayoutHoriz)
scrow.SetStretchMax()

scvw := gi3d.AddNewSceneView(scrow, "sceneview")
scvw.SetStretchMax()
scvw.Config()

//scvw.Viewport.Render.Paint.DrawLine(&scvw.Viewport.Render, 2, 2, 20, 20)

sc := scvw.Scene()

// first, add lights, set camera
sc.BgColor.SetUInt8(230, 230, 255, 255) // sky blue-ish
gi3d.AddNewAmbientLight(sc, "ambient", 0.3, gi3d.DirectSun)

dir := gi3d.AddNewDirLight(sc, "dir", 1, gi3d.DirectSun)
dir.Pos.Set(0, 2, 1) // default: 0,1,1 = above and behind us (we are at 0,0,X)

// point := gi3d.AddNewPointLight(sc, "point", 1, gi3d.DirectSun)
// point.Pos.Set(0, 5, 5)

// spot := gi3d.AddNewSpotLigjj

// spot.Pose.Pos.Set(0, 5, 5)

circle := gi3d.AddNewCircle(sc, "cube", 1)
circleobj := gi3d.AddNewObject(sc, sc, "green-trans-cube", circle.Name())
circleobj.Pose.Pos.Set(0, 0, 1)
circleobj.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

cbm := gi3d.AddNewBox(sc, "cube", 1, 1, 1)
// cbm.Segs.Set(10, 10, 10) // not clear if any diff really..

rbgp := gi3d.AddNewGroup(sc, sc, "r-b-group")

rcb := gi3d.AddNewObject(sc, rbgp, "red-cube", cbm.Name())
rcb.Pose.Pos.Set(-1, 0, 0)
rcb.Mat.Color.SetName("red")
rcb.Mat.Shiny = 500

bcb := gi3d.AddNewObject(sc, rbgp, "blue-cube", cbm.Name())
bcb.Pose.Pos.Set(1, 1, 0)
bcb.Pose.Scale.X = 2
bcb.Mat.Color.SetName("blue")
bcb.Mat.Shiny = 10

bcb.Mat.Specular.SetName("blue") // how you get rid of specular highlights

gcb := gi3d.AddNewObject(sc, sc, "green-trans-cube", cbm.Name())
gcb.Pose.Pos.Set(0, 0, 1)
gcb.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

tcg := gi3d.AddNewGroup(sc, sc, "TrackCamera") // automatically tracks camera -- FPS effect
fpgun := gi3d.AddNewObject(sc, tcg, "first-person-gun", cbm.Name())
fpgun.Pose.Scale.Set(.1, .1, 1)
fpgun.Pose.Pos.Set(.5, -.5, -2.5)          // in front of camera
fpgun.Mat.Color.SetUInt8(255, 0, 255, 128) // alpha = .5

grtx := gi3d.AddNewTextureFile(sc, "ground", "ground.png")
//wdtx := gi3d.AddNewTextureFile(sc, "wood", "wood.png")

floorp := gi3d.AddNewPlane(sc, "floor-plane", 10, 10)
floor := gi3d.AddNewObject(sc, sc, "floor", floorp.Name())
floor.Pose.Pos.Set(0, 0, 0)
floor.Mat.Color.SetName("tan")
floor.Mat.Emissive.SetName("brown")
floor.Mat.Bright = 2 // .5 for wood / brown
floor.Mat.SetTexture(sc, grtx)
floor.Mat.Tiling.Repeat.Set(40, 40)

txt := gi3d.AddNewText2D(sc, sc, "text", "Text2D 第三方can put <b>HTML</b> formatted<br>Text anywhere you might <i>want</i>")
// 	txt.SetProp("background-color", gi.Color{0, 0, 0, 0}) // transparent -- default
// txt.SetProp("background-color", "white")
// txt.SetProp("color", "black") // default
// txt.SetProp("margin", units.NewPt(4)) // default is 2 px
// txt.Mat.Bright = 5 // no dim text -- key if using a background and want it to be bright..
txt.Pose.Scale.SetScalar(0.2)
txt.Pose.Pos.Set(0, 2.2, 0)

sc.Camera.LookAt(mat32.Vec3Zero, mat32.Vec3Y) // defaults to looking at origin

win.MainMenuUpdated()
vp.UpdateEndNoSig(updt)
win.GoStartEventLoop() // in a separate goroutine

gi.WinWait.Wait()

}

func NewWin(obj ki.Ki) *gi.Window { width := 1280 height := 920 wnm := "gogi-editor" wti := "GoGi Editor"

rec := ki.Node{}          // receiver for events
rec.InitName(&rec, "rec") // this is essential for root objects not owned by other Ki tree nodes

win := gi.NewWindow2D(wnm, wti, width, height, true)

vp := win.WinViewport2D()
updt := vp.UpdateStart()

vp.Render.Paint.DrawCircle(&vp.Render, 0, 0, 1)

mfr := win.SetMainFrame()
mfr.Lay = gi.LayoutVert

graphtoolbar := gi.AddNewToolBar(mfr, "graphtoolbar")
graphtoolbar.Viewport = vp
graphtoolbar.SetStretchMaxWidth()
playbtn := graphtoolbar.AddAction(gi.ActOpts{Label: "Play", Icon: "play"}, win.This(),
	func(recv, send ki.Ki, sig int64, data interface{}) {
		NewWin(vp)
	})
playbtn.SetProp("margin", 0)
playbtn.SetProp("padding", 0)

scrow := gi.AddNewLayout(mfr, "scrow", gi.LayoutHoriz)
scrow.SetStretchMax()

scvw := gi3d.AddNewSceneView(scrow, "sceneview")
scvw.SetStretchMax()
scvw.Config()

//scvw.Viewport.Render.Paint.DrawLine(&scvw.Viewport.Render, 2, 2, 20, 20)

sc := scvw.Scene()

// first, add lights, set camera
sc.BgColor.SetUInt8(230, 230, 255, 255) // sky blue-ish
gi3d.AddNewAmbientLight(sc, "ambient", 0.3, gi3d.DirectSun)

dir := gi3d.AddNewDirLight(sc, "dir", 1, gi3d.DirectSun)
dir.Pos.Set(0, 2, 1) // default: 0,1,1 = above and behind us (we are at 0,0,X)

// point := gi3d.AddNewPointLight(sc, "point", 1, gi3d.DirectSun)
// point.Pos.Set(0, 5, 5)

// spot := gi3d.AddNewSpotLigjj

// spot.Pose.Pos.Set(0, 5, 5)

circle := gi3d.AddNewCircle(sc, "cube", 1)
circleobj := gi3d.AddNewObject(sc, sc, "green-trans-cube", circle.Name())
circleobj.Pose.Pos.Set(0, 0, 1)
circleobj.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

cbm := gi3d.AddNewBox(sc, "cube", 1, 1, 1)
// cbm.Segs.Set(10, 10, 10) // not clear if any diff really..

rbgp := gi3d.AddNewGroup(sc, sc, "r-b-group")

rcb := gi3d.AddNewObject(sc, rbgp, "red-cube", cbm.Name())
rcb.Pose.Pos.Set(-1, 0, 0)
rcb.Mat.Color.SetName("red")
rcb.Mat.Shiny = 500

bcb := gi3d.AddNewObject(sc, rbgp, "blue-cube", cbm.Name())
bcb.Pose.Pos.Set(1, 1, 0)
bcb.Pose.Scale.X = 2
bcb.Mat.Color.SetName("blue")
bcb.Mat.Shiny = 10

bcb.Mat.Specular.SetName("blue") // how you get rid of specular highlights

gcb := gi3d.AddNewObject(sc, sc, "green-trans-cube", cbm.Name())
gcb.Pose.Pos.Set(0, 0, 1)
gcb.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

tcg := gi3d.AddNewGroup(sc, sc, "TrackCamera") // automatically tracks camera -- FPS effect
fpgun := gi3d.AddNewObject(sc, tcg, "first-person-gun", cbm.Name())
fpgun.Pose.Scale.Set(.1, .1, 1)
fpgun.Pose.Pos.Set(.5, -.5, -2.5)          // in front of camera
fpgun.Mat.Color.SetUInt8(255, 0, 255, 128) // alpha = .5

grtx := gi3d.AddNewTextureFile(sc, "ground", "ground.png")
//wdtx := gi3d.AddNewTextureFile(sc, "wood", "wood.png")

floorp := gi3d.AddNewPlane(sc, "floor-plane", 10, 10)
floor := gi3d.AddNewObject(sc, sc, "floor", floorp.Name())
floor.Pose.Pos.Set(0, 0, 0)
floor.Mat.Color.SetName("tan")
floor.Mat.Emissive.SetName("brown")
floor.Mat.Bright = 2 // .5 for wood / brown
floor.Mat.SetTexture(sc, grtx)
floor.Mat.Tiling.Repeat.Set(40, 40)

txt := gi3d.AddNewText2D(sc, sc, "text", "Text2D 第三方can put <b>HTML</b> formatted<br>Text anywhere you might <i>want</i>")
// 	txt.SetProp("background-color", gi.Color{0, 0, 0, 0}) // transparent -- default
// txt.SetProp("background-color", "white")
// txt.SetProp("color", "black") // default
// txt.SetProp("margin", units.NewPt(4)) // default is 2 px
// txt.Mat.Bright = 5 // no dim text -- key if using a background and want it to be bright..
txt.Pose.Scale.SetScalar(0.2)
txt.Pose.Pos.Set(0, 2.2, 0)

sc.Camera.LookAt(mat32.Vec3Zero, mat32.Vec3Y) // defaults to looking at origin

win.MainMenuUpdated()
vp.UpdateEndNoSig(updt)
win.GoStartEventLoop() // in a separate goroutine
return win

}

runsys avatar Dec 07 '19 14:12 runsys

I was able to replicate this issue on my mac -- by repeatedly hitting the Play button I got seemingly random results that varied between a blank blue window, a black & white version of the correct 3D display, and the full color correct version of the display.

Then, I changed the Play code to use go directly -- and then it worked every time. I think the issue likely has to do with creating the opengl context on the same thread vs. separate threads, but I don't have time to track it any further right now. Anyway, the immediate fix is to use a separate goroutine to launch any new 3D windows.

	playbtn := graphtoolbar.AddAction(gi.ActOpts{Label: "Play", Icon: "play"}, win.This(),
		func(recv, send ki.Ki, sig int64, data interface{}) {
			go NewWin(vp)
		})

updated version of test code for future reference, without circles and with new NewMainWindow call.

// Copyright (c) 2018, The GoKi Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"github.com/goki/gi/gi"
	"github.com/goki/gi/gi3d"
	"github.com/goki/gi/gimain"
	"github.com/goki/gi/mat32"
	"github.com/goki/ki/ki"
)

func main() {
	gimain.Main(func() {
		mainrun()
	})
}

func mainrun() {
	width := 1280
	height := 920
	wnm := "gogi-editor"
	wti := "GoGi Editor"

	rec := ki.Node{}          // receiver for events
	rec.InitName(&rec, "rec") // this is essential for root objects not owned by other Ki tree nodes

	win := gi.NewMainWindow(wnm, wti, width, height)

	vp := win.WinViewport2D()
	updt := vp.UpdateStart()

	vp.Render.Paint.DrawCircle(&vp.Render, 0, 0, 1)

	mfr := win.SetMainFrame()
	mfr.Lay = gi.LayoutVert

	graphtoolbar := gi.AddNewToolBar(mfr, "graphtoolbar")
	graphtoolbar.Viewport = vp
	graphtoolbar.SetStretchMaxWidth()
	playbtn := graphtoolbar.AddAction(gi.ActOpts{Label: "Play", Icon: "play"}, win.This(),
		func(recv, send ki.Ki, sig int64, data interface{}) {
			NewWin(vp)
		})
	playbtn.SetProp("margin", 0)
	playbtn.SetProp("padding", 0)

	//graphrunstartbtn := gi.AddNewButton(mfr, "graphrunstartbtn")
	//graphrunstartbtn.Viewport = vp

	scrow := gi.AddNewLayout(mfr, "scrow", gi.LayoutHoriz)
	scrow.SetStretchMax()

	scvw := gi3d.AddNewSceneView(scrow, "sceneview")
	scvw.SetStretchMax()
	scvw.Config()

	//scvw.Viewport.Render.Paint.DrawLine(&scvw.Viewport.Render, 2, 2, 20, 20)

	sc := scvw.Scene()

	// first, add lights, set camera
	sc.BgColor.SetUInt8(230, 230, 255, 255) // sky blue-ish
	gi3d.AddNewAmbientLight(sc, "ambient", 0.3, gi3d.DirectSun)

	dir := gi3d.AddNewDirLight(sc, "dir", 1, gi3d.DirectSun)
	dir.Pos.Set(0, 2, 1) // default: 0,1,1 = above and behind us (we are at 0,0,X)

	// point := gi3d.AddNewPointLight(sc, "point", 1, gi3d.DirectSun)
	// point.Pos.Set(0, 5, 5)

	// spot := gi3d.AddNewSpotLigjj

	// spot.Pose.Pos.Set(0, 5, 5)

	// circle := gi3d.AddNewCircle(sc, "cube", 1)
	// circleobj := gi3d.AddNewObject(sc, sc, "green-trans-cube", circle.Name())
	// circleobj.Pose.Pos.Set(0, 0, 1)
	// circleobj.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

	cbm := gi3d.AddNewBox(sc, "cube", 1, 1, 1)
	// cbm.Segs.Set(10, 10, 10) // not clear if any diff really..

	rbgp := gi3d.AddNewGroup(sc, sc, "r-b-group")

	rcb := gi3d.AddNewObject(sc, rbgp, "red-cube", cbm.Name())
	rcb.Pose.Pos.Set(-1, 0, 0)
	rcb.Mat.Color.SetName("red")
	rcb.Mat.Shiny = 500

	bcb := gi3d.AddNewObject(sc, rbgp, "blue-cube", cbm.Name())
	bcb.Pose.Pos.Set(1, 1, 0)
	bcb.Pose.Scale.X = 2
	bcb.Mat.Color.SetName("blue")
	bcb.Mat.Shiny = 10

	bcb.Mat.Specular.SetName("blue") // how you get rid of specular highlights

	gcb := gi3d.AddNewObject(sc, sc, "green-trans-cube", cbm.Name())
	gcb.Pose.Pos.Set(0, 0, 1)
	gcb.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

	tcg := gi3d.AddNewGroup(sc, sc, "TrackCamera") // automatically tracks camera -- FPS effect
	fpgun := gi3d.AddNewObject(sc, tcg, "first-person-gun", cbm.Name())
	fpgun.Pose.Scale.Set(.1, .1, 1)
	fpgun.Pose.Pos.Set(.5, -.5, -2.5)          // in front of camera
	fpgun.Mat.Color.SetUInt8(255, 0, 255, 128) // alpha = .5

	grtx := gi3d.AddNewTextureFile(sc, "ground", "ground.png")
	//wdtx := gi3d.AddNewTextureFile(sc, "wood", "wood.png")

	floorp := gi3d.AddNewPlane(sc, "floor-plane", 10, 10)
	floor := gi3d.AddNewObject(sc, sc, "floor", floorp.Name())
	floor.Pose.Pos.Set(0, 0, 0)
	floor.Mat.Color.SetName("tan")
	floor.Mat.Emissive.SetName("brown")
	floor.Mat.Bright = 2 // .5 for wood / brown
	floor.Mat.SetTexture(sc, grtx)
	floor.Mat.Tiling.Repeat.Set(40, 40)

	txt := gi3d.AddNewText2D(sc, sc, "text", "Text2D 第三方can put <b>HTML</b> formatted<br>Text anywhere you might <i>want</i>")
	// 	txt.SetProp("background-color", gi.Color{0, 0, 0, 0}) // transparent -- default
	// txt.SetProp("background-color", "white")
	// txt.SetProp("color", "black") // default
	// txt.SetProp("margin", units.NewPt(4)) // default is 2 px
	// txt.Mat.Bright = 5 // no dim text -- key if using a background and want it to be bright..
	txt.Pose.Scale.SetScalar(0.2)
	txt.Pose.Pos.Set(0, 2.2, 0)

	sc.Camera.LookAt(mat32.Vec3Zero, mat32.Vec3Y) // defaults to looking at origin

	win.MainMenuUpdated()
	vp.UpdateEndNoSig(updt)
	win.GoStartEventLoop() // in a separate goroutine

	gi.WinWait.Wait()
}

func NewWin(obj ki.Ki) *gi.Window {
	width := 1280
	height := 920
	wnm := "gogi-editor"
	wti := "GoGi Editor"

	rec := ki.Node{}          // receiver for events
	rec.InitName(&rec, "rec") // this is essential for root objects not owned by other Ki tree nodes

	win := gi.NewMainWindow(wnm, wti, width, height)

	vp := win.WinViewport2D()
	updt := vp.UpdateStart()

	vp.Render.Paint.DrawCircle(&vp.Render, 0, 0, 1)

	mfr := win.SetMainFrame()
	mfr.Lay = gi.LayoutVert

	graphtoolbar := gi.AddNewToolBar(mfr, "graphtoolbar")
	graphtoolbar.Viewport = vp
	graphtoolbar.SetStretchMaxWidth()
	playbtn := graphtoolbar.AddAction(gi.ActOpts{Label: "Play", Icon: "play"}, win.This(),
		func(recv, send ki.Ki, sig int64, data interface{}) {
			NewWin(vp)
		})
	playbtn.SetProp("margin", 0)
	playbtn.SetProp("padding", 0)

	scrow := gi.AddNewLayout(mfr, "scrow", gi.LayoutHoriz)
	scrow.SetStretchMax()

	scvw := gi3d.AddNewSceneView(scrow, "sceneview")
	scvw.SetStretchMax()
	scvw.Config()

	//scvw.Viewport.Render.Paint.DrawLine(&scvw.Viewport.Render, 2, 2, 20, 20)

	sc := scvw.Scene()

	// first, add lights, set camera
	sc.BgColor.SetUInt8(230, 230, 255, 255) // sky blue-ish
	gi3d.AddNewAmbientLight(sc, "ambient", 0.3, gi3d.DirectSun)

	dir := gi3d.AddNewDirLight(sc, "dir", 1, gi3d.DirectSun)
	dir.Pos.Set(0, 2, 1) // default: 0,1,1 = above and behind us (we are at 0,0,X)

	// point := gi3d.AddNewPointLight(sc, "point", 1, gi3d.DirectSun)
	// point.Pos.Set(0, 5, 5)

	// spot := gi3d.AddNewSpotLigjj

	// spot.Pose.Pos.Set(0, 5, 5)

	// circle := gi3d.AddNewCircle(sc, "cube", 1)
	// circleobj := gi3d.AddNewObject(sc, sc, "green-trans-cube", circle.Name())
	// circleobj.Pose.Pos.Set(0, 0, 1)
	// circleobj.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

	cbm := gi3d.AddNewBox(sc, "cube", 1, 1, 1)
	// cbm.Segs.Set(10, 10, 10) // not clear if any diff really..

	rbgp := gi3d.AddNewGroup(sc, sc, "r-b-group")

	rcb := gi3d.AddNewObject(sc, rbgp, "red-cube", cbm.Name())
	rcb.Pose.Pos.Set(-1, 0, 0)
	rcb.Mat.Color.SetName("red")
	rcb.Mat.Shiny = 500

	bcb := gi3d.AddNewObject(sc, rbgp, "blue-cube", cbm.Name())
	bcb.Pose.Pos.Set(1, 1, 0)
	bcb.Pose.Scale.X = 2
	bcb.Mat.Color.SetName("blue")
	bcb.Mat.Shiny = 10

	bcb.Mat.Specular.SetName("blue") // how you get rid of specular highlights

	gcb := gi3d.AddNewObject(sc, sc, "green-trans-cube", cbm.Name())
	gcb.Pose.Pos.Set(0, 0, 1)
	gcb.Mat.Color.SetUInt8(0, 255, 0, 128) // alpha = .5

	tcg := gi3d.AddNewGroup(sc, sc, "TrackCamera") // automatically tracks camera -- FPS effect
	fpgun := gi3d.AddNewObject(sc, tcg, "first-person-gun", cbm.Name())
	fpgun.Pose.Scale.Set(.1, .1, 1)
	fpgun.Pose.Pos.Set(.5, -.5, -2.5)          // in front of camera
	fpgun.Mat.Color.SetUInt8(255, 0, 255, 128) // alpha = .5

	grtx := gi3d.AddNewTextureFile(sc, "ground", "ground.png")
	//wdtx := gi3d.AddNewTextureFile(sc, "wood", "wood.png")

	floorp := gi3d.AddNewPlane(sc, "floor-plane", 10, 10)
	floor := gi3d.AddNewObject(sc, sc, "floor", floorp.Name())
	floor.Pose.Pos.Set(0, 0, 0)
	floor.Mat.Color.SetName("tan")
	floor.Mat.Emissive.SetName("brown")
	floor.Mat.Bright = 2 // .5 for wood / brown
	floor.Mat.SetTexture(sc, grtx)
	floor.Mat.Tiling.Repeat.Set(40, 40)

	txt := gi3d.AddNewText2D(sc, sc, "text", "Text2D 第三方can put <b>HTML</b> formatted<br>Text anywhere you might <i>want</i>")
	// 	txt.SetProp("background-color", gi.Color{0, 0, 0, 0}) // transparent -- default
	// txt.SetProp("background-color", "white")
	// txt.SetProp("color", "black") // default
	// txt.SetProp("margin", units.NewPt(4)) // default is 2 px
	// txt.Mat.Bright = 5 // no dim text -- key if using a background and want it to be bright..
	txt.Pose.Scale.SetScalar(0.2)
	txt.Pose.Pos.Set(0, 2.2, 0)

	sc.Camera.LookAt(mat32.Vec3Zero, mat32.Vec3Y) // defaults to looking at origin

	win.MainMenuUpdated()
	vp.UpdateEndNoSig(updt)
	win.GoStartEventLoop() // in a separate goroutine
	return win
}

rcoreilly avatar Dec 23 '19 09:12 rcoreilly

Thanks your attention.This is very useful. I got it.

runsys avatar Dec 23 '19 14:12 runsys

should not be an issue with vulkan in any case..

rcoreilly avatar Dec 25 '23 00:12 rcoreilly