xlab / android-go

The android-go project provides a platform for writing native Android apps in Go programming language.
https://developer.android.com/ndk/index.html
MIT License
1.07k stars 79 forks source link

EGL bug. Opengl ES version Mismatch #24

Closed darmie closed 6 years ago

darmie commented 6 years ago

I am trying to Port Nanovgo example to Android using andrioid-go and EGL

I modified Nanovgo to support GLES2 library from https://github.com/xlab/android-go/tree/master/gles2 , see modified version here nanovgo-gles

func init() {
    app.SetLogTag("GolangExample")
    // Initialise gl bindings using the current context.
    // err := gl.Init()
    // if err != nil {
    //  log.Fatalln("gl.Init:", err)
    // }
}

func main() {
    log.Println("NativeActivity has started ^_^")
    log.Printf("Platform: %s %s", runtime.GOOS, runtime.GOARCH)
    nativeWindowEvents := make(chan app.NativeWindowEvent)
    var displayHandle *egl.DisplayHandle
    ctx, err := nanovgo.NewContext(0)
    if err != nil {
        panic(err)
    }

    //demoData = LoadDemo(ctx)
    app.Main(func(a app.NativeActivity) {
        a.HandleNativeWindowEvents(nativeWindowEvents)
        a.InitDone()
        for {
            select {
            case event := <-a.LifecycleEvents():
                switch event.Kind {
                case app.OnCreate:
                    log.Println(event.Kind, "handled")
                default:
                    log.Println(event.Kind, "event ignored")
                }
            case event := <-nativeWindowEvents:
                switch event.Kind {
                case app.NativeWindowRedrawNeeded:
                    a.NativeWindowRedrawDone()
                    draw(displayHandle, ctx)
                    log.Println(event.Kind, "handled")
                case app.NativeWindowCreated:
                    expectedSurface := map[int32]int32{
                        egl.SurfaceType: egl.WindowBit,
                        egl.RedSize:     8,
                        egl.GreenSize:   8,
                        egl.BlueSize:    8,
                    }
                    if handle, err := egl.NewDisplayHandle(event.Window, expectedSurface); err != nil {
                        log.Fatalln("EGL error:", err)
                    } else {
                        displayHandle = handle
                        log.Printf("EGL display res: %dx%d", handle.Width, handle.Height)
                    }
                    initGL()
                case app.NativeWindowDestroyed:
                    displayHandle.Destroy()
                default:
                    log.Println(event.Kind, "event ignored")
                    //demoData.FreeData(ctx)
                }
            }
        }
    })
}

func initGL() {
    gl.Enable(gl.BLEND)
    gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
    gl.Enable(gl.CULL_FACE)
    gl.Disable(gl.DEPTH_TEST)
}

func draw(handle *egl.DisplayHandle, ctx *nanovgo.Context) {
    fmt.Println("draw")
    //fps := perfgraph.NewPerfGraph("Frame Time", "sans")

    //t, _ := fps.UpdateGraph()

    pixelRatio := float32(handle.Width) / float32(handle.Height)

    gl.Viewport(0, 0, int32(handle.Width), int32(handle.Height))
    fmt.Println("view port")

    gl.ClearColor(0, 0, 0, 0)
    fmt.Println("clear color")

    gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

    ctx.BeginFrame(int32(handle.Width), int32(handle.Height), pixelRatio)
    fmt.Println("begin frame")

    demo.RenderDemo(ctx, 0, 0, 300, 600, 0, false, &demo.DemoData{})

    //fps.RenderGraph(ctx, 5, 5)

    ctx.EndFrame()

    //gl.Enable(gl.DEPTH_TEST)

    //glfw.PollEvents()

    handle.SwapBuffers()

}

demo.go :

func RenderDemo(ctx *nanovgo.Context, mx, my, width, height, t float32, blowup bool, data *DemoData) {
    // Widgets
    drawWindow(ctx, "Widgets `n Stuff", 50, 50, 300, 400)
    var x float32 = 60.0
    var y float32 = 95.0
    fmt.Println("Draw Window")
    drawSearchBox(ctx, "Search", x, y, 280, 25)
    y += 40
    fmt.Println("Draw Search")
    drawDropDown(ctx, "Effects", x, y, 280, 28)
    //popy := y + 14
    y += 45
    fmt.Println("Draw DropDown")
    // Form
    drawLabel(ctx, "Login", x, y, 280, 20)
    y += 25
    fmt.Println("Draw Label")
    drawEditBox(ctx, "Email", x, y, 280, 28)
    y += 35
    fmt.Println("Draw Edit Box")
    drawEditBox(ctx, "Password", x, y, 280, 28)
    y += 38
    fmt.Println("Draw Password")
    drawCheckBox(ctx, "Remember me", x, y, 140, 28)
    fmt.Println("Draw  Checkbox")
    drawButton(ctx, IconLOGIN, "Sign in", x+138, y, 140, 28, nanovgo.RGBA(0, 96, 128, 255))
    y += 45
    fmt.Println("Draw Button")

    // Slider
    drawLabel(ctx, "Diameter", x, y, 280, 20)
    y += 25
    drawEditBoxNum(ctx, "123.00", "px", x+180, y, 100, 28)
    drawSlider(ctx, 0.4, x, y, 170, 28)
    y += 55

    drawButton(ctx, IconTRASH, "Delete", x, y, 160, 28, nanovgo.RGBA(128, 16, 8, 255))
    drawButton(ctx, 0, "Cancel", x+170, y, 110, 28, nanovgo.RGBA(0, 0, 0, 0))

    fmt.Println("finished rendering")
    // Thumbnails box
    //drawThumbnails(ctx, 365, popy-30, 160, 300, data.Images, t)
}

