mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Add Texture.native
This commit is contained in:
parent
78755c9b09
commit
ec83c0ad5f
@ -15,21 +15,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
screen *Texture
|
screen *RenderTarget
|
||||||
screenWidth int
|
screenWidth int
|
||||||
screenHeight int
|
screenHeight int
|
||||||
screenScale int
|
screenScale int
|
||||||
textures map[C.GLuint]*Texture
|
textures map[graphics.TextureID]*Texture
|
||||||
currentOffscreen *Texture
|
renderTargets map[graphics.RenderTargetID]*RenderTarget
|
||||||
mainFramebufferTexture *Texture
|
currentOffscreen *RenderTarget
|
||||||
|
mainFramebufferTexture *RenderTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContext(screenWidth, screenHeight, screenScale int) *Context {
|
func newContext(screenWidth, screenHeight, screenScale int) *Context {
|
||||||
context := &Context{
|
context := &Context{
|
||||||
screenWidth: screenWidth,
|
screenWidth: screenWidth,
|
||||||
screenHeight: screenHeight,
|
screenHeight: screenHeight,
|
||||||
screenScale: screenScale,
|
screenScale: screenScale,
|
||||||
textures: map[C.GLuint]*Texture{},
|
textures: map[graphics.TextureID]*Texture{},
|
||||||
|
renderTargets: map[graphics.RenderTargetID]*RenderTarget{},
|
||||||
}
|
}
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
@ -49,11 +51,12 @@ func (context *Context) Init() {
|
|||||||
|
|
||||||
screenID := context.NewRenderTarget(
|
screenID := context.NewRenderTarget(
|
||||||
context.screenWidth, context.screenHeight)
|
context.screenWidth, context.screenHeight)
|
||||||
context.screen = context.textures[C.GLuint(screenID)]
|
context.screen = context.renderTargets[screenID]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) ToTexture(renderTargetID graphics.RenderTargetID) graphics.TextureID {
|
func (context *Context) ToTexture(renderTargetID graphics.RenderTargetID) graphics.TextureID {
|
||||||
return graphics.TextureID(renderTargetID)
|
renderTarget := context.renderTargets[renderTargetID]
|
||||||
|
return renderTarget.texture.ID()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) Clear() {
|
func (context *Context) Clear() {
|
||||||
@ -73,8 +76,10 @@ func (context *Context) Fill(r, g, b uint8) {
|
|||||||
func (context *Context) DrawTexture(
|
func (context *Context) DrawTexture(
|
||||||
textureID graphics.TextureID,
|
textureID graphics.TextureID,
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
||||||
texture := context.textures[C.GLuint(textureID)]
|
texture, ok := context.textures[textureID]
|
||||||
|
if !ok {
|
||||||
|
panic("invalid texture ID")
|
||||||
|
}
|
||||||
source := graphics.Rect{0, 0, texture.width, texture.height}
|
source := graphics.Rect{0, 0, texture.width, texture.height}
|
||||||
locations := []graphics.TexturePart{{0, 0, source}}
|
locations := []graphics.TexturePart{{0, 0, source}}
|
||||||
context.DrawTextureParts(textureID, locations,
|
context.DrawTextureParts(textureID, locations,
|
||||||
@ -84,13 +89,14 @@ func (context *Context) DrawTexture(
|
|||||||
func (context *Context) DrawTextureParts(
|
func (context *Context) DrawTextureParts(
|
||||||
textureID graphics.TextureID, parts []graphics.TexturePart,
|
textureID graphics.TextureID, parts []graphics.TexturePart,
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
||||||
texture := context.textures[C.GLuint(textureID)]
|
|
||||||
if texture == nil {
|
texture, ok := context.textures[textureID]
|
||||||
|
if !ok {
|
||||||
panic("invalid texture ID")
|
panic("invalid texture ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderProgram := context.setShaderProgram(geometryMatrix, colorMatrix)
|
shaderProgram := context.setShaderProgram(geometryMatrix, colorMatrix)
|
||||||
C.glBindTexture(C.GL_TEXTURE_2D, texture.id)
|
C.glBindTexture(C.GL_TEXTURE_2D, texture.native)
|
||||||
|
|
||||||
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
||||||
textureAttrLocation := getAttributeLocation(shaderProgram, "texture")
|
textureAttrLocation := getAttributeLocation(shaderProgram, "texture")
|
||||||
@ -142,11 +148,11 @@ func (context *Context) ResetOffscreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) SetOffscreen(renderTargetID graphics.RenderTargetID) {
|
func (context *Context) SetOffscreen(renderTargetID graphics.RenderTargetID) {
|
||||||
renderTarget := context.textures[C.GLuint(renderTargetID)]
|
renderTarget := context.renderTargets[renderTargetID]
|
||||||
context.setOffscreen(renderTarget)
|
context.setOffscreen(renderTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) setOffscreen(renderTarget *Texture) {
|
func (context *Context) setOffscreen(renderTarget *RenderTarget) {
|
||||||
context.currentOffscreen = renderTarget
|
context.currentOffscreen = renderTarget
|
||||||
|
|
||||||
C.glFlush()
|
C.glFlush()
|
||||||
@ -161,8 +167,8 @@ func (context *Context) setOffscreen(renderTarget *Texture) {
|
|||||||
C.glBlendFuncSeparate(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA,
|
C.glBlendFuncSeparate(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA,
|
||||||
C.GL_ZERO, C.GL_ONE)
|
C.GL_ZERO, C.GL_ONE)
|
||||||
|
|
||||||
C.glViewport(0, 0, C.GLsizei(renderTarget.textureWidth),
|
C.glViewport(0, 0, C.GLsizei(renderTarget.texture.textureWidth),
|
||||||
C.GLsizei(renderTarget.textureHeight))
|
C.GLsizei(renderTarget.texture.textureHeight))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) setMainFramebufferOffscreen() {
|
func (context *Context) setMainFramebufferOffscreen() {
|
||||||
@ -174,16 +180,16 @@ func (context *Context) flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) projectionMatrix() [16]float32 {
|
func (context *Context) projectionMatrix() [16]float32 {
|
||||||
texture := context.currentOffscreen
|
texture := context.currentOffscreen.texture
|
||||||
|
|
||||||
e11 := float32(2) / float32(texture.textureWidth)
|
e11 := float32(2) / float32(texture.textureWidth)
|
||||||
e22 := float32(2) / float32(texture.textureHeight)
|
e22 := float32(2) / float32(texture.textureHeight)
|
||||||
e41 := float32(-1)
|
e41 := float32(-1)
|
||||||
e42 := float32(-1)
|
e42 := float32(-1)
|
||||||
|
|
||||||
if texture == context.mainFramebufferTexture {
|
if context.currentOffscreen.ID() == context.mainFramebufferTexture.ID() {
|
||||||
e22 *= -1
|
e22 *= -1
|
||||||
e42 += float32(texture.height)/float32(texture.textureHeight)*2
|
e42 += float32(texture.height) / float32(texture.textureHeight) * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
return [...]float32{
|
return [...]float32{
|
||||||
@ -258,13 +264,14 @@ func (context *Context) setShaderProgram(
|
|||||||
|
|
||||||
func (context *Context) NewRenderTarget(width, height int) graphics.RenderTargetID {
|
func (context *Context) NewRenderTarget(width, height int) graphics.RenderTargetID {
|
||||||
renderTarget := newRenderTarget(width, height)
|
renderTarget := newRenderTarget(width, height)
|
||||||
context.textures[renderTarget.id] = (*Texture)(renderTarget)
|
context.renderTargets[renderTarget.ID()] = renderTarget
|
||||||
|
context.textures[renderTarget.texture.ID()] = renderTarget.texture
|
||||||
|
|
||||||
context.setOffscreen((*Texture)(renderTarget))
|
context.setOffscreen(renderTarget)
|
||||||
context.Clear()
|
context.Clear()
|
||||||
context.setMainFramebufferOffscreen()
|
context.setMainFramebufferOffscreen()
|
||||||
|
|
||||||
return graphics.RenderTargetID(renderTarget.id)
|
return renderTarget.ID()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) NewTextureFromImage(img image.Image) (
|
func (context *Context) NewTextureFromImage(img image.Image) (
|
||||||
@ -273,6 +280,6 @@ func (context *Context) NewTextureFromImage(img image.Image) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
context.textures[texture.id] = texture
|
context.textures[texture.ID()] = texture
|
||||||
return texture.ID(), nil
|
return texture.ID(), nil
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ func (device *Device) Update(draw func(graphics.Context)) {
|
|||||||
{0, scale, 0},
|
{0, scale, 0},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
context.DrawTexture(graphics.TextureID(context.screen.id),
|
context.DrawTexture(context.ToTexture(context.screen.ID()),
|
||||||
geometryMatrix, matrix.IdentityColor())
|
geometryMatrix, matrix.IdentityColor())
|
||||||
context.flush()
|
context.flush()
|
||||||
}
|
}
|
||||||
|
@ -38,24 +38,22 @@ func adjustPixels(width, height int, pixels []uint8) []uint8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
id C.GLuint
|
id graphics.TextureID
|
||||||
|
native C.GLuint
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
textureWidth int
|
textureWidth int
|
||||||
textureHeight int
|
textureHeight int
|
||||||
framebuffer C.GLuint
|
}
|
||||||
|
|
||||||
|
type RenderTarget struct {
|
||||||
|
id graphics.RenderTargetID
|
||||||
|
texture *Texture
|
||||||
|
framebuffer C.GLuint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (texture *Texture) ID() graphics.TextureID {
|
func (texture *Texture) ID() graphics.TextureID {
|
||||||
return graphics.TextureID(texture.id)
|
return texture.id
|
||||||
}
|
|
||||||
|
|
||||||
func (texture *Texture) Width() int {
|
|
||||||
return texture.width
|
|
||||||
}
|
|
||||||
|
|
||||||
func (texture *Texture) Height() int {
|
|
||||||
return texture.height
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTexture(width, height int, pixels []uint8) *Texture {
|
func createTexture(width, height int, pixels []uint8) *Texture {
|
||||||
@ -72,13 +70,13 @@ func createTexture(width, height int, pixels []uint8) *Texture {
|
|||||||
textureHeight: textureHeight,
|
textureHeight: textureHeight,
|
||||||
}
|
}
|
||||||
|
|
||||||
textureID := C.GLuint(0)
|
nativeTexture := C.GLuint(0)
|
||||||
C.glGenTextures(1, (*C.GLuint)(&textureID))
|
C.glGenTextures(1, (*C.GLuint)(&nativeTexture))
|
||||||
if textureID < 0 {
|
if nativeTexture < 0 {
|
||||||
panic("glGenTexture failed")
|
panic("glGenTexture failed")
|
||||||
}
|
}
|
||||||
C.glPixelStorei(C.GL_UNPACK_ALIGNMENT, 4)
|
C.glPixelStorei(C.GL_UNPACK_ALIGNMENT, 4)
|
||||||
C.glBindTexture(C.GL_TEXTURE_2D, C.GLuint(textureID))
|
C.glBindTexture(C.GL_TEXTURE_2D, C.GLuint(nativeTexture))
|
||||||
|
|
||||||
ptr := unsafe.Pointer(nil)
|
ptr := unsafe.Pointer(nil)
|
||||||
if pixels != nil {
|
if pixels != nil {
|
||||||
@ -92,23 +90,37 @@ func createTexture(width, height int, pixels []uint8) *Texture {
|
|||||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
||||||
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||||
|
|
||||||
texture.id = textureID
|
texture.native = nativeTexture
|
||||||
|
|
||||||
|
texture.id = graphics.TextureID(<-newID)
|
||||||
|
|
||||||
return texture
|
return texture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newRenderTarget(width, height int) *RenderTarget {
|
||||||
|
texture := createTexture(width, height, nil)
|
||||||
|
framebuffer := createFramebuffer(texture.native)
|
||||||
|
return &RenderTarget{
|
||||||
|
id: graphics.RenderTargetID(<-newID),
|
||||||
|
texture: texture,
|
||||||
|
framebuffer: framebuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (renderTarget *RenderTarget) ID() graphics.RenderTargetID {
|
||||||
|
return renderTarget.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (renderTarget *RenderTarget) Texture() *Texture {
|
||||||
|
return renderTarget.texture
|
||||||
|
}
|
||||||
|
|
||||||
type textureError string
|
type textureError string
|
||||||
|
|
||||||
func (err textureError) Error() string {
|
func (err textureError) Error() string {
|
||||||
return "Texture Error: " + string(err)
|
return "Texture Error: " + string(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRenderTarget(width, height int) *Texture {
|
|
||||||
texture := createTexture(width, height, nil)
|
|
||||||
texture.framebuffer = createFramebuffer(texture.id)
|
|
||||||
return texture
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTextureFromImage(img image.Image) (*Texture, error) {
|
func newTextureFromImage(img image.Image) (*Texture, error) {
|
||||||
var pix []uint8
|
var pix []uint8
|
||||||
switch img.(type) {
|
switch img.(type) {
|
||||||
@ -124,18 +136,21 @@ func newTextureFromImage(img image.Image) (*Texture, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newRenderTargetWithFramebuffer(width, height int,
|
func newRenderTargetWithFramebuffer(width, height int,
|
||||||
framebuffer C.GLuint) *Texture {
|
framebuffer C.GLuint) *RenderTarget {
|
||||||
return &Texture{
|
texture := &Texture{
|
||||||
id: 0,
|
id: graphics.TextureID(<-newID),
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
textureWidth: int(nextPowerOf2(uint64(width))),
|
textureWidth: int(nextPowerOf2(uint64(width))),
|
||||||
textureHeight: int(nextPowerOf2(uint64(height))),
|
textureHeight: int(nextPowerOf2(uint64(height))),
|
||||||
framebuffer: framebuffer,
|
}
|
||||||
|
return &RenderTarget{
|
||||||
|
texture: texture,
|
||||||
|
framebuffer: framebuffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFramebuffer(textureID C.GLuint) C.GLuint {
|
func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
|
||||||
framebuffer := C.GLuint(0)
|
framebuffer := C.GLuint(0)
|
||||||
C.glGenFramebuffers(1, &framebuffer)
|
C.glGenFramebuffers(1, &framebuffer)
|
||||||
|
|
||||||
@ -143,7 +158,7 @@ func createFramebuffer(textureID C.GLuint) C.GLuint {
|
|||||||
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &origFramebuffer)
|
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &origFramebuffer)
|
||||||
C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer)
|
C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer)
|
||||||
C.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0,
|
C.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0,
|
||||||
C.GL_TEXTURE_2D, textureID, 0)
|
C.GL_TEXTURE_2D, nativeTexture, 0)
|
||||||
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(origFramebuffer))
|
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(origFramebuffer))
|
||||||
if C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) !=
|
if C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) !=
|
||||||
C.GL_FRAMEBUFFER_COMPLETE {
|
C.GL_FRAMEBUFFER_COMPLETE {
|
||||||
@ -152,3 +167,14 @@ func createFramebuffer(textureID C.GLuint) C.GLuint {
|
|||||||
|
|
||||||
return framebuffer
|
return framebuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var newID chan int
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
newID = make(chan int)
|
||||||
|
go func() {
|
||||||
|
for i := 0; ; i++ {
|
||||||
|
newID <- i
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user