Bug fix: Line's vertices should be moved by 0.5

This commit is contained in:
Hajime Hoshi 2015-01-17 16:09:09 +09:00
parent 683ffafe8d
commit 1659e9abab
7 changed files with 76 additions and 45 deletions

View File

@ -26,11 +26,13 @@ const (
) )
func update(screen *ebiten.Image) error { func update(screen *ebiten.Image) error {
screen.DrawRect(0, 0, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80}) for i := 0; i < 6; i++ {
screen.DrawRect(float64(2*i), float64(2*i), 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
}
screen.FillRect(10, 10, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80}) screen.FillRect(10, 10, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
screen.FillRect(20, 20, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80}) screen.FillRect(20, 20, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
screen.DrawLine(130, 10, 140, 150, color.NRGBA{0xff, 0x80, 0x80, 0x80}) screen.DrawLine(130, 0, 140, 100, color.NRGBA{0xff, 0x80, 0x80, 0x80})
screen.DrawLine(140, 10, 150, 150, color.NRGBA{0xff, 0x80, 0x80, 0x80}) screen.DrawLine(140, 0, 150, 100, color.NRGBA{0xff, 0x80, 0x80, 0x80})
return nil return nil
} }

View File

@ -96,7 +96,7 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
} }
// DrawLine draws a line. // DrawLine draws a line.
func (i *Image) DrawLine(x0, y0, x1, y1 int, clr color.Color) error { func (i *Image) DrawLine(x0, y0, x1, y1 float64, clr color.Color) error {
return i.DrawLines(&line{x0, y0, x1, y1, clr}) return i.DrawLines(&line{x0, y0, x1, y1, clr})
} }
@ -108,7 +108,7 @@ func (i *Image) DrawLines(lines Lines) (err error) {
return return
} }
func (i *Image) DrawRect(x, y, width, height int, clr color.Color) error { func (i *Image) DrawRect(x, y, width, height float64, clr color.Color) error {
return i.DrawLines(&rectsAsLines{&rect{x, y, width, height, clr}}) return i.DrawLines(&rectsAsLines{&rect{x, y, width, height, clr}})
} }
@ -117,7 +117,7 @@ func (i *Image) DrawRects(rects Rects) error {
} }
// FillRect draws a filled rectangle. // FillRect draws a filled rectangle.
func (i *Image) FillRect(x, y, width, height int, clr color.Color) error { func (i *Image) FillRect(x, y, width, height float64, clr color.Color) error {
return i.FillRects(&rect{x, y, width, height, clr}) return i.FillRects(&rect{x, y, width, height, clr})
} }

View File

@ -116,7 +116,7 @@ func (f *Framebuffer) DrawTexture(c *opengl.Context, t *Texture, quads TextureQu
type Lines interface { type Lines interface {
Len() int Len() int
Points(i int) (x0, y0, x1, y1 int) Points(i int) (x0, y0, x1, y1 float64)
Color(i int) color.Color Color(i int) color.Color
} }
@ -130,7 +130,7 @@ func (f *Framebuffer) DrawLines(c *opengl.Context, lines Lines) error {
type Rects interface { type Rects interface {
Len() int Len() int
Rect(i int) (x, y, width, height int) Rect(i int) (x, y, width, height float64)
Color(i int) color.Color Color(i int) color.Color
} }

View File

@ -62,7 +62,7 @@ func DrawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", quadsMaxNum)) return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", quadsMaxNum))
} }
f := useProgramTexture(c, glMatrix(projectionMatrix), texture, geo, color) f := useProgramForTexture(c, glMatrix(projectionMatrix), texture, geo, color)
defer f.FinishProgram() defer f.FinishProgram()
vertices := vertices[0:0] vertices := vertices[0:0]
@ -91,7 +91,7 @@ func DrawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
type Lines interface { type Lines interface {
Len() int Len() int
Points(i int) (x0, y0, x1, y1 int) Points(i int) (x0, y0, x1, y1 float64)
Color(i int) color.Color Color(i int) color.Color
} }
@ -107,7 +107,7 @@ func DrawLines(c *opengl.Context, projectionMatrix *[4][4]float64, lines Lines)
return nil return nil
} }
f := useProgramLines(c, glMatrix(projectionMatrix)) f := useProgramForLines(c, glMatrix(projectionMatrix))
defer f.FinishProgram() defer f.FinishProgram()
vertices := vertices[0:0] vertices := vertices[0:0]
@ -135,7 +135,7 @@ func DrawLines(c *opengl.Context, projectionMatrix *[4][4]float64, lines Lines)
type Rects interface { type Rects interface {
Len() int Len() int
Rect(i int) (x, y, width, height int) Rect(i int) (x, y, width, height float64)
Color(i int) color.Color Color(i int) color.Color
} }
@ -151,7 +151,7 @@ func FillRects(c *opengl.Context, projectionMatrix *[4][4]float64, rects Rects)
return nil return nil
} }
f := useProgramRects(c, glMatrix(projectionMatrix)) f := useProgramForRects(c, glMatrix(projectionMatrix))
defer f.FinishProgram() defer f.FinishProgram()
vertices := vertices[0:0] vertices := vertices[0:0]