BUG:

i am getting a blank screen with these errors

06-08 11:37:00.885 23648-23666/? I/GolangExample: NativeActivity has started ^_^
06-08 11:37:00.885 23648-23666/? I/GolangExample: Platform: android arm
06-08 11:37:00.887 23648-23666/? I/GolangExample: Shader shader/vert error:
06-08 11:37:00.888 23648-23667/? I/GolangExample: onCreate handled
06-08 11:37:00.890 23648-23666/? I/GolangExample: onStart event ignored
06-08 11:37:00.893 23648-23666/? I/GolangExample: onResume event ignored
06-08 11:37:00.894 23648-23648/? D/ActivityThread: EYE startEyeVerifyBroadcast packagename=com.go_android.minimal; ClassName=android.app.NativeActivity
06-08 11:37:00.903 23648-23648/? V/PhoneWindow: DecorView setVisiblity: visibility = 4, Parent = null, this = DecorView@2359018[],statusBarBackground visible =false,statusColor: 0xff000000->
06-08 11:37:00.919 23648-23648/? D/WindowClient: Add to mViews: DecorView@2359018[NativeActivity], this = android.view.WindowManagerGlobal@4cddbcf
06-08 11:37:00.934 23648-23648/? V/PhoneWindow: DecorView setVisiblity: visibility = 0, Parent = ViewRoot{5b9d95c com.go_android.minimal/android.app.NativeActivity,ident = 0}, this = DecorView@2359018[NativeActivity],statusBarBackground visible =false,statusColor: 0xff000000->
06-08 11:37:00.968 23648-23648/? I/lulingjie--screenshot--observer--: observer is rigistedDecorView@2359018[NativeActivity]
06-08 11:37:00.994 23648-23648/? V/InputMethodManager: onWindowFocus: null softInputMode=272 first=true flags=#10100
06-08 11:37:01.027 23648-23666/? D/Surface: Surface::setBuffersUserDimensions(this=0xe663a000,w=0,h=0)
06-08 11:37:01.040 23648-23666/? D/Surface: Surface::connect(this=0xe663a000,api=1)
06-08 11:37:01.042 23648-23666/? W/libEGL: [ANDROID_RECORDABLE] format: 2
06-08 11:37:01.047 23648-23666/? D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000
06-08 11:37:01.051 23648-23666/? I/GolangExample: EGL display res: 640x1070
06-08 11:37:01.052 23648-23664/? I/GolangExample: draw
06-08 11:37:01.052 23648-23664/? I/GolangExample: view port
06-08 11:37:01.052 23648-23664/? I/GolangExample: clear color
06-08 11:37:01.066 23648-23666/? D/GraphicBuffer: register, handle(0xe91913c0) (w:640 h:1070 s:640 f:0x2 u:0x000b00)
06-08 11:37:01.068 23648-23664/? I/GolangExample: begin frame
06-08 11:37:01.068 23648-23664/? I/GolangExample: Draw Window
06-08 11:37:01.068 23648-23664/? I/GolangExample: Draw Search
06-08 11:37:01.069 23648-23664/? I/GolangExample: Draw DropDown
06-08 11:37:01.069 23648-23664/? I/GolangExample: Draw Label
06-08 11:37:01.069 23648-23664/? I/GolangExample: Draw Edit Box
06-08 11:37:01.069 23648-23664/? I/GolangExample: Draw Password
06-08 11:37:01.069 23648-23664/? I/GolangExample: Draw  Checkbox
06-08 11:37:01.070 23648-23664/? I/GolangExample: Draw Button
06-08 11:37:01.070 23648-23666/? D/MALI: gles_state_set_error_internal:75: [MALI] GLES ctx: 0xa6680008, error code:0x502
06-08 11:37:01.070 23648-23666/? D/MALI: gles_state_set_error_internal:76: [MALI] GLES error info: OpenGL ES API version mismatch
xlab commented 6 years ago

