Compare commits

..

7 Commits

Author SHA1 Message Date
Bertrand Jung
804f024424
Merge 1dd96726c4 into b131264c77 2024-08-21 19:52:40 +08:00
Hajime Hoshi
b131264c77 text/v2: add comments 2024-08-20 21:06:27 +09:00
Hajime Hoshi
35f9b1c224 ebiten: add RunGameOptions.DisableHiDPI
Closes #2987
2024-08-20 00:02:57 +09:00
Hajime Hoshi
789388618d all: add playstation5 dummy package 2024-08-18 11:54:48 +09:00
Hajime Hoshi
ba1af60480 all: update comments 2024-08-18 11:14:25 +09:00
Hajime Hoshi
8f32cc19c5 audio: update comments 2024-08-18 11:13:35 +09:00
Hajime Hoshi
48f79af884 shaderprecomp: retract shaderprecomp package
With #2984, we realized some considerations:

* Builtin shaders don't have to or should not be exposed.
* The shader complation processes like what the examples/shaderprecomp
  does can be provided by this package

Thus, until we decide a better API design, we'd like to retract the
package once.

Updates #2861
2024-08-18 11:09:16 +09:00
22 changed files with 51 additions and 660 deletions

View File

@ -14,15 +14,14 @@
// Package audio provides audio players.
//
// The stream format must be 16-bit little endian and 2 channels. The format is as follows:
// The stream format must be 16-bit little endian or 32-bit float little endian, and 2 channels. The format is as follows:
//
// [data] = [sample 1] [sample 2] [sample 3] ...
// [sample *] = [channel 1] ...
// [channel *] = [byte 1] [byte 2] ...
//
// An audio context (audio.Context object) has a sample rate you can specify and all streams you want to play must have the same
// sample rate. However, decoders in e.g. audio/mp3 package adjust sample rate automatically,
// and you don't have to care about it as long as you use those decoders.
// An audio context (audio.Context object) has a sample rate you can specify
// and all streams you want to play must have the same sample rate.
//
// An audio context can generate 'players' (audio.Player objects),
// and you can play sound by calling Play function of players.

View File

@ -20,7 +20,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/affine"
)
// ColorMDim is a dimension of a ColorM.
// ColorMDim is the dimension of a ColorM.
//
// Deprecated: as of v2.5. Use the colorm package instead.
const ColorMDim = affine.ColorMDim

View File

@ -24,7 +24,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/builtinshader"
)
// Dim is a dimension of a ColorM.
// Dim is the dimension of a ColorM.
const Dim = affine.ColorMDim
// ColorM represents a matrix to transform coloring when rendering an image.

View File