View File

@ -25,8 +25,9 @@ var (
) )
var ( var (
programTexture opengl.Program programTexture opengl.Program
programSolid opengl.Program programSolidRect opengl.Program
programSolidLine opengl.Program
) )
const indicesNum = math.MaxUint16 + 1 const indicesNum = math.MaxUint16 + 1
@ -34,13 +35,14 @@ const quadsMaxNum = indicesNum / 6
// unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS. // unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS.
const int16Size = 2 const int16Size = 2
const float32Size = 4
func initialize(c *opengl.Context) error { func initialize(c *opengl.Context) error {
shaderVertexNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertex)) shaderVertexModelviewNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexModelview))
if err != nil { if err != nil {
return err return err
} }
defer c.DeleteShader(shaderVertexNative) defer c.DeleteShader(shaderVertexModelviewNative)
shaderVertexColorNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexColor)) shaderVertexColorNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexColor))
if err != nil { if err != nil {
@ -48,6 +50,12 @@ func initialize(c *opengl.Context) error {
} }
defer c.DeleteShader(shaderVertexColorNative) defer c.DeleteShader(shaderVertexColorNative)
shaderVertexColorLineNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexColorLine))
if err != nil {
return err
}
defer c.DeleteShader(shaderVertexColorLineNative)
shaderFragmentTextureNative, err := c.NewShader(c.FragmentShader, shader(c, shaderFragmentTexture)) shaderFragmentTextureNative, err := c.NewShader(c.FragmentShader, shader(c, shaderFragmentTexture))
if err != nil { if err != nil {
return err return err
@ -61,14 +69,14 @@ func initialize(c *opengl.Context) error {
defer c.DeleteShader(shaderFragmentSolidNative) defer c.DeleteShader(shaderFragmentSolidNative)
programTexture, err = c.NewProgram([]opengl.Shader{ programTexture, err = c.NewProgram([]opengl.Shader{
shaderVertexNative, shaderVertexModelviewNative,
shaderFragmentTextureNative, shaderFragmentTextureNative,
}) })
if err != nil { if err != nil {
return err return err
} }
programSolid, err = c.NewProgram([]opengl.Shader{ programSolidRect, err = c.NewProgram([]opengl.Shader{
shaderVertexColorNative, shaderVertexColorNative,
shaderFragmentSolidNative, shaderFragmentSolidNative,
}) })
@ -76,7 +84,16 @@ func initialize(c *opengl.Context) error {
return err return err
} }
const stride = int16Size * 8 // 8 = (2 for vertex) + (2 for texture) + (4 for color) programSolidLine, err = c.NewProgram([]opengl.Shader{
shaderVertexColorLineNative,
shaderFragmentSolidNative,
})
if err != nil {
return err
}
// 16 [bytse] is an arbitrary number which seems enough to draw anything. Fix this if necessary.
const stride = 16
c.NewBuffer(c.ArrayBuffer, 4*stride*quadsMaxNum, c.DynamicDraw) c.NewBuffer(c.ArrayBuffer, 4*stride*quadsMaxNum, c.DynamicDraw)
indices := make([]uint16, 6*quadsMaxNum) indices := make([]uint16, 6*quadsMaxNum)
@ -107,7 +124,7 @@ func (p programFinisher) FinishProgram() {
p() p()
} }
func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture opengl.Texture, geo Matrix, color Matrix) programFinisher { func useProgramForTexture(c *opengl.Context, projectionMatrix []float32, texture opengl.Texture, geo Matrix, color Matrix) programFinisher {
if !lastProgram.Equals(programTexture) { if !lastProgram.Equals(programTexture) {
c.UseProgram(programTexture) c.UseProgram(programTexture)
lastProgram = programTexture lastProgram = programTexture
@ -168,12 +185,12 @@ func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture op
} }
} }
func useProgramLines(c *opengl.Context, projectionMatrix []float32) programFinisher { func useProgramForLines(c *opengl.Context, projectionMatrix []float32) programFinisher {
if !lastProgram.Equals(programSolid) { if !lastProgram.Equals(programSolidLine) {
c.UseProgram(programSolid) c.UseProgram(programSolidLine)
lastProgram = programSolid lastProgram = programSolidLine
} }
program := programSolid program := programSolidLine
c.BindElementArrayBuffer(indexBufferLines) c.BindElementArrayBuffer(indexBufferLines)
@ -192,12 +209,12 @@ func useProgramLines(c *opengl.Context, projectionMatrix []float32) programFinis
} }
} }
func useProgramRects(c *opengl.Context, projectionMatrix []float32) programFinisher { func useProgramForRects(c *opengl.Context, projectionMatrix []float32) programFinisher {
if !lastProgram.Equals(programSolid) { if !lastProgram.Equals(programSolidRect) {
c.UseProgram(programSolid) c.UseProgram(programSolidRect)
lastProgram = programSolid lastProgram = programSolidRect
} }
program := programSolid program := programSolidRect
c.BindElementArrayBuffer(indexBufferQuads) c.BindElementArrayBuffer(indexBufferQuads)

View File

@ -22,8 +22,9 @@ import (
type shaderId int type shaderId int
const ( const (
shaderVertex shaderId = iota shaderVertexModelview shaderId = iota
shaderVertexColor shaderVertexColor
shaderVertexColorLine
shaderFragmentTexture shaderFragmentTexture
shaderFragmentSolid shaderFragmentSolid
) )
@ -38,7 +39,7 @@ func shader(c *opengl.Context, id shaderId) string {
} }
var shaders = map[shaderId]string{ var shaders = map[shaderId]string{
shaderVertex: ` shaderVertexModelview: `
uniform highp mat4 projection_matrix; uniform highp mat4 projection_matrix;
uniform highp mat4 modelview_matrix; uniform highp mat4 modelview_matrix;
attribute highp vec2 vertex; attribute highp vec2 vertex;
@ -60,6 +61,17 @@ void main(void) {
vertex_out_color = color; vertex_out_color = color;
gl_Position = projection_matrix * vec4(vertex, 0, 1); gl_Position = projection_matrix * vec4(vertex, 0, 1);
} }
`,
shaderVertexColorLine: `
uniform highp mat4 projection_matrix;
attribute highp vec2 vertex;
attribute lowp vec4 color;
varying lowp vec4 vertex_out_color;
void main(void) {
vertex_out_color = color;
gl_Position = projection_matrix * vec4(vertex + vec2(0.5, 0.5), 0, 1);
}
`, `,
shaderFragmentTexture: ` shaderFragmentTexture: `
uniform lowp sampler2D texture; uniform lowp sampler2D texture;

View File

@ -21,13 +21,13 @@ import (
// A Lines represents the set of lines. // A Lines represents the set of lines.
type Lines interface { type Lines interface {
Len() int Len() int
Points(i int) (x0, y0, x1, y1 int) // TODO: Change to float64? Points(i int) (x0, y0, x1, y1 float64)
Color(i int) color.Color Color(i int) color.Color
} }
type line struct { type line struct {
x0, y0 int x0, y0 float64
x1, y1 int x1, y1 float64
color color.Color color color.Color
} }
@ -35,7 +35,7 @@ func (l *line) Len() int {
return 1 return 1
} }
func (l *line) Points(i int) (x0, y0, x1, y1 int) { func (l *line) Points(i int) (x0, y0, x1, y1 float64) {
return l.x0, l.y0, l.x1, l.y1 return l.x0, l.y0, l.x1, l.y1
} }
@ -51,17 +51,17 @@ func (r *rectsAsLines) Len() int {
return r.Rects.Len() * 4 return r.Rects.Len() * 4
} }
func (r *rectsAsLines) Points(i int) (x0, y0, x1, y1 int) { func (r *rectsAsLines) Points(i int) (x0, y0, x1, y1 float64) {
x, y, w, h := r.Rects.Rect(i / 4) x, y, w, h := r.Rects.Rect(i / 4)
switch i % 4 { switch i % 4 {
case 0: case 0:
return x, y, x + w, y return x, y, x + w, y
case 1: case 1:
return x, y, x + 1, y + h return x, y + 1, x, y + h - 1
case 2: case 2:
return x, y + h, x + w, y + h return x, y + h - 1, x + w, y + h - 1
case 3: case 3:
return x + w, y, x + w, y + h return x + w - 1, y + 1, x + w - 1, y + h - 1
} }
panic("not reach") panic("not reach")
} }
@ -73,13 +73,13 @@ func (r *rectsAsLines) Color(i int) color.Color {
// A Rects represents the set of rectangles. // A Rects represents the set of rectangles.
type Rects interface { type Rects interface {
Len() int Len() int
Rect(i int) (x, y, width, height int) // TODO: Change to float64? Rect(i int) (x, y, width, height float64)
Color(i int) color.Color Color(i int) color.Color
} }
type rect struct { type rect struct {
x, y int x, y float64
width, height int width, height float64
color color.Color color color.Color
} }
@ -87,7 +87,7 @@ func (r *rect) Len() int {
return 1 return 1
} }
func (r *rect) Rect(i int) (x, y, width, height int) { func (r *rect) Rect(i int) (x, y, width, height float64) {
return r.x, r.y, r.width, r.height return r.x, r.y, r.width, r.height
} }