@darmie thanks for mentioning me by X-Lab, this spelling brings some nostalgia, I used it ~12 years ago :)

As for your problem, I think you copied EGL/GLES context initialization of GLES 1.0..

See https://github.com/golang-ui/nuklear/blob/master/nk/impl_android_gles2.go#L107 for GLES 2 and https://github.com/golang-ui/nuklear/blob/master/nk/impl_android_gles3.go#L36 for examples on how to init GLES 2/ GLES 3 surfaces.

E.g.

display, err := egl.NewDisplayHandle(win, map[int32]int32{
        egl.SurfaceType:          egl.WindowBit,
        egl.ContextClientVersion: 2.0, // OpenGL ES 2.0

        egl.RedSize:   8,
        egl.GreenSize: 8,
        egl.BlueSize:  8,
        egl.AlphaSize: 8,
        egl.DepthSize: 24,
    })
    if err != nil {
        log.Println("Platform init failed:", err)
        return nil
    }
    if (int)(C.init_ext()) != 0 {
        log.Println("GL ES 2.0 extensions load failed:", err)
        return nil
    }
darmie commented 6 years ago

Thank you. I just did that and it was resolved. But I am getting new errors:

06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:75: [MALI] GLES ctx: 0xa6780008, error code:0x502
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:76: [MALI] GLES error info: the reserved buffer object 0 is bound to <target>
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:75: [MALI] GLES ctx: 0xa6780008, error code:0x502
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:76: [MALI] GLES error info: there is no current program object
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:75: [MALI] GLES ctx: 0xa6780008, error code:0x502
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:76: [MALI] GLES error info: there is no current program object
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:75: [MALI] GLES ctx: 0xa6780008, error code:0x502
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:76: [MALI] GLES error info: there is no current program object
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:75: [MALI] GLES ctx: 0xa6780008, error code:0x502
06-08 14:14:34.779 23381-23401/com.go_android.minimal D/MALI: gles_state_set_error_internal:76: [MALI] GLES error info: there is no current program object
xlab commented 6 years ago

@darmie NanoVG is originally for OpenGL, I guess there is an incompatible call in the GL code, you need to search the error in google and understand why it fails for GLESv3.

darmie commented 6 years ago

@xlab the readme on the original NanoVG page says it's backend supports OpenGL ES 2 and 3 However, maybe the problem is from Nanovgo the Golang port.

Thanks for your help so far, I'll keep looking, and would post the solution here if I find any.

darmie commented 6 years ago

@xlab So I realized that the problem is from the shader. The shader is not compiling

This is my shader:

# version 300
uniform vec2 viewSize;
in vec2 vertex;
in vec2 tcoord;
out vec2 ftcoord;
out vec2 fpos;

void main(void) {
   ftcoord = tcoord;
   fpos = vertex;
   gl_Position = vec4(2.0*vertex.x/viewSize.x - 1.0, 1.0 - 2.0*vertex.y/viewSize.y, 0, 1);
}
func (s *glShader) createShader(name, header, opts, vShader, fShader string) error {
    program := gl.CreateProgram()

    vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
    mShader := strings.Join([]string{opts, vShader}, "\x00")
    fmt.Println(mShader)
    gl.ShaderSource(vertexShader, 1, []string{mShader + "\x00"}, nil)
    gl.CompileShader(vertexShader)
    var status int32
    gl.GetShaderiv(vertexShader, gl.COMPILE_STATUS, &status)
    if status != gl.TRUE {
        fmt.Println("vertex shader status", status)
        return dumpShaderError(vertexShader, name, "vert")
    }
}

Error Log:

06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: # version 300 es
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: uniform vec2 viewSize;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: in vec2 vertex;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: in vec2 tcoord;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: out vec2 ftcoord;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: out vec2 fpos;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: void main(void) {
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample:    ftcoord = tcoord;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample:    fpos = vertex;
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample:    gl_Position = vec4(2.0*vertex.x/viewSize.x - 1.0, 1.0 - 2.0*vertex.y/viewSize.y, 0, 1);
06-08 20:03:03.624 10771-10789/com.go_android.minimal I/GolangExample: }
06-08 20:03:03.625 10771-10791/com.go_android.minimal I/GolangExample: Shader shader/vert error:
06-08 20:03:03.626 10771-10789/com.go_android.minimal I/GolangExample: vertex shader status 0

vertex shader status is supposed to be equals to 1 if the shader compiled properly

06-08 21:10:52.641 6524-6559/com.go_android.minimal I/Adreno: ERROR: 0:5: ':' : Syntax error:  syntax error
                                                              INTERNAL ERROR: no main() function!
                                                              ERROR: 1 compilation errors.  No code generated.