@ -15,9 +15,11 @@
package main
import (
"flag"
"fmt"
_ "image/jpeg"
"log"
"runtime"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
@ -93,7 +95,16 @@ func (g *Game) Draw(screen *ebiten.Image) {
op.Filter = ebiten.FilterLinear
screen.DrawImage(g.highDPIImage, op)
ebitenutil.DebugPrint(screen, fmt.Sprintf("(Init) Device Scale Ratio: %0.2f", scale))
msg := fmt.Sprintf("Device Scale Ratio: %0.2f", scale)
if runtime.GOOS == "js" {
if !*flagDisable {
msg += "\nHiDPI rendering is enabled. You can disable HiDPI by -disable flag."
} else {
msg += "\nHiDPI rendering is disabled."
}
}
// TODO: The texts might be too small. Improve legibility.
ebitenutil.DebugPrint(screen, msg)
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
@ -103,10 +114,16 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return int(float64(outsideWidth) * s), int(float64(outsideHeight) * s)
}
var flagDisable = flag.Bool("disable", false, "disables HiDPI rendering (only on browsers)")
func main() {
flag.Parse()
ebiten.SetWindowSize(640, 480)
ebiten.SetWindowTitle("High DPI (Ebitengine Demo)")
if err := ebiten.RunGame(NewGame()); err != nil {
op := &ebiten.RunGameOptions{}
op.DisableHiDPI = *flagDisable
if err := ebiten.RunGameWithOptions(NewGame(), op); err != nil {
log.Fatal(err)
}
}

View File

@ -1,33 +0,0 @@
// Copyright 2020 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build ignore
//kage:unit pixels
package main
var Time float
var Cursor vec2
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
pos := (dstPos.xy - imageDstOrigin()) / imageDstSize()
pos += Cursor / imageDstSize() / 4
clr := 0.0
clr += sin(pos.x*cos(Time/15)*80) + cos(pos.y*cos(Time/15)*10)
clr += sin(pos.y*sin(Time/10)*40) + cos(pos.x*sin(Time/25)*40)
clr += sin(pos.x*sin(Time/5)*10) + sin(pos.y*sin(Time/35)*80)
clr *= sin(Time/10) * 0.5
return vec4(clr, clr*0.5, sin(clr+Time/3)*0.75, 1)
}

View File

@ -1 +0,0 @@
This is a dummy .fxc file to trick Go's embed package.

View File

@ -1,132 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build ignore
// This is a program to generate precompiled HLSL blobs (FXC files).
//
// See https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc.
package main
import (
"bufio"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/hajimehoshi/ebiten/v2/shaderprecomp"
)
func main() {
if err := run(); err != nil {
panic(err)
}
}
func run() error {
if _, err := exec.LookPath("fxc.exe"); err != nil {
if errors.Is(err, exec.ErrNotFound) {
fmt.Fprintln(os.Stderr, "fxc.exe not found. Please install Windows SDK.")
fmt.Fprintln(os.Stderr, "See https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc for more details.")
fmt.Fprintln(os.Stderr, "HINT: On PowerShell, you can add a path to the PATH environment variable temporarily like:")
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, ` & (Get-Process -Id $PID).Path { $env:PATH="C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64;"+$env:PATH; go generate .\examples\shaderprecomp\fxc\ }`)
fmt.Fprintln(os.Stderr)
os.Exit(1)
}
return err
}
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
return err
}
defer os.RemoveAll(tmpdir)
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
defaultSrcBytes, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
if err != nil {
return err
}
srcs = append(srcs, shaderprecomp.NewShaderSource(defaultSrcBytes))
for i, src := range srcs {
// Avoid using errgroup.Group.
// Compiling sources in parallel causes a mixed error message on the console.
if err := compile(src, i, tmpdir); err != nil {
return err
}
}
return nil
}
func generateHSLSFiles(source *shaderprecomp.ShaderSource, index int, tmpdir string) (vs, ps string, err error) {
vsHLSLFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d_vs.hlsl", index))
vsf, err := os.Create(vsHLSLFilePath)
if err != nil {
return "", "", err
}
defer vsf.Close()
psHLSLFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d_ps.hlsl", index))
psf, err := os.Create(psHLSLFilePath)
if err != nil {
return "", "", err
}
defer psf.Close()
vsfw := bufio.NewWriter(vsf)
psfw := bufio.NewWriter(psf)
if err := shaderprecomp.CompileToHLSL(vsfw, psfw, source); err != nil {
return "", "", err
}
if err := vsfw.Flush(); err != nil {
return "", "", err
}
if err := psfw.Flush(); err != nil {
return "", "", err
}
return vsHLSLFilePath, psHLSLFilePath, nil
}
func compile(source *shaderprecomp.ShaderSource, index int, tmpdir string) error {
// Generate HLSL files. Make sure this process doesn't have any handlers of the files.
// Without closing the files, fxc.exe cannot access the files.
vsHLSLFilePath, psHLSLFilePath, err := generateHSLSFiles(source, index, tmpdir)
if err != nil {
return err
}
vsFXCFilePath := fmt.Sprintf("%d_vs.fxc", index)
cmd := exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLVertexShaderProfile, "/E", shaderprecomp.HLSLVertexShaderEntryPoint, "/Fo", vsFXCFilePath, vsHLSLFilePath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
psFXCFilePath := fmt.Sprintf("%d_ps.fxc", index)
cmd = exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLPixelShaderProfile, "/E", shaderprecomp.HLSLPixelShaderEntryPoint, "/Fo", psFXCFilePath, psHLSLFilePath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}

