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

View File

@ -25,6 +25,9 @@ var (
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 {
const uint16Size = 2
@ -34,6 +37,12 @@ func initialize(c *opengl.Context) error {
}
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))
if err != nil {
return err
@ -55,16 +64,15 @@ func initialize(c *opengl.Context) error {
}
programRect, err = c.NewProgram([]opengl.Shader{
shaderVertexNative,
shaderVertexColorNative,
shaderFragmentRectNative,
})
if err != nil {
return err
}
const stride = 4 * 4
const float32Size = 4
c.NewBuffer(c.ArrayBuffer, float32Size*stride*quadsMaxNum, c.DynamicDraw)
const stride = float32Size * 8 // 8 = (2 for vertex) + (2 for texture) + (4 for color)
c.NewBuffer(c.ArrayBuffer, 4*stride*quadsMaxNum, c.DynamicDraw)
indices := make([]uint16, 6*quadsMaxNum)
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 {
// unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS.
const float32Size = 4
const stride = 4 * 4
if lastProgram != programTexture {
c.UseProgram(programTexture)
lastProgram = programTexture
@ -142,8 +146,8 @@ func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture op
c.EnableVertexAttribArray(program, "vertex")
c.EnableVertexAttribArray(program, "tex_coord")
c.VertexAttribPointer(program, "vertex", stride, uintptr(float32Size*0))
c.VertexAttribPointer(program, "tex_coord", stride, uintptr(float32Size*2))
c.VertexAttribPointer(program, "vertex", float32Size*4, 2, uintptr(float32Size*0))
c.VertexAttribPointer(program, "tex_coord", float32Size*4, 2, uintptr(float32Size*2))
return func() {
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 {
const float32Size = 4
const stride = 4 * 4
func useProgramRect(c *opengl.Context, projectionMatrix []float32) programFinisher {
if lastProgram != programRect {
c.UseProgram(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)
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, "tex_coord")
c.EnableVertexAttribArray(program, "color")
c.VertexAttribPointer(program, "vertex", stride, uintptr(float32Size*0))
c.VertexAttribPointer(program, "tex_coord", stride, uintptr(float32Size*2))
c.VertexAttribPointer(program, "vertex", float32Size*6, 2, uintptr(float32Size*0))
c.VertexAttribPointer(program, "color", float32Size*6, 4, uintptr(float32Size*2))
return func() {
c.DisableVertexAttribArray(program, "tex_coord")
c.DisableVertexAttribArray(program, "color")
c.DisableVertexAttribArray(program, "vertex")
}
}

View File

@ -23,6 +23,7 @@ type shaderId int
const (
shaderVertex shaderId = iota
shaderVertexColor
shaderFragmentTexture
shaderFragmentRect
)
@ -48,6 +49,17 @@ void main(void) {
vertex_out_tex_coord = tex_coord;
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: `
uniform lowp sampler2D texture;
@ -72,11 +84,10 @@ void main(void) {
}
`,
shaderFragmentRect: `
uniform lowp vec4 color;
varying highp vec2 vertex_out_tex_coord;
varying lowp vec4 vertex_out_color;
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))
}
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.AttribPointer(2, gl.FLOAT, false, stride, v)
l.AttribPointer(uint(size), gl.FLOAT, false, stride, v)
}
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))
}
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
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) {