Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow text rendering? #21

Closed
JohnEmhoff opened this issue Dec 2, 2019 · 3 comments
Closed

Slow text rendering? #21

JohnEmhoff opened this issue Dec 2, 2019 · 3 comments

Comments

@JohnEmhoff
Copy link

Hello! I have a somewhat text-heavy use case and I think I'm noticing that text rendering seems to be pretty slow -- with a couple hundred characters on the screen I get about 20fps and it only goes down from there.

I glanced through the code and it seems it's building up a bitmap of the text to draw every frame with image.Draw, and then copying that to the destination buffer. Is that right? Is there some caching or a fast-path somewhere I can exploit?

@tfriedel6
Copy link
Owner

Hi, yes that is how it works. Currently there isn't any caching mechanism. It might be worth considering since it can be a common use case to draw the same strings every frame, but for now I have not planned it.

One thing you can try is to use separate canvases for text caching. Here is an example:

package main

import (
	"github.com/tfriedel6/canvas"
	"github.com/tfriedel6/canvas/backend/goglbackend"
	"github.com/tfriedel6/canvas/sdlcanvas"
)

func main() {
	wnd, cv, err := sdlcanvas.CreateWindow(1280, 720, "Canvas Test")
	if err != nil {
		panic(err)
	}
	defer wnd.Destroy()

	backend, err := goglbackend.NewOffscreen(110, 60, true, nil)
	if err != nil {
		panic(err)
	}
	cv2 := canvas.New(backend)

	cv2.SetFillStyle("#FFF")
	cv2.SetFont("_testapp/Roboto-Light.ttf", 40)
	cv2.FillText("hello", 10, 50)

	wnd.MainLoop(func() {
		cv.ClearRect(0, 0, 1280, 720)
		cv.DrawImage(cv2, 50, 50)
		cv.DrawImage(cv2, 50, 100)
	})
}

The offscreen canvas should be used directly in the DrawImage call, so it should be quite fast. However if you need to render different strings every frame it will not work.

@JohnEmhoff
Copy link
Author

Thanks, that's very helpful! Most of my text is static but not all of it, and zoom levels change pretty frequently -- I think I'm going to see if I can look into drawing text using a font atlas.

If I start interspersing calls to opengl (e.g., changing current texture, vertex lists, and shaders), what do I need to do to play nicely with and not step on any state that your library depends on?

@tfriedel6
Copy link
Owner

The shaders, textures, and buffers should be set as they are needed, so that shouldn't be a problem, I think. The stencil buffer settings are also set as needed, but stencil testing needs to be enabled for it to work. Similarly, the blend modes need to be kept, the depth buffer and depth testing should be disabled, and back face culling as well. Otherwise I can't think of anything right now. I think it should work, but I keep getting surprised by some aspects of OpenGL, so I might be missing something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants