mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Use go-gl/gl
This commit is contained in:
parent
1591e8299b
commit
ca56d05dfa
@ -1,23 +1,17 @@
|
||||
package opengl
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <stdlib.h>
|
||||
// #include <OpenGL/gl.h>
|
||||
import "C"
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten/graphics"
|
||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func enableAlphaBlending() {
|
||||
C.glEnable(C.GL_TEXTURE_2D)
|
||||
C.glEnable(C.GL_BLEND)
|
||||
func flush() {
|
||||
gl.Flush()
|
||||
}
|
||||
|
||||
func flush() {
|
||||
C.glFlush()
|
||||
}
|
||||
var onceInit sync.Once
|
||||
|
||||
type Context struct {
|
||||
screenId graphics.RenderTargetId
|
||||
@ -29,11 +23,18 @@ type Context struct {
|
||||
}
|
||||
|
||||
func NewContext(screenWidth, screenHeight, screenScale int) *Context {
|
||||
onceInit.Do(func() {
|
||||
gl.Init()
|
||||
gl.Enable(gl.TEXTURE_2D)
|
||||
gl.Enable(gl.BLEND)
|
||||
})
|
||||
|
||||
context := &Context{
|
||||
screenWidth: screenWidth,
|
||||
screenHeight: screenHeight,
|
||||
screenScale: screenScale,
|
||||
}
|
||||
|
||||
defaultRenderTarget := &RenderTarget{
|
||||
width: screenWidth * screenScale,
|
||||
height: screenHeight * screenScale,
|
||||
@ -49,8 +50,6 @@ func NewContext(screenWidth, screenHeight, screenScale int) *Context {
|
||||
context.ResetOffscreen()
|
||||
context.Clear()
|
||||
|
||||
enableAlphaBlending()
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
package opengl
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <OpenGL/gl.h>
|
||||
import "C"
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten/graphics"
|
||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
||||
"github.com/hajimehoshi/ebiten/graphics/opengl/internal/shader"
|
||||
@ -69,8 +66,7 @@ func (i *ids) toTexture(id graphics.RenderTargetId) graphics.TextureId {
|
||||
return i.renderTargetToTexture[id]
|
||||
}
|
||||
|
||||
func (i *ids) createTexture(img image.Image, filter graphics.Filter) (
|
||||
graphics.TextureId, error) {
|
||||
func (i *ids) createTexture(img image.Image, filter graphics.Filter) (graphics.TextureId, error) {
|
||||
texture, err := createTextureFromImage(img, filter)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -84,14 +80,12 @@ func (i *ids) createTexture(img image.Image, filter graphics.Filter) (
|
||||
return textureId, nil
|
||||
}
|
||||
|
||||
func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (
|
||||
graphics.RenderTargetId, error) {
|
||||
|
||||
func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (graphics.RenderTargetId, error) {
|
||||
texture, err := createTexture(width, height, filter)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
framebuffer := createFramebuffer(texture.native)
|
||||
framebuffer := createFramebuffer(gl.Texture(texture.native))
|
||||
// The current binded framebuffer can be changed.
|
||||
i.currentRenderTargetId = -1
|
||||
renderTarget := &RenderTarget{
|
||||
@ -144,12 +138,8 @@ func (i *ids) deleteRenderTarget(id graphics.RenderTargetId) {
|
||||
func (i *ids) fillRenderTarget(id graphics.RenderTargetId, r, g, b uint8) {
|
||||
i.setViewportIfNeeded(id)
|
||||
const max = float64(math.MaxUint8)
|
||||
C.glClearColor(
|
||||
C.GLclampf(float64(r)/max),
|
||||
C.GLclampf(float64(g)/max),
|
||||
C.GLclampf(float64(b)/max),
|
||||
1)
|
||||
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
||||
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(
|
||||
@ -163,12 +153,7 @@ func (i *ids) drawTexture(
|
||||
r := i.renderTargetAt(target)
|
||||
projectionMatrix := r.projectionMatrix()
|
||||
quads := graphics.TextureQuads(parts, texture.width, texture.height)
|
||||
shader.DrawTexture(
|
||||
shader.NativeTexture(texture.native),
|
||||
glMatrix(projectionMatrix),
|
||||
quads,
|
||||
geo,
|
||||
color)
|
||||
shader.DrawTexture(texture.native, glMatrix(projectionMatrix), quads, geo, color)
|
||||
}
|
||||
|
||||
func (i *ids) setViewportIfNeeded(id graphics.RenderTargetId) {
|
||||
|
@ -1,23 +1,15 @@
|
||||
package shader
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <OpenGL/gl.h>
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten/graphics"
|
||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type NativeTexture C.GLuint
|
||||
|
||||
var once sync.Once
|
||||
|
||||
func DrawTexture(native NativeTexture, projectionMatrix [16]float32,
|
||||
quads []graphics.TextureQuad, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
||||
func DrawTexture(native gl.Texture, projectionMatrix [16]float32, quads []graphics.TextureQuad, geo matrix.Geometry, color matrix.Color) {
|
||||
once.Do(func() {
|
||||
initialize()
|
||||
})
|
||||
@ -26,23 +18,23 @@ func DrawTexture(native NativeTexture, projectionMatrix [16]float32,
|
||||
return
|
||||
}
|
||||
// TODO: Check performance
|
||||
shaderProgram := use(projectionMatrix, geometryMatrix, colorMatrix)
|
||||
shaderProgram := use(projectionMatrix, geo, color)
|
||||
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, C.GLuint(native))
|
||||
defer C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||
native.Bind(gl.TEXTURE_2D)
|
||||
defer gl.Texture(0).Bind(gl.TEXTURE_2D)
|
||||
|
||||
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
||||
texCoordAttrLocation := getAttributeLocation(shaderProgram, "tex_coord")
|
||||
|
||||
C.glEnableClientState(C.GL_VERTEX_ARRAY)
|
||||
C.glEnableClientState(C.GL_TEXTURE_COORD_ARRAY)
|
||||
C.glEnableVertexAttribArray(C.GLuint(vertexAttrLocation))
|
||||
C.glEnableVertexAttribArray(C.GLuint(texCoordAttrLocation))
|
||||
gl.EnableClientState(gl.VERTEX_ARRAY)
|
||||
gl.EnableClientState(gl.TEXTURE_COORD_ARRAY)
|
||||
vertexAttrLocation.EnableArray()
|
||||
texCoordAttrLocation.EnableArray()
|
||||
defer func() {
|
||||
C.glDisableVertexAttribArray(C.GLuint(texCoordAttrLocation))
|
||||
C.glDisableVertexAttribArray(C.GLuint(vertexAttrLocation))
|
||||
C.glDisableClientState(C.GL_TEXTURE_COORD_ARRAY)
|
||||
C.glDisableClientState(C.GL_VERTEX_ARRAY)
|
||||
texCoordAttrLocation.DisableArray()
|
||||
vertexAttrLocation.DisableArray()
|
||||
gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)
|
||||
gl.DisableClientState(gl.VERTEX_ARRAY)
|
||||
}()
|
||||
|
||||
vertices := []float32{}
|
||||
@ -76,12 +68,7 @@ func DrawTexture(native NativeTexture, projectionMatrix [16]float32,
|
||||
base+1, base+2, base+3,
|
||||
)
|
||||
}
|
||||
C.glVertexAttribPointer(C.GLuint(vertexAttrLocation), 2,
|
||||
C.GL_FLOAT, C.GL_FALSE,
|
||||
0, unsafe.Pointer(&vertices[0]))
|
||||
C.glVertexAttribPointer(C.GLuint(texCoordAttrLocation), 2,
|
||||
C.GL_FLOAT, C.GL_FALSE,
|
||||
0, unsafe.Pointer(&texCoords[0]))
|
||||
C.glDrawElements(C.GL_TRIANGLES, C.GLsizei(len(indicies)),
|
||||
C.GL_UNSIGNED_INT, unsafe.Pointer(&indicies[0]))
|
||||
vertexAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, vertices)
|
||||
texCoordAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords)
|
||||
gl.DrawElements(gl.TRIANGLES, len(indicies), gl.UNSIGNED_INT, indicies)
|
||||
}
|
||||
|
@ -1,17 +1,12 @@
|
||||
package shader
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <OpenGL/gl.h>
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type program struct {
|
||||
native C.GLuint
|
||||
native gl.Program
|
||||
shaderIds []shaderId
|
||||
}
|
||||
|
||||
@ -33,18 +28,16 @@ var programs = map[programId]*program{
|
||||
}
|
||||
|
||||
func (p *program) create() {
|
||||
p.native = C.glCreateProgram()
|
||||
p.native = gl.CreateProgram()
|
||||
if p.native == 0 {
|
||||
panic("glCreateProgram failed")
|
||||
}
|
||||
|
||||
for _, shaderId := range p.shaderIds {
|
||||
C.glAttachShader(p.native, shaders[shaderId].native)
|
||||
p.native.AttachShader(shaders[shaderId].native)
|
||||
}
|
||||
C.glLinkProgram(p.native)
|
||||
linked := C.GLint(C.GL_FALSE)
|
||||
C.glGetProgramiv(p.native, C.GL_LINK_STATUS, &linked)
|
||||
if linked == C.GL_FALSE {
|
||||
p.native.Link()
|
||||
if p.native.Get(gl.LINK_STATUS) == gl.FALSE {
|
||||
panic("program error")
|
||||
}
|
||||
}
|
||||
@ -72,57 +65,49 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
shaderLocationCache = map[qualifierVariableType]map[string]C.GLint{
|
||||
qualifierVariableTypeAttribute: map[string]C.GLint{},
|
||||
qualifierVariableTypeUniform: map[string]C.GLint{},
|
||||
shaderLocationCache = map[qualifierVariableType]map[string]gl.AttribLocation{
|
||||
qualifierVariableTypeAttribute: map[string]gl.AttribLocation{},
|
||||
qualifierVariableTypeUniform: map[string]gl.AttribLocation{},
|
||||
}
|
||||
)
|
||||
|
||||
func getLocation(program C.GLuint, name string, qvType qualifierVariableType) C.GLint {
|
||||
func getLocation(program gl.Program, name string, qvType qualifierVariableType) gl.AttribLocation {
|
||||
if location, ok := shaderLocationCache[qvType][name]; ok {
|
||||
return location
|
||||
}
|
||||
|
||||
locationName := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(locationName))
|
||||
|
||||
const invalidLocation = -1
|
||||
location := C.GLint(invalidLocation)
|
||||
|
||||
location := gl.AttribLocation(-1)
|
||||
switch qvType {
|
||||
case qualifierVariableTypeAttribute:
|
||||
location = C.glGetAttribLocation(program, (*C.GLchar)(locationName))
|
||||
location = program.GetAttribLocation(name)
|
||||
case qualifierVariableTypeUniform:
|
||||
location = C.glGetUniformLocation(program, (*C.GLchar)(locationName))
|
||||
location = gl.AttribLocation(program.GetUniformLocation(name))
|
||||
default:
|
||||
panic("no reach")
|
||||
}
|
||||
if location == invalidLocation {
|
||||
panic("glGetUniformLocation failed")
|
||||
if location == -1 {
|
||||
panic("GetAttribLocation failed")
|
||||
}
|
||||
shaderLocationCache[qvType][name] = location
|
||||
|
||||
return location
|
||||
}
|
||||
|
||||
func getAttributeLocation(program C.GLuint, name string) C.GLint {
|
||||
func getAttributeLocation(program gl.Program, name string) gl.AttribLocation {
|
||||
return getLocation(program, name, qualifierVariableTypeAttribute)
|
||||
}
|
||||
|
||||
func getUniformLocation(program C.GLuint, name string) C.GLint {
|
||||
return getLocation(program, name, qualifierVariableTypeUniform)
|
||||
func getUniformLocation(program gl.Program, name string) gl.UniformLocation {
|
||||
return gl.UniformLocation(getLocation(program, name, qualifierVariableTypeUniform))
|
||||
}
|
||||
|
||||
func use(projectionMatrix [16]float32,
|
||||
geometryMatrix matrix.Geometry,
|
||||
colorMatrix matrix.Color) C.GLuint {
|
||||
func use(projectionMatrix [16]float32, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) gl.Program {
|
||||
programId := programColorMatrix
|
||||
program := programs[programId]
|
||||
// TODO: Check the performance.
|
||||
C.glUseProgram(program.native)
|
||||
program.native.Use()
|
||||
|
||||
C.glUniformMatrix4fv(C.GLint(getUniformLocation(program.native, "projection_matrix")),
|
||||
1, C.GL_FALSE, (*C.GLfloat)(&projectionMatrix[0]))
|
||||
getUniformLocation(program.native, "projection_matrix").UniformMatrix4fv(false, projectionMatrix)
|
||||
|
||||
a := float32(geometryMatrix.Elements[0][0])
|
||||
b := float32(geometryMatrix.Elements[0][1])
|
||||
@ -136,11 +121,9 @@ func use(projectionMatrix [16]float32,
|
||||
0, 0, 1, 0,
|
||||
tx, ty, 0, 1,
|
||||
}
|
||||
C.glUniformMatrix4fv(getUniformLocation(program.native, "modelview_matrix"),
|
||||
1, C.GL_FALSE,
|
||||
(*C.GLfloat)(&glModelviewMatrix[0]))
|
||||
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
|
||||
|
||||
C.glUniform1i(getUniformLocation(program.native, "texture"), 0)
|
||||
getUniformLocation(program.native, "texture").Uniform1i(0)
|
||||
|
||||
e := [4][5]float32{}
|
||||
for i := 0; i < 4; i++ {
|
||||
@ -155,14 +138,11 @@ func use(projectionMatrix [16]float32,
|
||||
e[0][2], e[1][2], e[2][2], e[3][2],
|
||||
e[0][3], e[1][3], e[2][3], e[3][3],
|
||||
}
|
||||
C.glUniformMatrix4fv(getUniformLocation(program.native, "color_matrix"),
|
||||
1, C.GL_FALSE, (*C.GLfloat)(&glColorMatrix[0]))
|
||||
|
||||
getUniformLocation(program.native, "color_matrix").UniformMatrix4fv(false, glColorMatrix)
|
||||
glColorMatrixTranslation := [...]float32{
|
||||
e[0][4], e[1][4], e[2][4], e[3][4],
|
||||
}
|
||||
C.glUniform4fv(getUniformLocation(program.native, "color_matrix_translation"),
|
||||
1, (*C.GLfloat)(&glColorMatrixTranslation[0]))
|
||||
getUniformLocation(program.native, "color_matrix_translation").Uniform4fv(1, glColorMatrixTranslation[:])
|
||||
|
||||
return program.native
|
||||
}
|
||||
|
@ -1,18 +1,13 @@
|
||||
package shader
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <OpenGL/gl.h>
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
"github.com/go-gl/gl"
|
||||
"log"
|
||||
)
|
||||
|
||||
type shader struct {
|
||||
native C.GLuint
|
||||
shaderType C.GLenum
|
||||
native gl.Shader
|
||||
shaderType gl.GLenum
|
||||
source string
|
||||
}
|
||||
|
||||
@ -27,7 +22,7 @@ const (
|
||||
|
||||
var shaders = map[shaderId]*shader{
|
||||
shaderVertex: &shader{
|
||||
shaderType: C.GL_VERTEX_SHADER,
|
||||
shaderType: gl.VERTEX_SHADER,
|
||||
source: `
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
@ -42,7 +37,7 @@ void main(void) {
|
||||
`,
|
||||
},
|
||||
shaderFragment: &shader{
|
||||
shaderType: C.GL_FRAGMENT_SHADER,
|
||||
shaderType: gl.FRAGMENT_SHADER,
|
||||
source: `
|
||||
uniform sampler2D texture;
|
||||
varying vec2 vertex_out_tex_coord;
|
||||
@ -53,7 +48,7 @@ void main(void) {
|
||||
`,
|
||||
},
|
||||
shaderColorMatrix: &shader{
|
||||
shaderType: C.GL_FRAGMENT_SHADER,
|
||||
shaderType: gl.FRAGMENT_SHADER,
|
||||
source: `
|
||||
uniform sampler2D texture;
|
||||
uniform mat4 color_matrix;
|
||||
@ -67,7 +62,7 @@ void main(void) {
|
||||
`,
|
||||
},
|
||||
shaderSolidColor: &shader{
|
||||
shaderType: C.GL_FRAGMENT_SHADER,
|
||||
shaderType: gl.FRAGMENT_SHADER,
|
||||
source: `
|
||||
uniform vec4 color;
|
||||
|
||||
@ -79,40 +74,27 @@ void main(void) {
|
||||
}
|
||||
|
||||
func (s *shader) compile() {
|
||||
s.native = C.glCreateShader(s.shaderType)
|
||||
s.native = gl.CreateShader(s.shaderType)
|
||||
if s.native == 0 {
|
||||
panic("glCreateShader failed")
|
||||
}
|
||||
|
||||
csource := (*C.GLchar)(C.CString(s.source))
|
||||
// TODO: defer?
|
||||
// defer C.free(unsafe.Pointer(csource))
|
||||
s.native.Source(s.source)
|
||||
s.native.Compile()
|
||||
|
||||
C.glShaderSource(s.native, 1, &csource, nil)
|
||||
C.glCompileShader(s.native)
|
||||
|
||||
compiled := C.GLint(C.GL_FALSE)
|
||||
C.glGetShaderiv(s.native, C.GL_COMPILE_STATUS, &compiled)
|
||||
if compiled == C.GL_FALSE {
|
||||
if s.native.Get(gl.COMPILE_STATUS) == gl.FALSE {
|
||||
s.showShaderLog()
|
||||
panic("shader compile failed")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *shader) showShaderLog() {
|
||||
logSize := C.GLint(0)
|
||||
C.glGetShaderiv(s.native, C.GL_INFO_LOG_LENGTH, &logSize)
|
||||
if logSize == 0 {
|
||||
if s.native.Get(gl.INFO_LOG_LENGTH) == 0 {
|
||||
return
|
||||
}
|
||||
length := C.GLsizei(0)
|
||||
buffer := make([]C.GLchar, logSize)
|
||||
C.glGetShaderInfoLog(s.native, C.GLsizei(logSize), &length, &buffer[0])
|
||||
|
||||
message := string(C.GoBytes(unsafe.Pointer(&buffer[0]), C.int(length)))
|
||||
fmt.Printf("shader error: %s\n", message)
|
||||
log.Fatalf("shader error: %s\n", s.native.GetInfoLog())
|
||||
}
|
||||
|
||||
func (s *shader) delete() {
|
||||
C.glDeleteShader(s.native)
|
||||
s.native.Delete()
|
||||
}
|
||||
|
@ -1,57 +1,49 @@
|
||||
package opengl
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <OpenGL/gl.h>
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten/graphics"
|
||||
)
|
||||
|
||||
type RenderTarget struct {
|
||||
framebuffer C.GLuint
|
||||
framebuffer gl.Framebuffer
|
||||
width int
|
||||
height int
|
||||
flipY bool
|
||||
}
|
||||
|
||||
func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
|
||||
framebuffer := C.GLuint(0)
|
||||
C.glGenFramebuffers(1, &framebuffer)
|
||||
func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
|
||||
framebuffer := gl.GenFramebuffer()
|
||||
framebuffer.Bind()
|
||||
|
||||
C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer)
|
||||
|
||||
C.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0,
|
||||
C.GL_TEXTURE_2D, nativeTexture, 0)
|
||||
if C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) !=
|
||||
C.GL_FRAMEBUFFER_COMPLETE {
|
||||
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
|
||||
gl.TEXTURE_2D, nativeTexture, 0)
|
||||
if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE {
|
||||
panic("creating framebuffer failed")
|
||||
}
|
||||
|
||||
// Set this framebuffer opaque because alpha values on a target might be
|
||||
// confusing.
|
||||
C.glClearColor(0, 0, 0, 1)
|
||||
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
||||
gl.ClearColor(0, 0, 0, 1)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
|
||||
return framebuffer
|
||||
}
|
||||
|
||||
func (r *RenderTarget) setAsViewport() {
|
||||
C.glFlush()
|
||||
|
||||
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer))
|
||||
err := C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER)
|
||||
if err != C.GL_FRAMEBUFFER_COMPLETE {
|
||||
gl.Flush()
|
||||
r.framebuffer.Bind()
|
||||
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
||||
if err != gl.FRAMEBUFFER_COMPLETE {
|
||||
panic(fmt.Sprintf("glBindFramebuffer failed: %d", err))
|
||||
}
|
||||
|
||||
C.glBlendFuncSeparate(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA,
|
||||
C.GL_ZERO, C.GL_ONE)
|
||||
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE)
|
||||
|
||||
width := graphics.AdjustSizeForTexture(r.width)
|
||||
height := graphics.AdjustSizeForTexture(r.height)
|
||||
C.glViewport(0, 0, C.GLsizei(width), C.GLsizei(height))
|
||||
gl.Viewport(0, 0, width, height)
|
||||
}
|
||||
|
||||
func (r *RenderTarget) projectionMatrix() [4][4]float64 {
|
||||
@ -67,5 +59,5 @@ func (r *RenderTarget) projectionMatrix() [4][4]float64 {
|
||||
}
|
||||
|
||||
func (r *RenderTarget) dispose() {
|
||||
C.glDeleteFramebuffers(1, &r.framebuffer)
|
||||
r.framebuffer.Delete()
|
||||
}
|
||||
|
@ -1,72 +1,55 @@
|
||||
package opengl
|
||||
|
||||
// #cgo LDFLAGS: -framework OpenGL
|
||||
//
|
||||
// #include <OpenGL/gl.h>
|
||||
import "C"
|
||||
import (
|
||||
"github.com/go-gl/gl"
|
||||
"github.com/hajimehoshi/ebiten/graphics"
|
||||
"image"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Texture struct {
|
||||
native C.GLuint
|
||||
native gl.Texture
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
func createNativeTexture(
|
||||
textureWidth, textureHeight int,
|
||||
pixels []uint8,
|
||||
filter graphics.Filter) C.GLuint {
|
||||
nativeTexture := C.GLuint(0)
|
||||
|
||||
C.glGenTextures(1, &nativeTexture)
|
||||
func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter graphics.Filter) gl.Texture {
|
||||
nativeTexture := gl.GenTexture()
|
||||
if nativeTexture < 0 {
|
||||
panic("glGenTexture failed")
|
||||
}
|
||||
C.glPixelStorei(C.GL_UNPACK_ALIGNMENT, 4)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, C.GLuint(nativeTexture))
|
||||
defer C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||
gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4)
|
||||
nativeTexture.Bind(gl.TEXTURE_2D)
|
||||
defer gl.Texture(0).Bind(gl.TEXTURE_2D)
|
||||
|
||||
glFilter := C.GLint(0)
|
||||
glFilter := 0
|
||||
switch filter {
|
||||
case graphics.FilterLinear:
|
||||
glFilter = C.GL_LINEAR
|
||||
glFilter = gl.LINEAR
|
||||
case graphics.FilterNearest:
|
||||
glFilter = C.GL_NEAREST
|
||||
glFilter = gl.NEAREST
|
||||
default:
|
||||
panic("not reached")
|
||||
}
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, glFilter)
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, glFilter)
|
||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter)
|
||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter)
|
||||
|
||||
ptr := unsafe.Pointer(nil)
|
||||
ptr := interface{}(nil)
|
||||
if pixels != nil {
|
||||
ptr = unsafe.Pointer(&pixels[0])
|
||||
ptr = pixels
|
||||
}
|
||||
C.glTexImage2D(C.GL_TEXTURE_2D, 0, C.GL_RGBA,
|
||||
C.GLsizei(textureWidth), C.GLsizei(textureHeight),
|
||||
0, C.GL_RGBA, C.GL_UNSIGNED_BYTE, ptr)
|
||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, textureWidth, textureHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, ptr)
|
||||
|
||||
return nativeTexture
|
||||
}
|
||||
|
||||
func createTexture(
|
||||
width, height int,
|
||||
filter graphics.Filter) (*Texture, error) {
|
||||
native := createNativeTexture(
|
||||
graphics.AdjustSizeForTexture(width),
|
||||
graphics.AdjustSizeForTexture(height),
|
||||
nil,
|
||||
filter)
|
||||
func createTexture(width, height int, filter graphics.Filter) (*Texture, error) {
|
||||
w := graphics.AdjustSizeForTexture(width)
|
||||
h := graphics.AdjustSizeForTexture(height)
|
||||
native := createNativeTexture(w, h, nil, filter)
|
||||
return &Texture{native, width, height}, nil
|
||||
}
|
||||
|
||||
func createTextureFromImage(
|
||||
img image.Image,
|
||||
filter graphics.Filter) (*Texture, error) {
|
||||
func createTextureFromImage(img image.Image, filter graphics.Filter) (*Texture, error) {
|
||||
adjustedImage := graphics.AdjustImageForTexture(img)
|
||||
size := adjustedImage.Bounds().Size()
|
||||
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
|
||||
@ -74,5 +57,5 @@ func createTextureFromImage(
|
||||
}
|
||||
|
||||
func (t *Texture) dispose() {
|
||||
C.glDeleteTextures(1, &t.native)
|
||||
t.native.Delete()
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ func (i *InputState) PressedKeys() ui.Keys {
|
||||
}
|
||||
|
||||
func (i *InputState) MouseX() int {
|
||||
// TODO: Update
|
||||
return i.mouseX
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user