mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Move some methods to opengl.Context
This commit is contained in:
parent
4e3beb65f0
commit
e10bcb3dd8
@ -55,16 +55,16 @@ func (c *graphicsContext) dispose() {
|
||||
framebuffer := c.screen.framebuffer
|
||||
texture := c.screen.texture
|
||||
|
||||
framebuffer.Dispose()
|
||||
texture.Dispose()
|
||||
framebuffer.Dispose(c.glContext)
|
||||
texture.Dispose(c.glContext)
|
||||
}
|
||||
|
||||
func (c *graphicsContext) preUpdate() error {
|
||||
return c.screen.Clear()
|
||||
return c.screen.Clear(c.glContext)
|
||||
}
|
||||
|
||||
func (c *graphicsContext) postUpdate() error {
|
||||
if err := c.defaultR.Clear(); err != nil {
|
||||
if err := c.defaultR.Clear(c.glContext); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
14
image.go
14
image.go
@ -39,13 +39,13 @@ func (i *innerImage) size() (width, height int) {
|
||||
return i.framebuffer.Size()
|
||||
}
|
||||
|
||||
func (i *innerImage) Clear() error {
|
||||
return i.Fill(color.Transparent)
|
||||
func (i *innerImage) Clear(c *opengl.Context) error {
|
||||
return i.Fill(c, color.Transparent)
|
||||
}
|
||||
|
||||
func (i *innerImage) Fill(clr color.Color) error {
|
||||
func (i *innerImage) Fill(c *opengl.Context, clr color.Color) error {
|
||||
r, g, b, a := internal.RGBA(clr)
|
||||
return i.framebuffer.Fill(r, g, b, a)
|
||||
return i.framebuffer.Fill(c, r, g, b, a)
|
||||
}
|
||||
|
||||
func (i *innerImage) drawImage(c *opengl.Context, img *innerImage, options *DrawImageOptions) error {
|
||||
@ -120,7 +120,7 @@ func (i *Image) Size() (width, height int) {
|
||||
func (i *Image) Clear() (err error) {
|
||||
i.pixels = nil
|
||||
i.syncer.Sync(func() {
|
||||
err = i.inner.Clear()
|
||||
err = i.inner.Clear(currentUI.glContext)
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -129,7 +129,7 @@ func (i *Image) Clear() (err error) {
|
||||
func (i *Image) Fill(clr color.Color) (err error) {
|
||||
i.pixels = nil
|
||||
i.syncer.Sync(func() {
|
||||
err = i.inner.Fill(clr)
|
||||
err = i.inner.Fill(currentUI.glContext, clr)
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -175,7 +175,7 @@ func (i *Image) At(x, y int) color.Color {
|
||||
if i.pixels == nil {
|
||||
i.syncer.Sync(func() {
|
||||
var err error
|
||||
i.pixels, err = i.inner.texture.Pixels()
|
||||
i.pixels, err = i.inner.texture.Pixels(currentUI.glContext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -67,14 +67,14 @@ func (f *Framebuffer) Size() (width, height int) {
|
||||
return f.width, f.height
|
||||
}
|
||||
|
||||
func (f *Framebuffer) Dispose() {
|
||||
f.native.Delete()
|
||||
func (f *Framebuffer) Dispose(c *opengl.Context) {
|
||||
c.DeleteFramebuffer(f.native)
|
||||
}
|
||||
|
||||
func (f *Framebuffer) setAsViewport() error {
|
||||
func (f *Framebuffer) setAsViewport(c *opengl.Context) error {
|
||||
width := internal.NextPowerOf2Int(f.width)
|
||||
height := internal.NextPowerOf2Int(f.height)
|
||||
return f.native.SetAsViewport(width, height)
|
||||
return c.SetViewport(f.native, width, height)
|
||||
}
|
||||
|
||||
func (f *Framebuffer) projectionMatrix() [4][4]float64 {
|
||||
@ -98,15 +98,15 @@ type TextureQuads interface {
|
||||
Texture(i int) (u0, v0, u1, v1 float32)
|
||||
}
|
||||
|
||||
func (f *Framebuffer) Fill(r, g, b, a float64) error {
|
||||
if err := f.setAsViewport(); err != nil {
|
||||
func (f *Framebuffer) Fill(c *opengl.Context, r, g, b, a float64) error {
|
||||
if err := f.setAsViewport(c); err != nil {
|
||||
return err
|
||||
}
|
||||
return f.native.Fill(r, g, b, a)
|
||||
return c.FillFramebuffer(f.native, r, g, b, a)
|
||||
}
|
||||
|
||||
func (f *Framebuffer) DrawTexture(c *opengl.Context, t *Texture, quads TextureQuads, geo, clr Matrix) error {
|
||||
if err := f.setAsViewport(); err != nil {
|
||||
if err := f.setAsViewport(c); err != nil {
|
||||
return err
|
||||
}
|
||||
projectionMatrix := f.projectionMatrix()
|
||||
|
@ -58,23 +58,20 @@ func DrawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix [4]
|
||||
}
|
||||
|
||||
// TODO: Check performance
|
||||
program := useProgramColorMatrix(glMatrix(projectionMatrix), geo, color)
|
||||
program := useProgramColorMatrix(c, glMatrix(projectionMatrix), geo, color)
|
||||
|
||||
// TODO: Do we have to call gl.ActiveTexture(gl.TEXTURE0)?
|
||||
texture.Bind()
|
||||
c.BindTexture(texture)
|
||||
|
||||
vertexAttrLocation := program.GetAttributeLocation("vertex")
|
||||
texCoordAttrLocation := program.GetAttributeLocation("tex_coord")
|
||||
|
||||
vertexAttrLocation.EnableArray()
|
||||
texCoordAttrLocation.EnableArray()
|
||||
c.EnableVertexAttribArray(program, "vertex")
|
||||
c.EnableVertexAttribArray(program, "tex_coord")
|
||||
defer func() {
|
||||
texCoordAttrLocation.DisableArray()
|
||||
vertexAttrLocation.DisableArray()
|
||||
c.DisableVertexAttribArray(program, "tex_coord")
|
||||
c.DisableVertexAttribArray(program, "vertex")
|
||||
}()
|
||||
|
||||
vertexAttrLocation.AttribPointer(stride, uintptr(float32Size*0))
|
||||
texCoordAttrLocation.AttribPointer(stride, uintptr(float32Size*2))
|
||||
c.VertexAttribPointer(program, "vertex", stride, uintptr(float32Size*0))
|
||||
c.VertexAttribPointer(program, "tex_coord", stride, uintptr(float32Size*2))
|
||||
|
||||
vertices := []float32{}
|
||||
for i := 0; i < quads.Len(); i++ {
|
||||
|
@ -29,13 +29,13 @@ func initialize(c *opengl.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer shaders[shaderVertex].native.Delete()
|
||||
defer c.DeleteShader(shaders[shaderVertex].native)
|
||||
|
||||
shaders[shaderColorMatrix].native, err = c.NewShader(c.FragmentShader, shaders[shaderColorMatrix].source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer shaders[shaderColorMatrix].native.Delete()
|
||||
defer c.DeleteShader(shaders[shaderColorMatrix].native)
|
||||
|
||||
shaders := []opengl.Shader{
|
||||
shaders[shaderVertex].native,
|
||||
@ -66,31 +66,30 @@ func initialize(c *opengl.Context) error {
|
||||
|
||||
var lastProgram opengl.Program = 0
|
||||
|
||||
func useProgramColorMatrix(projectionMatrix [16]float32, geo Matrix, color Matrix) opengl.Program {
|
||||
func useProgramColorMatrix(c *opengl.Context, projectionMatrix [16]float32, geo Matrix, color Matrix) opengl.Program {
|
||||
if lastProgram != programColorMatrix {
|
||||
programColorMatrix.Use()
|
||||
c.UseProgram(programColorMatrix)
|
||||
lastProgram = programColorMatrix
|
||||
}
|
||||
// TODO: Check the performance.
|
||||
program := programColorMatrix
|
||||
|
||||
program.GetUniformLocation("projection_matrix").UniformMatrix4fv(projectionMatrix)
|
||||
c.UniformMatrix4fv(program, "projection_matrix", projectionMatrix)
|
||||
|
||||
a := float32(geo.Element(0, 0))
|
||||
b := float32(geo.Element(0, 1))
|
||||
c := float32(geo.Element(1, 0))
|
||||
d := float32(geo.Element(1, 1))
|
||||
ma := float32(geo.Element(0, 0))
|
||||
mb := float32(geo.Element(0, 1))
|
||||
mc := float32(geo.Element(1, 0))
|
||||
md := float32(geo.Element(1, 1))
|
||||
tx := float32(geo.Element(0, 2))
|
||||
ty := float32(geo.Element(1, 2))
|
||||
glModelviewMatrix := [...]float32{
|
||||
a, c, 0, 0,
|
||||
b, d, 0, 0,
|
||||
ma, mc, 0, 0,
|
||||
mb, md, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
tx, ty, 0, 1,
|
||||
}
|
||||
program.GetUniformLocation("modelview_matrix").UniformMatrix4fv(glModelviewMatrix)
|
||||
|
||||
program.GetUniformLocation("texture").Uniform1i(0)
|
||||
c.UniformMatrix4fv(program, "modelview_matrix", glModelviewMatrix)
|
||||
c.Uniform1i(program, "texture", 0)
|
||||
|
||||
e := [4][5]float32{}
|
||||
for i := 0; i < 4; i++ {
|
||||
@ -105,11 +104,11 @@ func useProgramColorMatrix(projectionMatrix [16]float32, geo Matrix, color Matri
|
||||
e[0][2], e[1][2], e[2][2], e[3][2],
|
||||
e[0][3], e[1][3], e[2][3], e[3][3],
|
||||
}
|
||||
program.GetUniformLocation("color_matrix").UniformMatrix4fv(glColorMatrix)
|
||||
c.UniformMatrix4fv(program, "color_matrix", glColorMatrix)
|
||||
glColorMatrixTranslation := [...]float32{
|
||||
e[0][4], e[1][4], e[2][4], e[3][4],
|
||||
}
|
||||
program.GetUniformLocation("color_matrix_translation").Uniform4fv(1, glColorMatrixTranslation[:])
|
||||
c.Uniform4fv(program, "color_matrix_translation", glColorMatrixTranslation)
|
||||
|
||||
return program
|
||||
}
|
||||
|
@ -87,11 +87,11 @@ func NewTextureFromImage(c *opengl.Context, img image.Image, filter opengl.Filte
|
||||
return &Texture{native, origSize.X, origSize.Y}, nil
|
||||
}
|
||||
|
||||
func (t *Texture) Dispose() {
|
||||
t.native.Delete()
|
||||
func (t *Texture) Dispose(c *opengl.Context) {
|
||||
c.DeleteTexture(t.native)
|
||||
}
|
||||
|
||||
func (t *Texture) Pixels() ([]uint8, error) {
|
||||
func (t *Texture) Pixels(c *opengl.Context) ([]uint8, error) {
|
||||
w, h := internal.NextPowerOf2Int(t.width), internal.NextPowerOf2Int(t.height)
|
||||
return t.native.Pixels(w, h)
|
||||
return c.TexturePixels(t.native, w, h)
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !js
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
@ -20,107 +22,11 @@ import (
|
||||
"github.com/go-gl/gl"
|
||||
)
|
||||
|
||||
type FilterType int
|
||||
type ShaderType int
|
||||
type BufferType int
|
||||
type BufferUsageType int
|
||||
|
||||
type Texture gl.Texture
|
||||
|
||||
func (t Texture) Pixels(width, height int) ([]uint8, error) {
|
||||
// TODO: Use glGetTexLevelParameteri and GL_TEXTURE_WIDTH?
|
||||
pixels := make([]uint8, 4*width*height)
|
||||
gl.Texture(t).Bind(gl.TEXTURE_2D)
|
||||
gl.GetTexImage(gl.TEXTURE_2D, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
|
||||
if e := gl.GetError(); e != gl.NO_ERROR {
|
||||
// TODO: Use glu.ErrorString
|
||||
return nil, errors.New(fmt.Sprintf("gl error: %d", e))
|
||||
}
|
||||
return pixels, nil
|
||||
}
|
||||
|
||||
func (t Texture) Bind() {
|
||||
gl.Texture(t).Bind(gl.TEXTURE_2D)
|
||||
}
|
||||
|
||||
func (t Texture) Delete() {
|
||||
gl.Texture(t).Delete()
|
||||
}
|
||||
|
||||
type Framebuffer gl.Framebuffer
|
||||
|
||||
func (f Framebuffer) SetAsViewport(width, height int) error {
|
||||
gl.Flush()
|
||||
gl.Framebuffer(f).Bind()
|
||||
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
||||
if err != gl.FRAMEBUFFER_COMPLETE {
|
||||
if gl.GetError() != 0 {
|
||||
return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", gl.GetError()))
|
||||
}
|
||||
return errors.New("glBindFramebuffer failed: the context is different?")
|
||||
}
|
||||
gl.Viewport(0, 0, width, height)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f Framebuffer) Fill(r, g, b, a float64) error {
|
||||
gl.ClearColor(gl.GLclampf(r), gl.GLclampf(g), gl.GLclampf(b), gl.GLclampf(a))
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f Framebuffer) Delete() {
|
||||
gl.Framebuffer(f).Delete()
|
||||
}
|
||||
|
||||
type Shader gl.Shader
|
||||
|
||||
func (s Shader) Delete() {
|
||||
gl.Shader(s).Delete()
|
||||
}
|
||||
|
||||
type Program gl.Program
|
||||
|
||||
func (p Program) Use() {
|
||||
gl.Program(p).Use()
|
||||
}
|
||||
|
||||
func (p Program) GetAttributeLocation(name string) AttribLocation {
|
||||
return AttribLocation(gl.Program(p).GetAttribLocation(name))
|
||||
}
|
||||
|
||||
func (p Program) GetUniformLocation(name string) UniformLocation {
|
||||
return UniformLocation(gl.Program(p).GetUniformLocation(name))
|
||||
}
|
||||
|
||||
type AttribLocation int
|
||||
|
||||
func (a AttribLocation) EnableArray() {
|
||||
gl.AttribLocation(a).EnableArray()
|
||||
}
|
||||
|
||||
func (a AttribLocation) DisableArray() {
|
||||
gl.AttribLocation(a).DisableArray()
|
||||
}
|
||||
|
||||
func (a AttribLocation) AttribPointer(stride int, x uintptr) {
|
||||
gl.AttribLocation(a).AttribPointer(2, gl.FLOAT, false, stride, x)
|
||||
}
|
||||
|
||||
type UniformLocation int
|
||||
|
||||
func (u UniformLocation) UniformMatrix4fv(matrix [16]float32) {
|
||||
gl.UniformLocation(u).UniformMatrix4fv(false, matrix)
|
||||
}
|
||||
|
||||
func (u UniformLocation) Uniform4fv(count int, v []float32) {
|
||||
gl.UniformLocation(u).Uniform4fv(count, v)
|
||||
}
|
||||
|
||||
func (u UniformLocation) Uniform1i(v int) {
|
||||
gl.UniformLocation(u).Uniform1i(v)
|
||||
}
|
||||
|
||||
type Context struct {
|
||||
Nearest FilterType
|
||||
Linear FilterType
|
||||
@ -172,6 +78,26 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter FilterTyp
|
||||
return Texture(t), nil
|
||||
}
|
||||
|
||||
func (c *Context) TexturePixels(t Texture, width, height int) ([]uint8, error) {
|
||||
// TODO: Use glGetTexLevelParameteri and GL_TEXTURE_WIDTH?
|
||||
pixels := make([]uint8, 4*width*height)
|
||||
gl.Texture(t).Bind(gl.TEXTURE_2D)
|
||||
gl.GetTexImage(gl.TEXTURE_2D, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
|
||||
if e := gl.GetError(); e != gl.NO_ERROR {
|
||||
// TODO: Use glu.ErrorString
|
||||
return nil, errors.New(fmt.Sprintf("gl error: %d", e))
|
||||
}
|
||||
return pixels, nil
|
||||
}
|
||||
|
||||
func (c *Context) BindTexture(t Texture) {
|
||||
gl.Texture(t).Bind(gl.TEXTURE_2D)
|
||||
}
|
||||
|
||||
func (c *Context) DeleteTexture(t Texture) {
|
||||
gl.Texture(t).Delete()
|
||||
}
|
||||
|
||||
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
|
||||
f := gl.GenFramebuffer()
|
||||
f.Bind()
|
||||
@ -184,6 +110,30 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
|
||||
return Framebuffer(f), nil
|
||||
}
|
||||
|
||||
func (c *Context) SetViewport(f Framebuffer, width, height int) error {
|
||||
gl.Flush()
|
||||
gl.Framebuffer(f).Bind()
|
||||
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
||||
if err != gl.FRAMEBUFFER_COMPLETE {
|
||||
if gl.GetError() != 0 {
|
||||
return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", gl.GetError()))
|
||||
}
|
||||
return errors.New("glBindFramebuffer failed: the context is different?")
|
||||
}
|
||||
gl.Viewport(0, 0, width, height)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) FillFramebuffer(f Framebuffer, r, g, b, a float64) error {
|
||||
gl.ClearColor(gl.GLclampf(r), gl.GLclampf(g), gl.GLclampf(b), gl.GLclampf(a))
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) DeleteFramebuffer(f Framebuffer) {
|
||||
gl.Framebuffer(f).Delete()
|
||||
}
|
||||
|
||||
func (c *Context) NewShader(shaderType ShaderType, source string) (Shader, error) {
|
||||
s := gl.CreateShader(gl.GLenum(shaderType))
|
||||
if s == 0 {
|
||||
@ -204,6 +154,10 @@ func (c *Context) NewShader(shaderType ShaderType, source string) (Shader, error
|
||||
return Shader(s), nil
|
||||
}
|
||||
|
||||
func (c *Context) DeleteShader(s Shader) {
|
||||
gl.Shader(s).Delete()
|
||||
}
|
||||
|
||||
func (c *Context) NewProgram(shaders []Shader) (Program, error) {
|
||||
p := gl.CreateProgram()
|
||||
if p == 0 {
|
||||
@ -220,6 +174,35 @@ func (c *Context) NewProgram(shaders []Shader) (Program, error) {
|
||||
return Program(p), nil
|
||||
}
|
||||
|
||||
func (c *Context) UseProgram(p Program) {
|
||||
gl.Program(p).Use()
|
||||
}
|
||||
|
||||
func (c *Context) Uniform1i(p Program, location string, v int) {
|
||||
// TODO: Cache the location names.
|
||||
gl.Program(p).GetUniformLocation(location).Uniform1i(v)
|
||||
}
|
||||
|
||||
func (c *Context) Uniform4fv(p Program, location string, v [4]float32) {
|
||||
gl.Program(p).GetUniformLocation(location).Uniform4fv(1, v[:])
|
||||
}
|
||||
|
||||
func (c *Context) UniformMatrix4fv(p Program, location string, v [16]float32) {
|
||||
gl.Program(p).GetUniformLocation(location).UniformMatrix4fv(false, v)
|
||||
}
|
||||
|
||||
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) {
|
||||
gl.Program(p).GetAttribLocation(location).AttribPointer(2, gl.FLOAT, false, stride, v)
|
||||
}
|
||||
|
||||
func (c *Context) EnableVertexAttribArray(p Program, location string) {
|
||||
gl.Program(p).GetAttribLocation(location).EnableArray()
|
||||
}
|
||||
|
||||
func (c *Context) DisableVertexAttribArray(p Program, location string) {
|
||||
gl.Program(p).GetAttribLocation(location).DisableArray()
|
||||
}
|
||||
|
||||
func (c *Context) NewBuffer(bufferType BufferType, size int, ptr interface{}, bufferUsageType BufferUsageType) {
|
||||
gl.GenBuffer().Bind(gl.GLenum(bufferType))
|
||||
gl.BufferData(gl.GLenum(bufferType), size, ptr, gl.GLenum(bufferUsageType))
|
||||
|
20
internal/opengl/types.go
Normal file
20
internal/opengl/types.go
Normal file
@ -0,0 +1,20 @@
|
||||
// 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
|
||||
|
||||
type FilterType int
|
||||
type ShaderType int
|
||||
type BufferType int
|
||||
type BufferUsageType int
|
Loading…
Reference in New Issue
Block a user