Example #1
0
func (p *ShaderProgram) Link() (uint32, error) {
	defer func() {
		for _, shaders := range p.shaders {
			for _, shader := range shaders {
				gl.DeleteShader(shader)
			}
		}
		*p = ShaderProgram{}
	}()

	program := gl.CreateProgram()
	for _, shaders := range p.shaders {
		for _, shader := range shaders {
			gl.AttachShader(program, shader)
		}
	}
	gl.LinkProgram(program)

	var status int32
	gl.GetProgramiv(program, gl.LINK_STATUS, &status)
	if status == gl.FALSE {
		var logLength int32
		gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength)
		log := strings.Repeat("\x00", int(logLength+1))
		gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log))
		return 0, fmt.Errorf("failed to link program:\n%s", log)
	}
	return program, nil
}
Example #2
0
func (p *ShaderProgram) AddShader(source string, kind ShaderKind) error {
	shader := gl.CreateShader(uint32(kind))

	csource := gl.Str(source + "\x00")
	gl.ShaderSource(shader, 1, &csource, nil)
	gl.CompileShader(shader)

	var status int32
	gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
	if status == gl.FALSE {
		var logLength int32
		gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
		log := strings.Repeat("\x00", int(logLength+1))
		gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
		return fmt.Errorf("failed to compile %v shader:\n%s",
			kindString(kind), log)
	}
	p.shaders[kind] = append(p.shaders[kind], shader)
	return nil
}
Example #3
0
func (s *MainState) Render() error {
	gl.UseProgram(s.program)
	gl.UniformMatrix4fv(s.projectionUniform, 1, false, &s.projection[0])

	/*
		gl.BindVertexArray(s.vao)
		gl.BindBuffer(gl.ARRAY_BUFFER, s.vbo)
	*/
	gl.BufferData(
		gl.ARRAY_BUFFER,
		int(PARTICLE_COUNT_DEFAULT*unsafe.Sizeof([2]float32{})),
		nil,
		gl.STREAM_DRAW)
	data, err := sliceMap2Float32Buffer(gl.WRITE_ONLY, PARTICLE_COUNT_DEFAULT)
	if err != nil {
		return err
	}
	for i := range data {
		p := &s.space.Particles[i]
		if p == nil {
			return fmt.Errorf("no particle of id %d", i)
		}
		data[i][0] = float32(p.Position.X)
		data[i][1] = float32(p.Position.Y)
	}
	gl.UnmapBuffer(gl.ARRAY_BUFFER)
	data = nil

	positionAttrib := uint32(gl.GetAttribLocation(s.program, gl.Str("position\x00")))
	gl.EnableVertexAttribArray(positionAttrib)
	gl.VertexAttribPointer(positionAttrib, 2, gl.FLOAT, false, 0, gl.PtrOffset(0))

	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.DrawArrays(gl.POINTS, 0, PARTICLE_COUNT_DEFAULT)

	return nil
}
Example #4
0
func (s *MainState) Render() error {
	program := s.program
	gl.UseProgram(program)

	projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00"))
	gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])

	gl.Flush()
	buffer := s.vertexBuffer
	gl.BindBuffer(gl.ARRAY_BUFFER, buffer)
	gl.BufferData(
		gl.ARRAY_BUFFER,
		int(PARTICLE_COUNT_DEFAULT*unsafe.Sizeof([2]float32{})),
		nil,
		gl.STREAM_DRAW)
	dataPointer := gl.MapBuffer(gl.ARRAY_BUFFER, gl.WRITE_ONLY)
	if dataPointer == nil {
		return fmt.Errorf("buffer data pointer is nil")
	}
	data := (*[PARTICLE_COUNT_DEFAULT][2]float32)(dataPointer)

	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)

	for i := range data {
		p := s.space.Particle(i)
		if p == nil {
			return fmt.Errorf("no particle of id %d", i)
		}
		data[i][0] = float32(p.Position.X)
		data[i][1] = float32(p.Position.Y)
	}
	gl.UnmapBuffer(gl.ARRAY_BUFFER)

	gl.DrawArrays(gl.POINTS, 0, PARTICLE_COUNT_DEFAULT)

	return nil
}
Example #5
0
func (s *MainState) Init(e *engine.E) error {
	// Init Glow
	if err := gl.Init(); err != nil {
		return err
	}

	// Enable debug output
	if glfw3.ExtensionSupported("GL_ARB_debug_output") {
		gl.Enable(gl.DEBUG_OUTPUT_SYNCHRONOUS_ARB)
		gl.DebugMessageCallbackARB(gl.DebugProc(glDebugCallback), nil)
	}

	// Init shaders
	shaderProg := engine.NewShaderProgram()
	if err := shaderProg.ReadShaderFile("vert.glsl", engine.VertexShader); err != nil {
		return err
	}
	if err := shaderProg.ReadShaderFile("geom.glsl", engine.GeometryShader); err != nil {
		return err
	}
	if err := shaderProg.ReadShaderFile("frag.glsl", engine.FragmentShader); err != nil {
		return err
	}
	program, err := shaderProg.Link()
	if err != nil {
		return err
	}
	s.program = program
	gl.UseProgram(program)

	// Manage GL features
	gl.Disable(gl.DEPTH_TEST)
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.Enable(gl.MULTISAMPLE)
	gl.Enable(gl.POLYGON_SMOOTH)
	gl.Enable(gl.PROGRAM_POINT_SIZE)

	// Init VAO
	gl.GenVertexArrays(1, &s.vao)
	gl.BindVertexArray(s.vao)
	e.Defer(func() {
		gl.DeleteVertexArrays(1, &s.vao)
	})

	s.projectionUniform = gl.GetUniformLocation(program, gl.Str("projection\x00"))

	// Init VBO
	gl.GenBuffers(1, &s.vbo)
	gl.BindBuffer(gl.ARRAY_BUFFER, s.vbo)
	e.Defer(func() {
		gl.DeleteBuffers(1, &s.vbo)
	})

	positionAttrib := uint32(gl.GetAttribLocation(program, gl.Str("position\x00")))
	gl.EnableVertexAttribArray(positionAttrib)
	gl.VertexAttribPointer(positionAttrib, 2, gl.FLOAT, false, 0, gl.PtrOffset(0))

	// Init space
	space, err := gputicles.New()
	if err != nil {
		return err
	}
	s.space = space
	/*
		for i := 0; i < PARTICLE_COUNT_DEFAULT; i++ {
			particle := space.MkParticle(PARTICLE_MASS_DEFAULT)
			particle.Position = randVect()
			//particle.Velocity = randVect().Div(8)
		}
	*/
	for i := 0; i < PARTICLE_COUNT_DEFAULT/2; i++ {
		particle := space.MkParticle(PARTICLE_MASS_DEFAULT)
		particle.Position = randVect().Div(2).Add(vect.V{-0.5, -0.5})
	}
	for i := PARTICLE_COUNT_DEFAULT / 2; i < PARTICLE_COUNT_DEFAULT; i++ {
		particle := space.MkParticle(PARTICLE_MASS_DEFAULT)
		particle.Position = randVect().Div(2).Add(vect.V{0.5, 0.5})
	}

	return nil
}
Example #6
0
func (s *MainState) Init(eng *engine.E) error {
	println("initializing state")
	// Init Glow
	if err := gl.Init(); err != nil {
		return err
	}

	// Enable debug output
	if glfw3.ExtensionSupported("GL_ARB_debug_output") {
		gl.Enable(gl.DEBUG_OUTPUT_SYNCHRONOUS_ARB)
		gl.DebugMessageCallbackARB(gl.DebugProc(glDebugCallback), nil)
	}

	shaderProg := engine.NewShaderProgram()
	if err := shaderProg.ReadShaderFile("vert.glsl", engine.VertexShader); err != nil {
		return err
	}
	if err := shaderProg.ReadShaderFile("geom.glsl", engine.GeometryShader); err != nil {
		return err
	}
	if err := shaderProg.ReadShaderFile("frag.glsl", engine.FragmentShader); err != nil {
		return err
	}
	program, err := shaderProg.Link()
	if err != nil {
		return err
	}
	s.program = program
	gl.UseProgram(program)

	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	//gl.Enable(gl.DITHER)
	gl.Enable(gl.MULTISAMPLE)
	gl.Enable(gl.POLYGON_SMOOTH)
	gl.Enable(gl.PROGRAM_POINT_SIZE)

	// Init VAO
	var vao uint32
	gl.GenVertexArrays(1, &vao)
	gl.BindVertexArray(vao)
	s.vertexArray = vao
	eng.Defer(func() {
		gl.DeleteVertexArrays(1, &vao)
	})

	// Set projection
	projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00"))
	gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])

	// Initialize vertex buffer
	var buffer uint32
	gl.GenBuffers(1, &buffer)
	gl.BindBuffer(gl.ARRAY_BUFFER, buffer)
	s.vertexBuffer = buffer
	eng.Defer(func() {
		gl.DeleteBuffers(1, &buffer)
	})

	positionAttrib := uint32(gl.GetAttribLocation(program, gl.Str("position\x00")))
	gl.EnableVertexAttribArray(positionAttrib)
	gl.VertexAttribPointer(positionAttrib, 2, gl.FLOAT, false, 0, gl.PtrOffset(0))

	// Initialize space
	space := leapfrog.New()
	for i := 0; i < PARTICLE_COUNT_DEFAULT; i++ {
		particle := space.MkParticle(PARTICLE_MASS_DEFAULT)
		particle.Position = randVect().Div(2)
	}
	s.space = space

	// Deinit is not part of interface, but can be deferred manually:
	eng.Defer(s.Deinit)

	return nil
}