mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
Remove dependencies on ebiten from opengl
This commit is contained in:
parent
d264d7a06b
commit
76b7da090c
30
graphics.go
30
graphics.go
@ -16,6 +16,11 @@ limitations under the License.
|
||||
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl/internal/shader"
|
||||
)
|
||||
|
||||
// A Rect represents a rectangle.
|
||||
type Rect struct {
|
||||
X int
|
||||
@ -81,3 +86,28 @@ type RenderTargetID int
|
||||
func (i RenderTargetID) IsNil() bool {
|
||||
return i == 0
|
||||
}
|
||||
|
||||
func u(x int, width int) float32 {
|
||||
return float32(x) / float32(opengl.AdjustSizeForTexture(width))
|
||||
}
|
||||
|
||||
func v(y int, height int) float32 {
|
||||
return float32(y) / float32(opengl.AdjustSizeForTexture(height))
|
||||
}
|
||||
|
||||
func textureQuads(parts []TexturePart, width, height int) []shader.TextureQuad {
|
||||
quads := make([]shader.TextureQuad, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
x1 := float32(part.LocationX)
|
||||
x2 := float32(part.LocationX + part.Source.Width)
|
||||
y1 := float32(part.LocationY)
|
||||
y2 := float32(part.LocationY + part.Source.Height)
|
||||
u1 := u(part.Source.X, width)
|
||||
u2 := u(part.Source.X+part.Source.Width, width)
|
||||
v1 := v(part.Source.Y, height)
|
||||
v2 := v(part.Source.Y+part.Source.Height, height)
|
||||
quad := shader.TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
|
||||
quads = append(quads, quad)
|
||||
}
|
||||
return quads
|
||||
}
|
||||
|
@ -14,29 +14,29 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package opengl
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||
)
|
||||
|
||||
func Initialize(screenWidth, screenHeight, screenScale int) (*GraphicsContext, error) {
|
||||
func Initialize(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
|
||||
gl.Init()
|
||||
gl.Enable(gl.TEXTURE_2D)
|
||||
gl.Enable(gl.BLEND)
|
||||
|
||||
c := &GraphicsContext{
|
||||
c := &graphicsContext{
|
||||
screenWidth: screenWidth,
|
||||
screenHeight: screenHeight,
|
||||
screenScale: screenScale,
|
||||
}
|
||||
|
||||
// The defualt framebuffer should be 0.
|
||||
c.defaultID = idsInstance.addRenderTarget(&renderTarget{
|
||||
width: screenWidth * screenScale,
|
||||
height: screenHeight * screenScale,
|
||||
flipY: true,
|
||||
c.defaultID = idsInstance.addRenderTarget(&opengl.RenderTarget{
|
||||
Width: screenWidth * screenScale,
|
||||
Height: screenHeight * screenScale,
|
||||
FlipY: true,
|
||||
})
|
||||
|
||||
var err error
|
||||
@ -46,76 +46,76 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*GraphicsContext, e
|
||||
}
|
||||
|
||||
// TODO: This is a special stack only for clearing. Can we change this?
|
||||
c.currentIDs = []ebiten.RenderTargetID{c.screenID}
|
||||
c.currentIDs = []RenderTargetID{c.screenID}
|
||||
c.Clear()
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type GraphicsContext struct {
|
||||
screenID ebiten.RenderTargetID
|
||||
defaultID ebiten.RenderTargetID
|
||||
currentIDs []ebiten.RenderTargetID
|
||||
type graphicsContext struct {
|
||||
screenID RenderTargetID
|
||||
defaultID RenderTargetID
|
||||
currentIDs []RenderTargetID
|
||||
screenWidth int
|
||||
screenHeight int
|
||||
screenScale int
|
||||
}
|
||||
|
||||
var _ ebiten.GraphicsContext = new(GraphicsContext)
|
||||
var _ GraphicsContext = new(graphicsContext)
|
||||
|
||||
func (c *GraphicsContext) dispose() {
|
||||
func (c *graphicsContext) dispose() {
|
||||
// NOTE: Now this method is not used anywhere.
|
||||
idsInstance.deleteRenderTarget(c.screenID)
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) Clear() {
|
||||
func (c *graphicsContext) Clear() {
|
||||
c.Fill(0, 0, 0)
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) Fill(r, g, b uint8) {
|
||||
func (c *graphicsContext) Fill(r, g, b uint8) {
|
||||
idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b)
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) Texture(id ebiten.TextureID) ebiten.Drawer {
|
||||
func (c *graphicsContext) Texture(id TextureID) Drawer {
|
||||
return &textureWithContext{id, c}
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) RenderTarget(id ebiten.RenderTargetID) ebiten.Drawer {
|
||||
func (c *graphicsContext) RenderTarget(id RenderTargetID) Drawer {
|
||||
return &textureWithContext{idsInstance.toTexture(id), c}
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) PushRenderTarget(renderTargetID ebiten.RenderTargetID) {
|
||||
func (c *graphicsContext) PushRenderTarget(renderTargetID RenderTargetID) {
|
||||
c.currentIDs = append(c.currentIDs, renderTargetID)
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) PopRenderTarget() {
|
||||
func (c *graphicsContext) PopRenderTarget() {
|
||||
c.currentIDs = c.currentIDs[:len(c.currentIDs)-1]
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) PreUpdate() {
|
||||
c.currentIDs = []ebiten.RenderTargetID{c.defaultID}
|
||||
func (c *graphicsContext) PreUpdate() {
|
||||
c.currentIDs = []RenderTargetID{c.defaultID}
|
||||
c.PushRenderTarget(c.screenID)
|
||||
c.Clear()
|
||||
}
|
||||
|
||||
func (c *GraphicsContext) PostUpdate() {
|
||||
func (c *graphicsContext) PostUpdate() {
|
||||
c.PopRenderTarget()
|
||||
c.Clear()
|
||||
|
||||
scale := float64(c.screenScale)
|
||||
geo := ebiten.GeometryMatrixI()
|
||||
geo := GeometryMatrixI()
|
||||
geo.Scale(scale, scale)
|
||||
ebiten.DrawWhole(c.RenderTarget(c.screenID), c.screenWidth, c.screenHeight, geo, ebiten.ColorMatrixI())
|
||||
DrawWhole(c.RenderTarget(c.screenID), c.screenWidth, c.screenHeight, geo, ColorMatrixI())
|
||||
|
||||
gl.Flush()
|
||||
}
|
||||
|
||||
type textureWithContext struct {
|
||||
id ebiten.TextureID
|
||||
context *GraphicsContext
|
||||
id TextureID
|
||||
context *graphicsContext
|
||||
}
|
||||
|
||||
func (t *textureWithContext) Draw(parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) {
|
||||
func (t *textureWithContext) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) {
|
||||
currentID := t.context.currentIDs[len(t.context.currentIDs)-1]
|
||||
idsInstance.drawTexture(currentID, t.id, parts, geo, color)
|
||||
}
|
@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package opengl
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl/internal/shader"
|
||||
"image"
|
||||
"math"
|
||||
@ -26,49 +26,49 @@ import (
|
||||
)
|
||||
|
||||
type ids struct {
|
||||
textures map[ebiten.TextureID]*texture
|
||||
renderTargets map[ebiten.RenderTargetID]*renderTarget
|
||||
renderTargetToTexture map[ebiten.RenderTargetID]ebiten.TextureID
|
||||
textures map[TextureID]*opengl.Texture
|
||||
renderTargets map[RenderTargetID]*opengl.RenderTarget
|
||||
renderTargetToTexture map[RenderTargetID]TextureID
|
||||
lastId int
|
||||
currentRenderTargetId ebiten.RenderTargetID
|
||||
currentRenderTargetId RenderTargetID
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
var idsInstance = &ids{
|
||||
textures: map[ebiten.TextureID]*texture{},
|
||||
renderTargets: map[ebiten.RenderTargetID]*renderTarget{},
|
||||
renderTargetToTexture: map[ebiten.RenderTargetID]ebiten.TextureID{},
|
||||
textures: map[TextureID]*opengl.Texture{},
|
||||
renderTargets: map[RenderTargetID]*opengl.RenderTarget{},
|
||||
renderTargetToTexture: map[RenderTargetID]TextureID{},
|
||||
currentRenderTargetId: -1,
|
||||
}
|
||||
|
||||
func NewRenderTargetID(width, height int, filter int) (ebiten.RenderTargetID, error) {
|
||||
func NewRenderTargetID(width, height int, filter int) (RenderTargetID, error) {
|
||||
return idsInstance.createRenderTarget(width, height, filter)
|
||||
}
|
||||
|
||||
func NewTextureID(img image.Image, filter int) (ebiten.TextureID, error) {
|
||||
func NewTextureID(img image.Image, filter int) (TextureID, error) {
|
||||
return idsInstance.createTexture(img, filter)
|
||||
}
|
||||
|
||||
func (i *ids) textureAt(id ebiten.TextureID) *texture {
|
||||
func (i *ids) textureAt(id TextureID) *opengl.Texture {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
return i.textures[id]
|
||||
}
|
||||
|
||||
func (i *ids) renderTargetAt(id ebiten.RenderTargetID) *renderTarget {
|
||||
func (i *ids) renderTargetAt(id RenderTargetID) *opengl.RenderTarget {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
return i.renderTargets[id]
|
||||
}
|
||||
|
||||
func (i *ids) toTexture(id ebiten.RenderTargetID) ebiten.TextureID {
|
||||
func (i *ids) toTexture(id RenderTargetID) TextureID {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
return i.renderTargetToTexture[id]
|
||||
}
|
||||
|
||||
func (i *ids) createTexture(img image.Image, filter int) (ebiten.TextureID, error) {
|
||||
texture, err := createTextureFromImage(img, filter)
|
||||
func (i *ids) createTexture(img image.Image, filter int) (TextureID, error) {
|
||||
texture, err := opengl.CreateTextureFromImage(img, filter)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -76,31 +76,31 @@ func (i *ids) createTexture(img image.Image, filter int) (ebiten.TextureID, erro
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
i.lastId++
|
||||
textureId := ebiten.TextureID(i.lastId)
|
||||
textureId := TextureID(i.lastId)
|
||||
i.textures[textureId] = texture
|
||||
return textureId, nil
|
||||
}
|
||||
|
||||
func (i *ids) createRenderTarget(width, height int, filter int) (ebiten.RenderTargetID, error) {
|
||||
texture, err := createTexture(width, height, filter)
|
||||
func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID, error) {
|
||||
texture, err := opengl.CreateTexture(width, height, filter)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
framebuffer := createFramebuffer(gl.Texture(texture.native))
|
||||
framebuffer := opengl.CreateFramebuffer(texture.Native())
|
||||
// The current binded framebuffer can be changed.
|
||||
i.currentRenderTargetId = -1
|
||||
r := &renderTarget{
|
||||
framebuffer: framebuffer,
|
||||
width: texture.width,
|
||||
height: texture.height,
|
||||
r := &opengl.RenderTarget{
|
||||
Framebuffer: framebuffer,
|
||||
Width: texture.Width(),
|
||||
Height: texture.Height(),
|
||||
}
|
||||
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
i.lastId++
|
||||
textureId := ebiten.TextureID(i.lastId)
|
||||
textureId := TextureID(i.lastId)
|
||||
i.lastId++
|
||||
renderTargetId := ebiten.RenderTargetID(i.lastId)
|
||||
renderTargetId := RenderTargetID(i.lastId)
|
||||
|
||||
i.textures[textureId] = texture
|
||||
i.renderTargets[renderTargetId] = r
|
||||
@ -110,17 +110,17 @@ func (i *ids) createRenderTarget(width, height int, filter int) (ebiten.RenderTa
|
||||
}
|
||||
|
||||
// NOTE: renderTarget can't be used as a texture.
|
||||
func (i *ids) addRenderTarget(renderTarget *renderTarget) ebiten.RenderTargetID {
|
||||
func (i *ids) addRenderTarget(renderTarget *opengl.RenderTarget) RenderTargetID {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
i.lastId++
|
||||
id := ebiten.RenderTargetID(i.lastId)
|
||||
id := RenderTargetID(i.lastId)
|
||||
i.renderTargets[id] = renderTarget
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
func (i *ids) deleteRenderTarget(id ebiten.RenderTargetID) {
|
||||
func (i *ids) deleteRenderTarget(id RenderTargetID) {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
|
||||
@ -128,34 +128,34 @@ func (i *ids) deleteRenderTarget(id ebiten.RenderTargetID) {
|
||||
textureId := i.renderTargetToTexture[id]
|
||||
texture := i.textures[textureId]
|
||||
|
||||
renderTarget.dispose()
|
||||
texture.dispose()
|
||||
renderTarget.Dispose()
|
||||
texture.Dispose()
|
||||
|
||||
delete(i.renderTargets, id)
|
||||
delete(i.renderTargetToTexture, id)
|
||||
delete(i.textures, textureId)
|
||||
}
|
||||
|
||||
func (i *ids) fillRenderTarget(id ebiten.RenderTargetID, r, g, b uint8) {
|
||||
func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) {
|
||||
i.setViewportIfNeeded(id)
|
||||
const max = float64(math.MaxUint8)
|
||||
gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
}
|
||||
|
||||
func (i *ids) drawTexture(target ebiten.RenderTargetID, id ebiten.TextureID, parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) {
|
||||
func (i *ids) drawTexture(target RenderTargetID, id TextureID, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) {
|
||||
texture := i.textureAt(id)
|
||||
i.setViewportIfNeeded(target)
|
||||
r := i.renderTargetAt(target)
|
||||
projectionMatrix := r.projectionMatrix()
|
||||
quads := textureQuads(parts, texture.width, texture.height)
|
||||
shader.DrawTexture(texture.native, projectionMatrix, quads, &geo, &color)
|
||||
projectionMatrix := r.ProjectionMatrix()
|
||||
quads := textureQuads(parts, texture.Width(), texture.Height())
|
||||
shader.DrawTexture(texture.Native(), projectionMatrix, quads, &geo, &color)
|
||||
}
|
||||
|
||||
func (i *ids) setViewportIfNeeded(id ebiten.RenderTargetID) {
|
||||
func (i *ids) setViewportIfNeeded(id RenderTargetID) {
|
||||
r := i.renderTargetAt(id)
|
||||
if i.currentRenderTargetId != id {
|
||||
r.setAsViewport()
|
||||
r.SetAsViewport()
|
||||
i.currentRenderTargetId = id
|
||||
}
|
||||
}
|
@ -20,15 +20,20 @@ import (
|
||||
"github.com/go-gl/gl"
|
||||
glfw "github.com/go-gl/glfw3"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||
"image"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type GraphicsContext interface {
|
||||
ebiten.GraphicsContext
|
||||
PreUpdate()
|
||||
PostUpdate()
|
||||
}
|
||||
|
||||
type canvas struct {
|
||||
window *glfw.Window
|
||||
scale int
|
||||
graphicsContext *opengl.GraphicsContext
|
||||
graphicsContext GraphicsContext
|
||||
input input
|
||||
funcs chan func()
|
||||
funcsDone chan struct{}
|
||||
@ -65,7 +70,7 @@ func (c *canvas) NewTextureID(img image.Image, filter ebiten.Filter) (ebiten.Tex
|
||||
default:
|
||||
panic("not reached")
|
||||
}
|
||||
id, err = opengl.NewTextureID(img, glFilter)
|
||||
id, err = ebiten.NewTextureID(img, glFilter)
|
||||
})
|
||||
return id, err
|
||||
}
|
||||
@ -83,7 +88,7 @@ func (c *canvas) NewRenderTargetID(width, height int, filter ebiten.Filter) (ebi
|
||||
default:
|
||||
panic("not reached")
|
||||
}
|
||||
id, err = opengl.NewRenderTargetID(width, height, glFilter)
|
||||
id, err = ebiten.NewRenderTargetID(width, height, glFilter)
|
||||
})
|
||||
return id, err
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"fmt"
|
||||
glfw "github.com/go-gl/glfw3"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -57,7 +56,7 @@ func (u *UI) Start(game ebiten.Game, width, height, scale int, title string) err
|
||||
windowWidth, _ := window.GetFramebufferSize()
|
||||
realScale := windowWidth / width
|
||||
c.use(func() {
|
||||
c.graphicsContext, err = opengl.Initialize(width, height, realScale)
|
||||
c.graphicsContext, err = ebiten.Initialize(width, height, realScale)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -35,14 +35,18 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
|
||||
}
|
||||
}
|
||||
|
||||
type renderTarget struct {
|
||||
framebuffer gl.Framebuffer
|
||||
width int
|
||||
height int
|
||||
flipY bool
|
||||
type RenderTarget struct {
|
||||
Framebuffer gl.Framebuffer
|
||||
Width int
|
||||
Height int
|
||||
FlipY bool
|
||||
}
|
||||
|
||||
func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
|
||||
func (r *RenderTarget) Dispose() {
|
||||
r.Framebuffer.Delete()
|
||||
}
|
||||
|
||||
func CreateFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
|
||||
framebuffer := gl.GenFramebuffer()
|
||||
framebuffer.Bind()
|
||||
|
||||
@ -59,9 +63,9 @@ func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
|
||||
return framebuffer
|
||||
}
|
||||
|
||||
func (r *renderTarget) setAsViewport() {
|
||||
func (r *RenderTarget) SetAsViewport() {
|
||||
gl.Flush()
|
||||
r.framebuffer.Bind()
|
||||
r.Framebuffer.Bind()
|
||||
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
||||
if err != gl.FRAMEBUFFER_COMPLETE {
|
||||
panic(fmt.Sprintf("glBindFramebuffer failed: %d", err))
|
||||
@ -69,22 +73,18 @@ func (r *renderTarget) setAsViewport() {
|
||||
|
||||
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE)
|
||||
|
||||
width := adjustSizeForTexture(r.width)
|
||||
height := adjustSizeForTexture(r.height)
|
||||
width := AdjustSizeForTexture(r.Width)
|
||||
height := AdjustSizeForTexture(r.Height)
|
||||
gl.Viewport(0, 0, width, height)
|
||||
}
|
||||
|
||||
func (r *renderTarget) projectionMatrix() [4][4]float64 {
|
||||
width := adjustSizeForTexture(r.width)
|
||||
height := adjustSizeForTexture(r.height)
|
||||
ebiten := orthoProjectionMatrix(0, width, 0, height)
|
||||
if r.flipY {
|
||||
ebiten[1][1] *= -1
|
||||
ebiten[1][3] += float64(r.height) / float64(adjustSizeForTexture(r.height)) * 2
|
||||
func (r *RenderTarget) ProjectionMatrix() [4][4]float64 {
|
||||
width := AdjustSizeForTexture(r.Width)
|
||||
height := AdjustSizeForTexture(r.Height)
|
||||
m := orthoProjectionMatrix(0, width, 0, height)
|
||||
if r.FlipY {
|
||||
m[1][1] *= -1
|
||||
m[1][3] += float64(r.Height) / float64(AdjustSizeForTexture(r.Height)) * 2
|
||||
}
|
||||
return ebiten
|
||||
}
|
||||
|
||||
func (r *renderTarget) dispose() {
|
||||
r.framebuffer.Delete()
|
||||
return m
|
||||
}
|
||||
|
@ -22,13 +22,28 @@ import (
|
||||
"image/draw"
|
||||
)
|
||||
|
||||
func NextPowerOf2(x uint64) uint64 {
|
||||
x -= 1
|
||||
x |= (x >> 1)
|
||||
x |= (x >> 2)
|
||||
x |= (x >> 4)
|
||||
x |= (x >> 8)
|
||||
x |= (x >> 16)
|
||||
x |= (x >> 32)
|
||||
return x + 1
|
||||
}
|
||||
|
||||
func AdjustSizeForTexture(size int) int {
|
||||
return int(NextPowerOf2(uint64(size)))
|
||||
}
|
||||
|
||||
func adjustImageForTexture(img image.Image) *image.NRGBA {
|
||||
width, height := img.Bounds().Size().X, img.Bounds().Size().Y
|
||||
adjustedImageBounds := image.Rectangle{
|
||||
image.ZP,
|
||||
image.Point{
|
||||
adjustSizeForTexture(width),
|
||||
adjustSizeForTexture(height),
|
||||
AdjustSizeForTexture(width),
|
||||
AdjustSizeForTexture(height),
|
||||
},
|
||||
}
|
||||
if nrgba, ok := img.(*image.NRGBA); ok && img.Bounds() == adjustedImageBounds {
|
||||
@ -44,12 +59,24 @@ func adjustImageForTexture(img image.Image) *image.NRGBA {
|
||||
return adjustedImage
|
||||
}
|
||||
|
||||
type texture struct {
|
||||
type Texture struct {
|
||||
native gl.Texture
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
func (t *Texture) Native() gl.Texture {
|
||||
return t.native
|
||||
}
|
||||
|
||||
func (t *Texture) Width() int {
|
||||
return t.width
|
||||
}
|
||||
|
||||
func (t *Texture) Height() int {
|
||||
return t.height
|
||||
}
|
||||
|
||||
func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter int) gl.Texture {
|
||||
nativeTexture := gl.GenTexture()
|
||||
if nativeTexture < 0 {
|
||||
@ -67,20 +94,20 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter
|
||||
return nativeTexture
|
||||
}
|
||||
|
||||
func createTexture(width, height int, filter int) (*texture, error) {
|
||||
w := adjustSizeForTexture(width)
|
||||
h := adjustSizeForTexture(height)
|
||||
func CreateTexture(width, height int, filter int) (*Texture, error) {
|
||||
w := AdjustSizeForTexture(width)
|
||||
h := AdjustSizeForTexture(height)
|
||||
native := createNativeTexture(w, h, nil, filter)
|
||||
return &texture{native, width, height}, nil
|
||||
return &Texture{native, width, height}, nil
|
||||
}
|
||||
|
||||
func createTextureFromImage(img image.Image, filter int) (*texture, error) {
|
||||
func CreateTextureFromImage(img image.Image, filter int) (*Texture, error) {
|
||||
adjustedImage := adjustImageForTexture(img)
|
||||
size := adjustedImage.Bounds().Size()
|
||||
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
|
||||
return &texture{native, size.X, size.Y}, nil
|
||||
return &Texture{native, size.X, size.Y}, nil
|
||||
}
|
||||
|
||||
func (t *texture) dispose() {
|
||||
func (t *Texture) Dispose() {
|
||||
t.native.Delete()
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 Hajime Hoshi
|
||||
|
||||
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 opengl
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl/internal/shader"
|
||||
)
|
||||
|
||||
func NextPowerOf2(x uint64) uint64 {
|
||||
x -= 1
|
||||
x |= (x >> 1)
|
||||
x |= (x >> 2)
|
||||
x |= (x >> 4)
|
||||
x |= (x >> 8)
|
||||
x |= (x >> 16)
|
||||
x |= (x >> 32)
|
||||
return x + 1
|
||||
}
|
||||
|
||||
func adjustSizeForTexture(size int) int {
|
||||
return int(NextPowerOf2(uint64(size)))
|
||||
}
|
||||
|
||||
func u(x int, width int) float32 {
|
||||
return float32(x) / float32(adjustSizeForTexture(width))
|
||||
}
|
||||
|
||||
func v(y int, height int) float32 {
|
||||
return float32(y) / float32(adjustSizeForTexture(height))
|
||||
}
|
||||
|
||||
func textureQuads(parts []ebiten.TexturePart, width, height int) []shader.TextureQuad {
|
||||
quads := make([]shader.TextureQuad, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
x1 := float32(part.LocationX)
|
||||
x2 := float32(part.LocationX + part.Source.Width)
|
||||
y1 := float32(part.LocationY)
|
||||
y2 := float32(part.LocationY + part.Source.Height)
|
||||
u1 := u(part.Source.X, width)
|
||||
u2 := u(part.Source.X+part.Source.Width, width)
|
||||
v1 := v(part.Source.Y, height)
|
||||
v2 := v(part.Source.Y+part.Source.Height, height)
|
||||
quad := shader.TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
|
||||
quads = append(quads, quad)
|
||||
}
|
||||
return quads
|
||||
}
|
Loading…
Reference in New Issue
Block a user