func (app *MainApplication) loadGameTexture(id editormodel.TextureKey) {
	projectID := app.viewModel.SelectedProject()
	gameTextureKey := id.(editormodel.GameTextureKey)

	app.store.TextureBitmap(projectID, gameTextureKey.ID(), "large", func(bmp *model.RawBitmap) {
		pixelData, _ := base64.StdEncoding.DecodeString(bmp.Pixels)
		app.gameTextureStore.SetTexture(id, graphics.NewBitmapTexture(app.gl, bmp.Width, bmp.Height, pixelData))
	}, app.simpleStoreFailure("TextureBitmap"))
}
func (app *MainApplication) iconRetriever(id editormodel.ObjectID) graphics.BitmapRetriever {
	if app.gameObjectIconRetriever[id] == nil {
		projectID := app.viewModel.SelectedProject()

		app.gameObjectIconRetriever[id] = func() *graphics.BitmapTexture { return app.defaultIcon }

		app.store.GameObjectIcon(projectID, id.Class(), id.Subclass(), id.Type(),
			func(raw *model.RawBitmap) {
				bmp := graphics.BitmapFromRaw(*raw)
				bitmap := graphics.NewBitmapTexture(app.gl, bmp.Width, bmp.Height, bmp.Pixels)
				app.gameObjectIcons[id] = bitmap
				app.gameObjectIconRetriever[id] = func() *graphics.BitmapTexture { return bitmap }
			}, app.simpleStoreFailure("GameObjectIcon"))
	}

	return func() *graphics.BitmapTexture { return app.gameObjectIconRetriever[id]() }
}
func (renderable *TextRenderable) updateBitmap() {
	if renderable.bitmapTexture != nil {
		renderable.bitmapTexture.Dispose()
		renderable.bitmapTexture = nil
	}
	if renderable.textRenderer != nil {
		textBitmap := renderable.textRenderer.Render(renderable.text)
		renderable.bitmapTexture = graphics.NewBitmapTexture(renderable.gl, textBitmap.Width, textBitmap.Height, textBitmap.Pixels)

		renderable.withShader(func() {
			gl := renderable.gl
			width := float32(textBitmap.Width)
			height := float32(textBitmap.Height)
			var vertices = []float32{
				0.0, 0.0, 0.0,
				width, 0.0, 0.0,
				width, height, 0.0,

				width, height, 0.0,
				0.0, height, 0.0,
				0.0, 0.0, 0.0}
			gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.vertexPositionBuffer)
			gl.BufferData(opengl.ARRAY_BUFFER, len(vertices)*4, vertices, opengl.STATIC_DRAW)

			limit := float32(1.0)
			var uv = []float32{
				0.0, 0.0, 0.0,
				limit, 0.0, 0.0,
				limit, limit, 0.0,

				limit, limit, 0.0,
				0.0, limit, 0.0,
				0.0, 0.0, 0.0}
			gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.uvPositionBuffer)
			gl.BufferData(opengl.ARRAY_BUFFER, len(uv)*4, uv, opengl.STATIC_DRAW)
		})
	}
}
func (app *MainApplication) onSelectedProjectChanged(projectID string) {
	app.updateViewModel(func() {
		app.viewModel.SetLevels(nil)
		app.viewModel.SetTextureCount(0)
	})

	if app.tileTextureMapRenderable != nil {
		app.tileTextureMapRenderable.Dispose()
		app.tileTextureMapRenderable = nil
	}
	if app.tileGridMapRenderable != nil {
		app.tileGridMapRenderable.Dispose()
		app.tileGridMapRenderable = nil
	}
	if app.paletteTexture != nil {
		app.paletteTexture.Dispose()
		app.paletteTexture = nil
	}
	app.gameObjectIconRetriever = make(map[editormodel.ObjectID]graphics.BitmapRetriever)
	for _, texture := range app.gameObjectIcons {
		texture.Dispose()
	}
	app.gameObjectIcons = make(map[editormodel.ObjectID]*graphics.BitmapTexture)
	app.textureData = nil
	app.gameTextureStore.Reset()
	app.levels = nil

	if projectID != "" {
		app.store.Font(projectID, 0x025B, func(font *model.Font) {
			app.defaultFont = graphics.NewBitmapTextRenderer(*font)
			bmp := app.defaultFont.Render("?")
			app.defaultIcon = graphics.NewBitmapTexture(app.gl, bmp.Width, bmp.Height, bmp.Pixels)
		}, app.simpleStoreFailure("Font"))

		app.store.Palette(projectID, "game", func(colors [256]model.Color) {
			colorProvider := func(index int) (byte, byte, byte, byte) {
				entry := &colors[app.animatedPaletteIndex(index)]
				return byte(entry.Red), byte(entry.Green), byte(entry.Blue), 255
			}
			app.paletteTexture = graphics.NewPaletteTexture(app.gl, colorProvider)
			app.tileGridMapRenderable = display.NewTileGridMapRenderable(app.gl)

			app.simpleBitmapRenderable = display.NewSimpleBitmapRenderable(app.gl, app.paletteTexture)
		}, app.simpleStoreFailure("Palette"))

		app.store.Textures(projectID, func(textures []model.Texture) {
			app.textureData = textures
			app.updateViewModel(func() {
				app.viewModel.SetTextureCount(len(textures))
			})
		}, app.simpleStoreFailure("Textures"))

		app.store.Levels(projectID, "archive", func(levels []model.Level) {
			levelIDs := make([]string, len(levels))
			for index, level := range levels {
				levelIDs[index] = level.ID
			}
			app.levels = levels
			app.updateViewModel(func() {
				app.viewModel.SetLevels(levelIDs)
			})
		}, app.simpleStoreFailure("Levels"))
	}
}