Pass color values for each vertex on drawing rects

This commit is contained in:
Hajime Hoshi 2015-01-16 00:57:49 +09:00
parent b2924d193b
commit 037f35b0db
5 changed files with 49 additions and 47 deletions

View File

@ -39,10 +39,7 @@ type TextureQuads interface {
Texture(i int) (u0, v0, u1, v1 float64) Texture(i int) (u0, v0, u1, v1 float64)
} }
// TODO: better name? var vertices = make([]float32, 0, 4*8*quadsMaxNum)
const stride = 4 * 4
var vertices = make([]float32, 0, stride*quadsMaxNum)
var initialized = false var initialized = false
@ -68,6 +65,7 @@ func DrawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
defer f.FinishProgram() defer f.FinishProgram()
vertices := vertices[0:0] vertices := vertices[0:0]
num := 0
for i := 0; i < quads.Len(); i++ { for i := 0; i < quads.Len(); i++ {
x0, y0, x1, y1 := quads.Vertex(i) x0, y0, x1, y1 := quads.Vertex(i)
u0, v0, u1, v1 := quads.Texture(i) u0, v0, u1, v1 := quads.Texture(i)
@ -80,12 +78,13 @@ func DrawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
float32(x0), float32(y1), float32(u0), float32(v1), float32(x0), float32(y1), float32(u0), float32(v1),
float32(x1), float32(y1), float32(u1), float32(v1), float32(x1), float32(y1), float32(u1), float32(v1),
) )
num++
} }
if len(vertices) == 0 { if len(vertices) == 0 {
return nil return nil
} }
c.BufferSubData(c.ArrayBuffer, vertices) c.BufferSubData(c.ArrayBuffer, vertices)
c.DrawElements(6 * len(vertices) / 16) c.DrawElements(6 * num)
return nil return nil
} }
@ -113,27 +112,29 @@ func DrawRects(c *opengl.Context, projectionMatrix *[4][4]float64, r, g, b, a fl
return nil return nil
} }
f := useProgramRect(c, glMatrix(projectionMatrix), r, g, b, a) f := useProgramRect(c, glMatrix(projectionMatrix))
defer f.FinishProgram() defer f.FinishProgram()
vertices := vertices[0:0] vertices := vertices[0:0]
num := 0
for i := 0; i < quads.Len(); i++ { for i := 0; i < quads.Len(); i++ {
x0, y0, x1, y1 := quads.Vertex(i) x0, y0, x1, y1 := quads.Vertex(i)
if x0 == x1 || y0 == y1 { if x0 == x1 || y0 == y1 {
continue continue
} }
vertices = append(vertices, vertices = append(vertices,
float32(x0), float32(y0), 0, 0, float32(x0), float32(y0), float32(r), float32(g), float32(b), float32(a),
float32(x1), float32(y0), 1, 0, float32(x1), float32(y0), float32(r), float32(g), float32(b), float32(a),
float32(x0), float32(y1), 0, 1, float32(x0), float32(y1), float32(r), float32(g), float32(b), float32(a),
float32(x1), float32(y1), 1, 1, float32(x1), float32(y1), float32(r), float32(g), float32(b), float32(a),
) )
num++
} }
if len(vertices) == 0 { if len(vertices) == 0 {
return nil return nil
} }
c.BufferSubData(c.ArrayBuffer, vertices) c.BufferSubData(c.ArrayBuffer, vertices)
c.DrawElements(6 * len(vertices) / 16) c.DrawElements(6 * num)
return nil return nil
} }

View File

