mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
Refactoring
This commit is contained in:
parent
a0f17a4971
commit
9aded38cc2
@ -70,7 +70,7 @@ type Sprites struct {
|
|||||||
|
|
||||||
func New() *Sprites {
|
func New() *Sprites {
|
||||||
go func() {
|
go func() {
|
||||||
|
|
||||||
}()
|
}()
|
||||||
return &Sprites{}
|
return &Sprites{}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ type Context struct {
|
|||||||
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
|
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
|
||||||
currentOffscreen *RenderTarget
|
currentOffscreen *RenderTarget
|
||||||
mainFramebufferTexture *RenderTarget
|
mainFramebufferTexture *RenderTarget
|
||||||
|
projectionMatrix [16]float32
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContext(screenWidth, screenHeight, screenScale int) *Context {
|
func newContext(screenWidth, screenHeight, screenScale int) *Context {
|
||||||
@ -96,11 +97,11 @@ func (context *Context) DrawTextureParts(
|
|||||||
|
|
||||||
texture, ok := context.textures[textureId]
|
texture, ok := context.textures[textureId]
|
||||||
if !ok {
|
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.native)
|
C.glBindTexture(C.GL_TEXTURE_2D, texture.Native().(C.GLuint))
|
||||||
|
|
||||||
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
||||||
textureAttrLocation := getAttributeLocation(shaderProgram, "texture")
|
textureAttrLocation := getAttributeLocation(shaderProgram, "texture")
|
||||||
@ -123,10 +124,10 @@ func (context *Context) DrawTextureParts(
|
|||||||
}
|
}
|
||||||
|
|
||||||
src := part.Source
|
src := part.Source
|
||||||
tu1 := float32(src.X) / float32(texture.textureWidth)
|
tu1 := float32(texture.U(src.X))
|
||||||
tu2 := float32(src.X+src.Width) / float32(texture.textureWidth)
|
tu2 := float32(texture.U(src.X + src.Width))
|
||||||
tv1 := float32(src.Y) / float32(texture.textureHeight)
|
tv1 := float32(texture.V(src.Y))
|
||||||
tv2 := float32(src.Y+src.Height) / float32(texture.textureHeight)
|
tv2 := float32(texture.V(src.Y + src.Height))
|
||||||
texCoord := [...]float32{
|
texCoord := [...]float32{
|
||||||
tu1, tv1,
|
tu1, tv1,
|
||||||
tu2, tv1,
|
tu2, tv1,
|
||||||
@ -171,8 +172,41 @@ func (context *Context) setOffscreen(renderTarget *RenderTarget) {
|
|||||||
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.texture.textureWidth),
|
context.currentOffscreen.SetAsViewport(context)
|
||||||
C.GLsizei(renderTarget.texture.textureHeight))
|
}
|
||||||
|
|
||||||
|
func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
|
||||||
|
e11 := float64(2) / float64(right-left)
|
||||||
|
e22 := float64(2) / float64(top-bottom)
|
||||||
|
e14 := -1 * float64(right+left) / float64(right-left)
|
||||||
|
e24 := -1 * float64(top+bottom) / float64(top-bottom)
|
||||||
|
|
||||||
|
return [4][4]float64{
|
||||||
|
{e11, 0, 0, e14},
|
||||||
|
{0, e22, 0, e24},
|
||||||
|
{0, 0, 1, 0},
|
||||||
|
{0, 0, 0, 1},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (context *Context) SetViewport(x, y, width, height int) {
|
||||||
|
C.glViewport(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height))
|
||||||
|
|
||||||
|
matrix := orthoProjectionMatrix(x, width, y, height)
|
||||||
|
if context.currentOffscreen == context.mainFramebufferTexture {
|
||||||
|
// Flip Y and translate
|
||||||
|
matrix[1][1] *= -1
|
||||||
|
actualHeight := context.screenHeight * context.screenScale
|
||||||
|
matrix[1][3] += float64(actualHeight) / float64(height) * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
context.projectionMatrix[i+j*4] = float32(matrix[i][j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: call 'setShaderProgram' here?
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) setMainFramebufferOffscreen() {
|
func (context *Context) setMainFramebufferOffscreen() {
|
||||||
@ -183,27 +217,6 @@ func (context *Context) flush() {
|
|||||||
C.glFlush()
|
C.glFlush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) projectionMatrix() [16]float32 {
|
|
||||||
texture := context.currentOffscreen.texture
|
|
||||||
|
|
||||||
e11 := float32(2) / float32(texture.textureWidth)
|
|
||||||
e22 := float32(2) / float32(texture.textureHeight)
|
|
||||||
e41 := float32(-1)
|
|
||||||
e42 := float32(-1)
|
|
||||||
|
|
||||||
if context.currentOffscreen == context.mainFramebufferTexture {
|
|
||||||
e22 *= -1
|
|
||||||
e42 += float32(texture.height) / float32(texture.textureHeight) * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
return [...]float32{
|
|
||||||
e11, 0, 0, 0,
|
|
||||||
0, e22, 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
e41, e42, 0, 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (context *Context) setShaderProgram(
|
func (context *Context) setShaderProgram(
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) (program C.GLuint) {
|
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) (program C.GLuint) {
|
||||||
if colorMatrix.IsIdentity() {
|
if colorMatrix.IsIdentity() {
|
||||||
@ -214,10 +227,9 @@ func (context *Context) setShaderProgram(
|
|||||||
// TODO: cache and skip?
|
// TODO: cache and skip?
|
||||||
C.glUseProgram(program)
|
C.glUseProgram(program)
|
||||||
|
|
||||||
projectionMatrix := context.projectionMatrix()
|
|
||||||
C.glUniformMatrix4fv(getUniformLocation(program, "projection_matrix"),
|
C.glUniformMatrix4fv(getUniformLocation(program, "projection_matrix"),
|
||||||
1, C.GL_FALSE,
|
1, C.GL_FALSE,
|
||||||
(*C.GLfloat)(&projectionMatrix[0]))
|
(*C.GLfloat)(&context.projectionMatrix[0]))
|
||||||
|
|
||||||
a := float32(geometryMatrix.Elements[0][0])
|
a := float32(geometryMatrix.Elements[0][0])
|
||||||
b := float32(geometryMatrix.Elements[0][1])
|
b := float32(geometryMatrix.Elements[0][1])
|
||||||
@ -280,6 +292,7 @@ func (context *Context) NewRenderTarget(width, height int) (
|
|||||||
|
|
||||||
context.setOffscreen(renderTarget)
|
context.setOffscreen(renderTarget)
|
||||||
context.Clear()
|
context.Clear()
|
||||||
|
// TODO: Is it OK to revert he main framebuffer?
|
||||||
context.setMainFramebufferOffscreen()
|
context.setMainFramebufferOffscreen()
|
||||||
|
|
||||||
return renderTargetId, nil
|
return renderTargetId, nil
|
||||||
|
@ -22,11 +22,29 @@ func nextPowerOf2(x uint64) uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
native C.GLuint
|
native interface{}
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
textureWidth int
|
}
|
||||||
textureHeight int
|
|
||||||
|
func (texture *Texture) Native() interface{} {
|
||||||
|
return texture.native
|
||||||
|
}
|
||||||
|
|
||||||
|
func (texture *Texture) textureWidth() int {
|
||||||
|
return int(nextPowerOf2(uint64(texture.width)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (texture *Texture) textureHeight() int {
|
||||||
|
return int(nextPowerOf2(uint64(texture.height)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (texture *Texture) U(x int) float64 {
|
||||||
|
return float64(x) / float64(texture.textureWidth())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (texture *Texture) V(y int) float64 {
|
||||||
|
return float64(y) / float64(texture.textureHeight())
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderTarget struct {
|
type RenderTarget struct {
|
||||||
@ -34,6 +52,14 @@ type RenderTarget struct {
|
|||||||
framebuffer C.GLuint
|
framebuffer C.GLuint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (renderTarget *RenderTarget) SetAsViewport(setter interface{
|
||||||
|
SetViewport(x, y, width, height int)
|
||||||
|
}) {
|
||||||
|
texture := renderTarget.texture
|
||||||
|
x, y, width, height := 0, 0, texture.textureWidth(), texture.textureHeight()
|
||||||
|
setter.SetViewport(x, y, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
func createNativeTexture(textureWidth, textureHeight int, pixels unsafe.Pointer) C.GLuint {
|
func createNativeTexture(textureWidth, textureHeight int, pixels unsafe.Pointer) C.GLuint {
|
||||||
nativeTexture := C.GLuint(0)
|
nativeTexture := C.GLuint(0)
|
||||||
|
|
||||||
@ -56,20 +82,17 @@ func createNativeTexture(textureWidth, textureHeight int, pixels unsafe.Pointer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createTexture(width, height int) *Texture {
|
func createTexture(width, height int) *Texture {
|
||||||
textureWidth := int(nextPowerOf2(uint64(width)))
|
texture := &Texture{
|
||||||
textureHeight := int(nextPowerOf2(uint64(height)))
|
width: width,
|
||||||
return &Texture{
|
height: height,
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
textureWidth: textureWidth,
|
|
||||||
textureHeight: textureHeight,
|
|
||||||
native: createNativeTexture(textureWidth, textureHeight, nil),
|
|
||||||
}
|
}
|
||||||
|
texture.native = createNativeTexture(texture.textureWidth(), texture.textureHeight(), nil)
|
||||||
|
return texture
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRenderTarget(width, height int) (*RenderTarget, error) {
|
func newRenderTarget(width, height int) (*RenderTarget, error) {
|
||||||
texture := createTexture(width, height)
|
texture := createTexture(width, height)
|
||||||
framebuffer := createFramebuffer(texture.native)
|
framebuffer := createFramebuffer(texture.Native().(C.GLuint))
|
||||||
return &RenderTarget{
|
return &RenderTarget{
|
||||||
texture: texture,
|
texture: texture,
|
||||||
framebuffer: framebuffer,
|
framebuffer: framebuffer,
|
||||||
@ -80,12 +103,14 @@ func newTextureFromImage(img image.Image) (*Texture, error) {
|
|||||||
size := img.Bounds().Size()
|
size := img.Bounds().Size()
|
||||||
width, height := size.X, size.Y
|
width, height := size.X, size.Y
|
||||||
|
|
||||||
textureWidth := int(nextPowerOf2(uint64(width)))
|
texture := &Texture{
|
||||||
textureHeight := int(nextPowerOf2(uint64(height)))
|
width: width,
|
||||||
|
height: height,
|
||||||
|
}
|
||||||
|
|
||||||
adjustedImageBound := image.Rectangle{
|
adjustedImageBound := image.Rectangle{
|
||||||
image.ZP,
|
image.ZP,
|
||||||
image.Point{textureWidth, textureHeight},
|
image.Point{texture.textureWidth(), texture.textureHeight()},
|
||||||
}
|
}
|
||||||
adjustedImage := image.NewNRGBA(adjustedImageBound)
|
adjustedImage := image.NewNRGBA(adjustedImageBound)
|
||||||
dstBound := image.Rectangle{
|
dstBound := image.Rectangle{
|
||||||
@ -94,24 +119,16 @@ func newTextureFromImage(img image.Image) (*Texture, error) {
|
|||||||
}
|
}
|
||||||
draw.Draw(adjustedImage, dstBound, img, image.ZP, draw.Src)
|
draw.Draw(adjustedImage, dstBound, img, image.ZP, draw.Src)
|
||||||
pixelsPtr := unsafe.Pointer(&adjustedImage.Pix[0])
|
pixelsPtr := unsafe.Pointer(&adjustedImage.Pix[0])
|
||||||
nativeTexture := createNativeTexture(textureWidth, textureHeight, pixelsPtr)
|
texture.native = createNativeTexture(
|
||||||
|
texture.textureWidth(), texture.textureHeight(), pixelsPtr)
|
||||||
return &Texture{
|
return texture, nil
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
textureWidth: textureWidth,
|
|
||||||
textureHeight: textureHeight,
|
|
||||||
native: nativeTexture,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRenderTargetWithFramebuffer(width, height int,
|
func newRenderTargetWithFramebuffer(width, height int,
|
||||||
framebuffer C.GLuint) *RenderTarget {
|
framebuffer C.GLuint) *RenderTarget {
|
||||||
texture := &Texture{
|
texture := &Texture{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
textureWidth: int(nextPowerOf2(uint64(width))),
|
|
||||||
textureHeight: int(nextPowerOf2(uint64(height))),
|
|
||||||
}
|
}
|
||||||
return &RenderTarget{
|
return &RenderTarget{
|
||||||
texture: texture,
|
texture: texture,
|
||||||
|
Loading…
Reference in New Issue
Block a user