View File

@ -1,19 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
//go:generate go run gen.go
package fxc

View File

@ -1,74 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
_ "embed"
"log"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)
//go:embed defaultshader.go
var defaultShaderSourceBytes []byte
type Game struct {
defaultShader *ebiten.Shader
counter int
}
func (g *Game) Update() error {
g.counter++
if g.defaultShader == nil {
s, err := ebiten.NewShader(defaultShaderSourceBytes)
if err != nil {
return err
}
g.defaultShader = s
}
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
cx, cy := ebiten.CursorPosition()
w, h := screen.Bounds().Dx(), screen.Bounds().Dy()
op := &ebiten.DrawRectShaderOptions{}
op.Uniforms = map[string]interface{}{
"Time": float32(g.counter) / float32(ebiten.TPS()),
"Cursor": []float32{float32(cx), float32(cy)},
}
screen.DrawRectShader(w, h, g.defaultShader, op)
msg := `This is a test for shader precompilation.
Precompilation works only on macOS so far.
Note that this example still works even without shader precompilation.`
ebitenutil.DebugPrint(screen, msg)
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return outsideWidth, outsideHeight
}
func main() {
if err := registerPrecompiledShaders(); err != nil {
log.Fatal(err)
}
ebiten.SetWindowTitle("Ebitengine Example (Shader Precompilation)")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}

View File

@ -1 +0,0 @@
This is a dummy .metallib file to trick Go's embed package.

View File

@ -1,95 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build ignore
// This is a program to generate precompiled Metal libraries.
//
// See https://developer.apple.com/documentation/metal/shader_libraries/building_a_shader_library_by_precompiling_source_files.
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/hajimehoshi/ebiten/v2/shaderprecomp"
)
func main() {
if err := run(); err != nil {
panic(err)
}
}
func run() error {
tmpdir, err := os.MkdirTemp("", "")
if err != nil {
return err
}
defer os.RemoveAll(tmpdir)
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
defaultSrcBytes, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
if err != nil {
return err
}
srcs = append(srcs, shaderprecomp.NewShaderSource(defaultSrcBytes))
for i, src := range srcs {
// Avoid using errgroup.Group.
// Compiling sources in parallel causes a mixed error message on the console.
if err := compile(src, i, tmpdir); err != nil {
return err
}
}
return nil
}
func compile(source *shaderprecomp.ShaderSource, index int, tmpdir string) error {
metalFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d.metal", index))
f, err := os.Create(metalFilePath)
if err != nil {
return err
}
defer f.Close()
w := bufio.NewWriter(f)
if err := shaderprecomp.CompileToMSL(w, source); err != nil {
return err
}
if err := w.Flush(); err != nil {
return err
}
irFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d.ir", index))
cmd := exec.Command("xcrun", "-sdk", "macosx", "metal", "-o", irFilePath, "-c", metalFilePath)
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
metallibFilePath := fmt.Sprintf("%d.metallib", index)
cmd = exec.Command("xcrun", "-sdk", "macosx", "metallib", "-o", metallibFilePath, irFilePath)
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}

View File

@ -1,48 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"embed"
"errors"
"fmt"
"io/fs"
"os"
"github.com/hajimehoshi/ebiten/v2/shaderprecomp"
)
//go:embed metallib/*.metallib
var metallibs embed.FS
func registerPrecompiledShaders() error {
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
srcs = append(srcs, shaderprecomp.NewShaderSource(defaultShaderSourceBytes))
for i, src := range srcs {
name := fmt.Sprintf("%d.metallib", i)
lib, err := metallibs.ReadFile("metallib/" + name)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
fmt.Fprintf(os.Stderr, "precompiled Metal library %s was not found. Run 'go generate' for 'metallib' directory to generate them.\n", name)
continue
}
return err
}
shaderprecomp.RegisterMetalLibrary(src, lib)
}
return nil
}