@ -25,6 +25,9 @@ var (
const quadsMaxNum = 65536 / 6 const quadsMaxNum = 65536 / 6
// unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS.
const float32Size = 4
func initialize(c *opengl.Context) error { func initialize(c *opengl.Context) error {
const uint16Size = 2 const uint16Size = 2
@ -34,6 +37,12 @@ func initialize(c *opengl.Context) error {
} }
defer c.DeleteShader(shaderVertexNative) defer c.DeleteShader(shaderVertexNative)
shaderVertexColorNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexColor))
if err != nil {
return err
}
defer c.DeleteShader(shaderVertexColorNative)
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
@ -55,16 +64,15 @@ func initialize(c *opengl.Context) error {
} }
programRect, err = c.NewProgram([]opengl.Shader{ programRect, err = c.NewProgram([]opengl.Shader{
shaderVertexNative, shaderVertexColorNative,
shaderFragmentRectNative, shaderFragmentRectNative,
}) })
if err != nil { if err != nil {
return err return err
} }
const stride = 4 * 4 const stride = float32Size * 8 // 8 = (2 for vertex) + (2 for texture) + (4 for color)
const float32Size = 4 c.NewBuffer(c.ArrayBuffer, 4*stride*quadsMaxNum, c.DynamicDraw)
c.NewBuffer(c.ArrayBuffer, float32Size*stride*quadsMaxNum, c.DynamicDraw)
indices := make([]uint16, 6*quadsMaxNum) indices := make([]uint16, 6*quadsMaxNum)
for i := uint16(0); i < quadsMaxNum; i++ { for i := uint16(0); i < quadsMaxNum; i++ {
@ -89,10 +97,6 @@ func (p programFinisher) FinishProgram() {
} }
func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture opengl.Texture, geo Matrix, color Matrix) programFinisher { func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture opengl.Texture, geo Matrix, color Matrix) programFinisher {
// unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS.
const float32Size = 4
const stride = 4 * 4
if lastProgram != programTexture { if lastProgram != programTexture {
c.UseProgram(programTexture) c.UseProgram(programTexture)
lastProgram = programTexture lastProgram = programTexture
@ -142,8 +146,8 @@ func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture op
c.EnableVertexAttribArray(program, "vertex") c.EnableVertexAttribArray(program, "vertex")
c.EnableVertexAttribArray(program, "tex_coord") c.EnableVertexAttribArray(program, "tex_coord")
c.VertexAttribPointer(program, "vertex", stride, uintptr(float32Size*0)) c.VertexAttribPointer(program, "vertex", float32Size*4, 2, uintptr(float32Size*0))
c.VertexAttribPointer(program, "tex_coord", stride, uintptr(float32Size*2)) c.VertexAttribPointer(program, "tex_coord", float32Size*4, 2, uintptr(float32Size*2))
return func() { return func() {
c.DisableVertexAttribArray(program, "tex_coord") c.DisableVertexAttribArray(program, "tex_coord")
@ -151,10 +155,7 @@ func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture op
} }
} }
func useProgramRect(c *opengl.Context, projectionMatrix []float32, r, g, b, a float64) programFinisher { func useProgramRect(c *opengl.Context, projectionMatrix []float32) programFinisher {
const float32Size = 4
const stride = 4 * 4
if lastProgram != programRect { if lastProgram != programRect {
c.UseProgram(programRect) c.UseProgram(programRect)
lastProgram = programRect lastProgram = programRect
@ -163,25 +164,14 @@ func useProgramRect(c *opengl.Context, projectionMatrix []float32, r, g, b, a fl
c.UniformFloats(program, "projection_matrix", projectionMatrix) c.UniformFloats(program, "projection_matrix", projectionMatrix)
glModelviewMatrix := []float32{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
}
c.UniformFloats(program, "modelview_matrix", glModelviewMatrix)
clr := []float32{float32(r), float32(g), float32(b), float32(a)}
c.UniformFloats(program, "color", clr)
c.EnableVertexAttribArray(program, "vertex") c.EnableVertexAttribArray(program, "vertex")
c.EnableVertexAttribArray(program, "tex_coord") c.EnableVertexAttribArray(program, "color")
c.VertexAttribPointer(program, "vertex", stride, uintptr(float32Size*0)) c.VertexAttribPointer(program, "vertex", float32Size*6, 2, uintptr(float32Size*0))
c.VertexAttribPointer(program, "tex_coord", stride, uintptr(float32Size*2)) c.VertexAttribPointer(program, "color", float32Size*6, 4, uintptr(float32Size*2))
return func() { return func() {
c.DisableVertexAttribArray(program, "tex_coord") c.DisableVertexAttribArray(program, "color")
c.DisableVertexAttribArray(program, "vertex") c.DisableVertexAttribArray(program, "vertex")
} }
} }

View File

@ -23,6 +23,7 @@ type shaderId int
const ( const (
shaderVertex shaderId = iota shaderVertex shaderId = iota
shaderVertexColor
shaderFragmentTexture shaderFragmentTexture
shaderFragmentRect shaderFragmentRect
) )
@ -48,6 +49,17 @@ void main(void) {
vertex_out_tex_coord = tex_coord; vertex_out_tex_coord = tex_coord;
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1); gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
} }
`,
shaderVertexColor: `
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, 0, 1);
}
`, `,
shaderFragmentTexture: ` shaderFragmentTexture: `
uniform lowp sampler2D texture; uniform lowp sampler2D texture;
@ -72,11 +84,10 @@ void main(void) {
} }
`, `,
shaderFragmentRect: ` shaderFragmentRect: `
uniform lowp vec4 color; varying lowp vec4 vertex_out_color;
varying highp vec2 vertex_out_tex_coord;
void main(void) { void main(void) {
gl_FragColor = color; gl_FragColor = vertex_out_color;
} }
`, `,
} }

View File

@ -206,9 +206,9 @@ func (c *Context) GetAttribLocation(p Program, location string) AttribLocation {
return AttribLocation(gl.Program(p).GetAttribLocation(location)) return AttribLocation(gl.Program(p).GetAttribLocation(location))
} }
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) { func (c *Context) VertexAttribPointer(p Program, location string, stride int, size int, v uintptr) {
l := gl.AttribLocation(GetAttribLocation(c, p, location)) l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.AttribPointer(2, gl.FLOAT, false, stride, v) l.AttribPointer(uint(size), gl.FLOAT, false, stride, v)
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {

View File

@ -256,10 +256,10 @@ func (c *Context) GetAttribLocation(p Program, location string) AttribLocation {
return AttribLocation(gl.GetAttribLocation(p.Object, location)) return AttribLocation(gl.GetAttribLocation(p.Object, location))
} }
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) { func (c *Context) VertexAttribPointer(p Program, location string, stride int, size int, v uintptr) {
gl := c.gl gl := c.gl
l := GetAttribLocation(c, p, location) l := GetAttribLocation(c, p, location)
gl.VertexAttribPointer(int(l), 2, gl.FLOAT, false, stride, int(v)) gl.VertexAttribPointer(int(l), size, gl.FLOAT, false, stride, int(v))
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {