mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 12:08:58 +01:00
Refactoring
This commit is contained in:
parent
63fc25d24c
commit
d087333e48
@ -41,7 +41,7 @@ func main() {
|
|||||||
|
|
||||||
textureCreated := textureFactory.TextureCreated()
|
textureCreated := textureFactory.TextureCreated()
|
||||||
renderTargetCreated := textureFactory.RenderTargetCreated()
|
renderTargetCreated := textureFactory.RenderTargetCreated()
|
||||||
|
|
||||||
for tag, path := range TexturePaths {
|
for tag, path := range TexturePaths {
|
||||||
tag := tag
|
tag := tag
|
||||||
path := path
|
path := path
|
||||||
|
@ -20,7 +20,7 @@ type TexturePart struct {
|
|||||||
type Line struct {
|
type Line struct {
|
||||||
X1, Y1 int
|
X1, Y1 int
|
||||||
X2, Y2 int
|
X2, Y2 int
|
||||||
Color color.Color
|
Color color.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextureId int
|
type TextureId int
|
||||||
|
@ -10,49 +10,59 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func createProgram(shaders ...*shader) C.GLuint {
|
type program struct {
|
||||||
program := C.glCreateProgram()
|
native C.GLuint
|
||||||
for _, shader := range shaders {
|
shaderIds []shaderId
|
||||||
C.glAttachShader(program, shader.id)
|
}
|
||||||
|
|
||||||
|
type programId int
|
||||||
|
|
||||||
|
const (
|
||||||
|
programRegular programId = iota
|
||||||
|
programColorMatrix
|
||||||
|
)
|
||||||
|
|
||||||
|
var programs = map[programId]*program{
|
||||||
|
programRegular: &program{
|
||||||
|
shaderIds: []shaderId{shaderVertex, shaderFragment},
|
||||||
|
},
|
||||||
|
programColorMatrix: &program{
|
||||||
|
shaderIds: []shaderId{shaderVertex, shaderColorMatrix},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *program) create() {
|
||||||
|
p.native = C.glCreateProgram()
|
||||||
|
if p.native == 0 {
|
||||||
|
panic("glCreateProgram failed")
|
||||||
}
|
}
|
||||||
C.glLinkProgram(program)
|
|
||||||
|
for _, shaderId := range p.shaderIds {
|
||||||
|
C.glAttachShader(p.native, shaders[shaderId].native)
|
||||||
|
}
|
||||||
|
C.glLinkProgram(p.native)
|
||||||
linked := C.GLint(C.GL_FALSE)
|
linked := C.GLint(C.GL_FALSE)
|
||||||
C.glGetProgramiv(program, C.GL_LINK_STATUS, &linked)
|
C.glGetProgramiv(p.native, C.GL_LINK_STATUS, &linked)
|
||||||
if linked == C.GL_FALSE {
|
if linked == C.GL_FALSE {
|
||||||
panic("program error")
|
panic("program error")
|
||||||
}
|
}
|
||||||
return program
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var initialized = false
|
||||||
initialized = false
|
|
||||||
)
|
|
||||||
|
|
||||||
func initialize() {
|
func initialize() {
|
||||||
// TODO: when should this function be called?
|
for _, shader := range shaders {
|
||||||
vertexShader.id = C.glCreateShader(C.GL_VERTEX_SHADER)
|
shader.compile()
|
||||||
if vertexShader.id == 0 {
|
|
||||||
panic("creating shader failed")
|
|
||||||
}
|
}
|
||||||
fragmentShader.id = C.glCreateShader(C.GL_FRAGMENT_SHADER)
|
defer func() {
|
||||||
if fragmentShader.id == 0 {
|
for _, shader := range shaders {
|
||||||
panic("creating shader failed")
|
shader.delete()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for _, program := range programs {
|
||||||
|
program.create()
|
||||||
}
|
}
|
||||||
colorMatrixShader.id = C.glCreateShader(C.GL_FRAGMENT_SHADER)
|
|
||||||
if colorMatrixShader.id == 0 {
|
|
||||||
panic("creating shader failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexShader.compile()
|
|
||||||
fragmentShader.compile()
|
|
||||||
colorMatrixShader.compile()
|
|
||||||
|
|
||||||
programRegular = createProgram(vertexShader, fragmentShader)
|
|
||||||
programColorMatrix = createProgram(vertexShader, colorMatrixShader)
|
|
||||||
|
|
||||||
C.glDeleteShader(vertexShader.id)
|
|
||||||
C.glDeleteShader(fragmentShader.id)
|
|
||||||
C.glDeleteShader(colorMatrixShader.id)
|
|
||||||
|
|
||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
@ -105,13 +115,14 @@ func getUniformLocation(program C.GLuint, name string) C.GLint {
|
|||||||
|
|
||||||
func use(projectionMatrix [16]float32,
|
func use(projectionMatrix [16]float32,
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) C.GLuint {
|
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) C.GLuint {
|
||||||
program := programRegular
|
programId := programRegular
|
||||||
if !colorMatrix.IsIdentity() {
|
if !colorMatrix.IsIdentity() {
|
||||||
program = programColorMatrix
|
programId = programColorMatrix
|
||||||
}
|
}
|
||||||
C.glUseProgram(program)
|
program := programs[programId]
|
||||||
|
C.glUseProgram(program.native)
|
||||||
|
|
||||||
C.glUniformMatrix4fv(C.GLint(getUniformLocation(program, "projection_matrix")),
|
C.glUniformMatrix4fv(C.GLint(getUniformLocation(program.native, "projection_matrix")),
|
||||||
1, C.GL_FALSE, (*C.GLfloat)(&projectionMatrix[0]))
|
1, C.GL_FALSE, (*C.GLfloat)(&projectionMatrix[0]))
|
||||||
|
|
||||||
a := float32(geometryMatrix.Elements[0][0])
|
a := float32(geometryMatrix.Elements[0][0])
|
||||||
@ -126,14 +137,14 @@ func use(projectionMatrix [16]float32,
|
|||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
tx, ty, 0, 1,
|
tx, ty, 0, 1,
|
||||||
}
|
}
|
||||||
C.glUniformMatrix4fv(getUniformLocation(program, "modelview_matrix"),
|
C.glUniformMatrix4fv(getUniformLocation(program.native, "modelview_matrix"),
|
||||||
1, C.GL_FALSE,
|
1, C.GL_FALSE,
|
||||||
(*C.GLfloat)(&glModelviewMatrix[0]))
|
(*C.GLfloat)(&glModelviewMatrix[0]))
|
||||||
|
|
||||||
C.glUniform1i(getUniformLocation(program, "texture"), 0)
|
C.glUniform1i(getUniformLocation(program.native, "texture"), 0)
|
||||||
|
|
||||||
if program != programColorMatrix {
|
if programId != programColorMatrix {
|
||||||
return program
|
return program.native
|
||||||
}
|
}
|
||||||
|
|
||||||
e := [4][5]float32{}
|
e := [4][5]float32{}
|
||||||
@ -149,14 +160,14 @@ func use(projectionMatrix [16]float32,
|
|||||||
e[0][2], e[1][2], e[2][2], e[3][2],
|
e[0][2], e[1][2], e[2][2], e[3][2],
|
||||||
e[0][3], e[1][3], e[2][3], e[3][3],
|
e[0][3], e[1][3], e[2][3], e[3][3],
|
||||||
}
|
}
|
||||||
C.glUniformMatrix4fv(getUniformLocation(program, "color_matrix"),
|
C.glUniformMatrix4fv(getUniformLocation(program.native, "color_matrix"),
|
||||||
1, C.GL_FALSE, (*C.GLfloat)(&glColorMatrix[0]))
|
1, C.GL_FALSE, (*C.GLfloat)(&glColorMatrix[0]))
|
||||||
|
|
||||||
glColorMatrixTranslation := [...]float32{
|
glColorMatrixTranslation := [...]float32{
|
||||||
e[0][4], e[1][4], e[2][4], e[3][4],
|
e[0][4], e[1][4], e[2][4], e[3][4],
|
||||||
}
|
}
|
||||||
C.glUniform4fv(getUniformLocation(program, "color_matrix_translation"),
|
C.glUniform4fv(getUniformLocation(program.native, "color_matrix_translation"),
|
||||||
1, (*C.GLfloat)(&glColorMatrixTranslation[0]))
|
1, (*C.GLfloat)(&glColorMatrixTranslation[0]))
|
||||||
|
|
||||||
return program
|
return program.native
|
||||||
}
|
}
|
||||||
|
@ -6,92 +6,113 @@ package shader
|
|||||||
// #include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shader struct {
|
type shader struct {
|
||||||
id C.GLuint
|
native C.GLuint
|
||||||
name string
|
shaderType C.GLenum
|
||||||
source string
|
source string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
type shaderId int
|
||||||
vertexShader = &shader{
|
|
||||||
id: 0,
|
const (
|
||||||
name: "vertex_shader",
|
shaderVertex shaderId = iota
|
||||||
|
shaderFragment
|
||||||
|
shaderColorMatrix
|
||||||
|
shaderSolidColor
|
||||||
|
)
|
||||||
|
|
||||||
|
var shaders = map[shaderId]*shader{
|
||||||
|
shaderVertex: &shader{
|
||||||
|
shaderType: C.GL_VERTEX_SHADER,
|
||||||
source: `
|
source: `
|
||||||
attribute /*highp*/ vec2 vertex;
|
attribute vec2 vertex;
|
||||||
attribute /*highp*/ vec2 texture;
|
attribute vec2 texture;
|
||||||
uniform /*highp*/ mat4 projection_matrix;
|
uniform mat4 projection_matrix;
|
||||||
uniform /*highp*/ mat4 modelview_matrix;
|
uniform mat4 modelview_matrix;
|
||||||
varying /*highp*/ vec2 tex_coord;
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
tex_coord = texture;
|
tex_coord = texture;
|
||||||
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
|
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
}
|
},
|
||||||
fragmentShader = &shader{
|
shaderFragment: &shader{
|
||||||
id: 0,
|
shaderType: C.GL_FRAGMENT_SHADER,
|
||||||
name: "fragment_shader",
|
|
||||||
source: `
|
source: `
|
||||||
uniform /*lowp*/ sampler2D texture;
|
uniform sampler2D texture;
|
||||||
varying /*highp*/ vec2 tex_coord;
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_FragColor = texture2D(texture, tex_coord);
|
gl_FragColor = texture2D(texture, tex_coord);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
}
|
},
|
||||||
colorMatrixShader = &shader{
|
shaderColorMatrix: &shader{
|
||||||
id: 0,
|
shaderType: C.GL_FRAGMENT_SHADER,
|
||||||
name: "color_matrix_shader",
|
|
||||||
source: `
|
source: `
|
||||||
uniform /*highp*/ sampler2D texture;
|
uniform sampler2D texture;
|
||||||
uniform /*lowp*/ mat4 color_matrix;
|
uniform mat4 color_matrix;
|
||||||
uniform /*lowp*/ vec4 color_matrix_translation;
|
uniform vec4 color_matrix_translation;
|
||||||
varying /*highp*/ vec2 tex_coord;
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
/*lowp*/ vec4 color = texture2D(texture, tex_coord);
|
vec4 color = texture2D(texture, tex_coord);
|
||||||
gl_FragColor = (color_matrix * color) + color_matrix_translation;
|
gl_FragColor = (color_matrix * color) + color_matrix_translation;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
}
|
},
|
||||||
)
|
shaderSolidColor: &shader{
|
||||||
|
shaderType: C.GL_FRAGMENT_SHADER,
|
||||||
|
source: `
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
var (
|
void main(void) {
|
||||||
programRegular = C.GLuint(0)
|
gl_FragColor = color;
|
||||||
programColorMatrix = C.GLuint(0)
|
}
|
||||||
)
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func (s *shader) compile() {
|
func (s *shader) compile() {
|
||||||
|
s.native = C.glCreateShader(s.shaderType)
|
||||||
|
if s.native == 0 {
|
||||||
|
panic("glCreateShader failed")
|
||||||
|
}
|
||||||
|
|
||||||
csource := (*C.GLchar)(C.CString(s.source))
|
csource := (*C.GLchar)(C.CString(s.source))
|
||||||
// TODO: defer?
|
// TODO: defer?
|
||||||
// defer C.free(unsafe.Pointer(csource))
|
// defer C.free(unsafe.Pointer(csource))
|
||||||
|
|
||||||
C.glShaderSource(s.id, 1, &csource, nil)
|
C.glShaderSource(s.native, 1, &csource, nil)
|
||||||
C.glCompileShader(s.id)
|
C.glCompileShader(s.native)
|
||||||
|
|
||||||
compiled := C.GLint(C.GL_FALSE)
|
compiled := C.GLint(C.GL_FALSE)
|
||||||
C.glGetShaderiv(s.id, C.GL_COMPILE_STATUS, &compiled)
|
C.glGetShaderiv(s.native, C.GL_COMPILE_STATUS, &compiled)
|
||||||
if compiled == C.GL_FALSE {
|
if compiled == C.GL_FALSE {
|
||||||
s.showShaderLog()
|
s.showShaderLog()
|
||||||
panic("shader compile failed: " + s.name)
|
panic("shader compile failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shader) showShaderLog() {
|
func (s *shader) showShaderLog() {
|
||||||
logSize := C.GLint(0)
|
logSize := C.GLint(0)
|
||||||
C.glGetShaderiv(s.id, C.GL_INFO_LOG_LENGTH, &logSize)
|
C.glGetShaderiv(s.native, C.GL_INFO_LOG_LENGTH, &logSize)
|
||||||
if logSize == 0 {
|
if logSize == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
length := C.GLsizei(0)
|
length := C.GLsizei(0)
|
||||||
buffer := make([]C.GLchar, logSize)
|
buffer := make([]C.GLchar, logSize)
|
||||||
C.glGetShaderInfoLog(s.id, C.GLsizei(logSize), &length, &buffer[0])
|
C.glGetShaderInfoLog(s.native, C.GLsizei(logSize), &length, &buffer[0])
|
||||||
|
|
||||||
message := string(C.GoBytes(unsafe.Pointer(&buffer[0]), C.int(length)))
|
message := string(C.GoBytes(unsafe.Pointer(&buffer[0]), C.int(length)))
|
||||||
print("shader error (", s.name, "):\n", message)
|
fmt.Printf("shader error: %s\n", message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *shader) delete() {
|
||||||
|
C.glDeleteShader(s.native)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
type windowEvents struct {
|
type windowEvents struct {
|
||||||
screenSizeUpdated chan ui.ScreenSizeUpdatedEvent // initialized lazily
|
screenSizeUpdated chan ui.ScreenSizeUpdatedEvent // initialized lazily
|
||||||
inputStateUpdated chan ui.InputStateUpdatedEvent // initialized lazily
|
inputStateUpdated chan ui.InputStateUpdatedEvent // initialized lazily
|
||||||
windowClosed chan ui.WindowClosedEvent // initialized lazily
|
windowClosed chan ui.WindowClosedEvent // initialized lazily
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowEvents) ScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
|
func (w *windowEvents) ScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
|
||||||
@ -60,4 +60,3 @@ func (w *windowEvents) notifyWindowClosed(e ui.WindowClosedEvent) {
|
|||||||
w.windowClosed <- e
|
w.windowClosed <- e
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user