View File

@ -1,27 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !darwin && !windows
package main
import (
"fmt"
"os"
)
func registerPrecompiledShaders() error {
fmt.Fprintf(os.Stderr, "precompiled shaders are not available in this environment.\n")
return nil
}

View File

@ -1,61 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"embed"
"errors"
"fmt"
"io/fs"
"os"
"github.com/hajimehoshi/ebiten/v2/shaderprecomp"
)
// https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
//go:embed fxc/*.fxc
var fxcs embed.FS
func registerPrecompiledShaders() error {
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
srcs = append(srcs, shaderprecomp.NewShaderSource(defaultShaderSourceBytes))
for i, src := range srcs {
vsname := fmt.Sprintf("%d_vs.fxc", i)
vs, err := fxcs.ReadFile("fxc/" + vsname)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
fmt.Fprintf(os.Stderr, "precompiled HLSL library %s was not found. Run 'go generate' for 'fxc' directory to generate them.\n", vsname)
continue
}
return err
}
psname := fmt.Sprintf("%d_ps.fxc", i)
ps, err := fxcs.ReadFile("fxc/" + psname)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
fmt.Fprintf(os.Stderr, "precompiled HLSL library %s was not found. Run 'go generate' for 'fxc' directory to generate them.\n", psname)
continue
}
return err
}
shaderprecomp.RegisterFXCs(src, vs, ps)
}
return nil
}

View File

@ -175,6 +175,7 @@ type RunOptions struct {
ScreenTransparent bool
SkipTaskbar bool
SingleThread bool
DisableHiDPI bool
X11ClassName string
X11InstanceName string
}

View File

