Beispiel #1
0
func (s shape) draw(ctx *context, shader *shaderProgram, ub uniformBindings) {
	shader.bind(ctx, s.vb, ub)
	if s.ib != nil {
		ctx.getOrCreateIndexBufferContext(s.ib).render(s.drawMode)
	} else {
		gl.DrawArrays(gl.Enum(s.drawMode), 0, s.vb.count)
	}
	shader.unbind(ctx)
	checkError()
}
Beispiel #2
0
func compile(source string, ty int) gl.Shader {
	shader := gl.CreateShader(gl.Enum(ty))
	gl.ShaderSource(shader, source)

	gl.CompileShader(shader)
	if gl.GetShaderi(shader, gl.COMPILE_STATUS) != gl.TRUE {
		panic(gl.GetShaderInfoLog(shader))
	}
	checkError()

	return shader
}
Beispiel #3
0
func (s *glShader) createShader(name, header, opts, vShader, fShader string) error {
	program := gl.CreateProgram()

	vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
	gl.ShaderSource(vertexShader, strings.Join([]string{header, opts, vShader}, "\n"))
	gl.CompileShader(vertexShader)
	status := gl.Enum(gl.GetShaderi(vertexShader, gl.COMPILE_STATUS))
	if status != gl.TRUE {
		return dumpShaderError(vertexShader, name, "vert")
	}

	fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER)
	gl.ShaderSource(fragmentShader, strings.Join([]string{header, opts, fShader}, "\n"))
	gl.CompileShader(fragmentShader)
	status = gl.Enum(gl.GetShaderi(fragmentShader, gl.COMPILE_STATUS))
	if status != gl.TRUE {
		return dumpShaderError(fragmentShader, name, "vert")
	}

	gl.AttachShader(program, vertexShader)
	gl.AttachShader(program, fragmentShader)

	gl.LinkProgram(program)
	status = gl.Enum(gl.GetProgrami(program, gl.LINK_STATUS))
	if status != gl.TRUE {
		return dumpProgramError(program, name)
	}

	s.vertexAttrib = gl.GetAttribLocation(program, "vertex")
	s.tcoordAttrib = gl.GetAttribLocation(program, "tcoord")

	s.program = program
	s.vertex = vertexShader
	s.fragment = fragmentShader

	return nil
}
Beispiel #4
0
func (u *shaderUniform) bind(context *context, v interface{}) {
	switch u.ty {
	case stFloatMat2:
		gl.UniformMatrix2fv(u.location, v.([]float32))
	case stFloatMat3:
		switch m := v.(type) {
		case math.Mat3:
			gl.UniformMatrix3fv(u.location, m[:])
		case []float32:
			gl.UniformMatrix3fv(u.location, m)
		}
	case stFloatMat4:
		gl.UniformMatrix4fv(u.location, v.([]float32))
	case stFloatVec1:
		switch v := v.(type) {
		case float32:
			gl.Uniform1f(u.location, v)
		case []float32:
			gl.Uniform1fv(u.location, v)
		}
	case stFloatVec2:
		switch v := v.(type) {
		case math.Vec2:
			gl.Uniform2fv(u.location, []float32{v.X, v.Y})
		case []float32:
			if len(v)%2 != 0 {
				panic(fmt.Errorf("Uniform '%s' of type vec2 should be an float32 array with a multiple of two length", u.name))
			}
			gl.Uniform2fv(u.location, v)
		}
	case stFloatVec3:
		switch v := v.(type) {
		case math.Vec3:
			gl.Uniform3fv(u.location, []float32{v.X, v.Y, v.Z})
		case []float32:
			if len(v)%3 != 0 {
				panic(fmt.Errorf("Uniform '%s' of type vec3 should be an float32 array with a multiple of three length", u.name))
			}
			gl.Uniform3fv(u.location, v)
		}
	case stFloatVec4:
		switch v := v.(type) {
		case math.Vec4:
			gl.Uniform4fv(u.location, []float32{v.X, v.Y, v.Z, v.W})
		case gxui.Color:
			gl.Uniform4fv(u.location, []float32{v.R, v.G, v.B, v.A})
		case []float32:
			if len(v)%4 != 0 {
				panic(fmt.Errorf("Uniform '%s' of type vec4 should be an float32 array with a multiple of four length", u.name))
			}
			gl.Uniform4fv(u.location, v)
		}
	case stSampler2d:
		tc := v.(*textureContext)
		gl.ActiveTexture(gl.Enum(gl.TEXTURE0 + u.textureUnit))
		gl.BindTexture(gl.TEXTURE_2D, tc.texture)
		gl.Uniform1i(u.location, u.textureUnit)
	default:
		panic(fmt.Errorf("Uniform of unsupported type %s", u.ty))
	}
}
Beispiel #5
0
func (c *indexBufferContext) render(drawMode drawMode) {
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, c.buffer)
	gl.DrawElements(gl.Enum(drawMode), c.length, gl.Enum(c.ty), 0)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Buffer{})
	checkError()
}
Beispiel #6
0
func (a shaderAttribute) attribPointer(size int32, ty uint32, normalized bool, stride int32, offset int) {
	gl.VertexAttribPointer(a.location, int(size), gl.Enum(ty), normalized, int(stride), offset)
}