@ -96,6 +96,7 @@ type userInterfaceImpl struct {
cursorShape CursorShape
onceUpdateCalled bool
lastCaptureExitTime time.Time
hiDPIEnabled bool
context *context
inputState InputState
@ -465,6 +466,7 @@ func (u *UserInterface) init() error {
runnableOnUnfocused: true,
savedCursorX: math.NaN(),
savedCursorY: math.NaN(),
hiDPIEnabled: true,
}
// document is undefined on node.js
@ -762,6 +764,8 @@ func (u *UserInterface) shouldFocusFirst(options *RunOptions) bool {
func (u *UserInterface) initOnMainThread(options *RunOptions) error {
u.setRunning(true)
u.hiDPIEnabled = !options.DisableHiDPI
if u.shouldFocusFirst(options) {
canvas.Call("focus")
}
@ -815,6 +819,10 @@ func (m *Monitor) Name() string {
}
func (m *Monitor) DeviceScaleFactor() float64 {
if !theUI.hiDPIEnabled {
return 1
}
if m.deviceScaleFactor != 0 {
return m.deviceScaleFactor
}

View File

@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build darwin
//go:build playstation5
//go:generate go run gen.go
// Package playstation5 provides utilities for PlayStation 5.
package playstation5
package metallib
// The actual implementation will be provided by another repository using the -overlay option.

10
run.go
View File

@ -274,6 +274,15 @@ type RunGameOptions struct {
// The default (zero) value is false, which means that the single thread mode is disabled.
SingleThread bool
// DisableHiDPI indicates whether the rendering for HiDPI is disabled or not.
// If HiDPI is disabled, the device scale factor is always 1 i.e. Monitor's DeviceScaleFactor always returns 1.
// This is useful to get a better performance on HiDPI displays, in the expense of rendering quality.
//
// DisableHiDPI is available only on browsers.
//
// The default (zero) value is false, which means that HiDPI is enabled.
DisableHiDPI bool
// X11DisplayName is a class name in the ICCCM WM_CLASS window property.
X11ClassName string
@ -703,6 +712,7 @@ func toUIRunOptions(options *RunGameOptions) *ui.RunOptions {
ScreenTransparent: options.ScreenTransparent,
SkipTaskbar: options.SkipTaskbar,
SingleThread: options.SingleThread,
DisableHiDPI: options.DisableHiDPI,
X11ClassName: options.X11ClassName,
X11InstanceName: options.X11InstanceName,
}

View File

@ -1,43 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shaderprecomp
import (
"github.com/hajimehoshi/ebiten/v2/internal/builtinshader"
)
// AppendBuildinShaderSources appends all the built-in shader sources to the given slice.
//
// Do not modify the content of the shader source.
//
// AppendBuildinShaderSources is concurrent-safe.
func AppendBuildinShaderSources(sources []*ShaderSource) []*ShaderSource {
for _, s := range builtinshader.AppendShaderSources(nil) {
sources = append(sources, NewShaderSource(s))
}
return sources
}
// ShaderSource is an object encapsulating a shader source code.
type ShaderSource struct {
source []byte
}
// NewShaderSource creates a new ShaderSource object from the given source code.
func NewShaderSource(source []byte) *ShaderSource {
return &ShaderSource{
source: source,
}
}

View File

@ -1,48 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !playstation5
package shaderprecomp
import (
"io"
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal"
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/msl"
)
// CompileToMSL compiles the shader source to Metal Shader Language, and writes the result to w.
//
// CompileToMSL is concurrent-safe.
func CompileToMSL(w io.Writer, source *ShaderSource) error {
ir, err := graphics.CompileShader(source.source)
if err != nil {
return err
}
if _, err = w.Write([]byte(msl.Compile(ir))); err != nil {
return err
}
return nil
}
// RegisterMetalLibrary registers a precompiled Metal library for a shader source.
// library must be the content of a .metallib file.
// For more details, see https://developer.apple.com/documentation/metal/shader_libraries/building_a_shader_library_by_precompiling_source_files.
//
// RegisterMetalLibrary is concurrent-safe.
func RegisterMetalLibrary(source *ShaderSource, library []byte) {
metal.RegisterPrecompiledLibrary(source.source, library)
}

View File

@ -1,66 +0,0 @@
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !playstation5
package shaderprecomp
import (
"io"
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/directx"
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
)
const (
// HLSLVertexShaderProfile is the target profile for vertex shaders.
HLSLVertexShaderProfile = directx.VertexShaderProfile
// HLSLPixelShaderProfile is the target profile for pixel shaders.
HLSLPixelShaderProfile = directx.PixelShaderProfile
// HLSLVertexShaderEntryPoint is the entry point name for vertex shaders.
HLSLVertexShaderEntryPoint = directx.VertexShaderEntryPoint
// HLSLPixelShaderEntryPoint is the entry point name for pixel shaders.
HLSLPixelShaderEntryPoint = directx.PixelShaderEntryPoint
)
// CompileToHLSL compiles the shader source to High-Level Shader Language to writers.
//
// CompileToHLSL is concurrent-safe.
func CompileToHLSL(vertexWriter, pixelWriter io.Writer, source *ShaderSource) error {
ir, err := graphics.CompileShader(source.source)
if err != nil {
return err
}
vs, ps := hlsl.Compile(ir)
if _, err = vertexWriter.Write([]byte(vs)); err != nil {
return err
}
if _, err = pixelWriter.Write([]byte(ps)); err != nil {
return err
}
return nil
}
// RegisterFXCs registers a precompiled HLSL (FXC) for a shader source.
// vertexFXC and pixelFXC must be the content of .fxc files generated by `fxc` command.
// For more details, see https://learn.microsoft.com/en-us/windows/win32/direct3dtools/dx-graphics-tools-fxc-using.
//
// RegisterFXCs is concurrent-safe.
func RegisterFXCs(source *ShaderSource, vertexFXC, pixelFXC []byte) {
directx.RegisterPrecompiledFXCs(source.source, vertexFXC, pixelFXC)
}

View File

@ -131,7 +131,10 @@ type Glyph struct {
// Image is a rasterized glyph image.
// Image is a grayscale image i.e. RGBA values are the same.
// Image should be used as a render source and should not be modified.
//
// Image should be used as a render source and must not be modified.
//
// Image can be nil.
Image *ebiten.Image
// X is the X position to render this glyph.