func MakeProgram3(vertFname, geomFname, fragFname string) gl.Program {
	vertShader := MakeShader(gl.VERTEX_SHADER, vertFname)
	defer vertShader.Delete()
	geomShader := MakeShader(gl.GEOMETRY_SHADER, geomFname)
	defer geomShader.Delete()
	fragShader := MakeShader(gl.FRAGMENT_SHADER, fragFname)
	defer fragShader.Delete()

	program := gl.CreateProgram()
	program.AttachShader(vertShader)
	program.AttachShader(geomShader)
	program.AttachShader(fragShader)
	program.Link()

	log := program.GetInfoLog()
	if log != "" {
		if program.Get(gl.LINK_STATUS) == gl.FALSE {
			panic(fmt.Sprint("linking ", vertFname, geomFname, fragFname, log))
		} else {
			fmt.Print("linking ", vertFname, geomFname, fragFname, log)
		}
	}

	return program
}
Example #2
0
func createProgram(vertShaderSrc string, fragShaderSrc string) gl.Program {
	vertShader := loadShader(gl.VERTEX_SHADER, vertShaderSrc)
	fragShader := loadShader(gl.FRAGMENT_SHADER, fragShaderSrc)

	prog := gl.CreateProgram()

	prog.AttachShader(vertShader)
	prog.AttachShader(fragShader)
	prog.Link()

	if prog.Get(gl.LINK_STATUS) != gl.TRUE {
		log := prog.GetInfoLog()
		panic(fmt.Errorf("Failed to link program: %v", log))
	}

	return prog
}
Example #3
0
func CreateProgram(filenames ...string) gl.Program {

	program := gl.CreateProgram()

	for _, fn := range filenames {

		var shaderType gl.GLenum

		switch {
		case strings.HasSuffix(fn, ".vert"):
			shaderType = gl.VERTEX_SHADER
		case strings.HasSuffix(fn, ".geom"):
			shaderType = gl.GEOMETRY_SHADER
		case strings.HasSuffix(fn, ".frag"):
			shaderType = gl.FRAGMENT_SHADER
		default:
			fmt.Println("Wrong suffix: " + fn)
		}

		shader := gl.CreateShader(shaderType)
		defer shader.Delete()

		shader.Source(ReadFile(fn))
		shader.Compile()
		if info := shader.GetInfoLog(); info != "" {
			log.Fatal(info)
		}

		program.AttachShader(shader)
		defer program.DetachShader(shader)
	}

	program.Link()
	if info := program.GetInfoLog(); info != "" {
		log.Fatal(info)
	}

	return program
}
func MakeProgram(vertFname, fragFname string) gl.Program {
	vao := gl.GenVertexArray()
	vao.Bind()

	vertShader := MakeShader(gl.VERTEX_SHADER, vertFname)
	defer vertShader.Delete()
	fragShader := MakeShader(gl.FRAGMENT_SHADER, fragFname)
	defer fragShader.Delete()

	program := gl.CreateProgram()
	program.AttachShader(vertShader)
	program.AttachShader(fragShader)
	program.Link()

	linkstat := program.Get(gl.LINK_STATUS)
	if linkstat != 1 {
		// log.Panic("Program link failed, sources=", vertFname, fragFname, "\nstatus=", linkstat, "\nInfo log: ", program.GetInfoLog())
	}

	program.Validate()
	valstat := program.Get(gl.VALIDATE_STATUS)
	if valstat != 1 {
		// log.Panic("Program validation failed: ", valstat)
	}

	log := program.GetInfoLog()
	if log != "" {
		if program.Get(gl.LINK_STATUS) == gl.FALSE {
			panic(fmt.Sprint("linking ", vertFname, fragFname, log))
		} else {
			fmt.Print("linking ", vertFname, fragFname, log)
		}
	}

	vao.Delete()

	return program
}
Example #5
0
func main() {
	glfw.SetErrorCallback(errorCallback)
	// lock glfw/gl calls to a single thread
	runtime.LockOSThread()
	runtime.GOMAXPROCS(8) // Render, read commands, send input, extra for file loading, etc

	if !glfw.Init() {
		panic("Could not init glfw!")
	}

	defer glfw.Terminate()

	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)

	window, err := glfw.CreateWindow(800, 600, "Example", nil, nil)
	if err != nil {
		panic(err)
	}

	window.SetFramebufferSizeCallback(func(w *glfw.Window, width, height int) {
		fmt.Printf("Framebuffer size is now %vx%v\n", width, height)
		// Keep aspect ratio from camwidth/camheight
		camRatio := camWidth / camHeight
		bufRatio := float32(width) / float32(height)
		var newWidth, newHeight float32

		switch {
		case camRatio > bufRatio:
			newHeight = float32(width) / camRatio
			newWidth = float32(width)
		case bufRatio > camRatio:
			newWidth = float32(height) * camRatio
			newHeight = float32(height)
		}

		fmt.Printf("Viewport size is now %vx%v; cam ratio is %v; viewport ratio is %v;\n", newWidth, newHeight, camRatio, newWidth/newHeight)

		gl.Viewport((width-int(newWidth))/2, (height-int(newHeight))/2, int(newWidth), int(newHeight))
	})

	defer window.Destroy()

	window.MakeContextCurrent()
	glfw.SwapInterval(1)

	gl.Init()

	// Enable blending
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

	vao := gl.GenVertexArray()
	vao.Bind()

	vbo := gl.GenBuffer()
	vbo.Bind(gl.ARRAY_BUFFER)

	verticies := []float32{-0.5, 0.5,
		0.5, 0.5,
		0.5, -0.5,
		-0.5, -0.5}

	gl.BufferData(gl.ARRAY_BUFFER, len(verticies)*4, verticies, gl.STATIC_DRAW)

	vertex_shader := gl.CreateShader(gl.VERTEX_SHADER)
	vertex_shader.Source(vertex)
	vertex_shader.Compile()
	fmt.Println(vertex_shader.GetInfoLog())
	defer vertex_shader.Delete()

	fragment_shader := gl.CreateShader(gl.FRAGMENT_SHADER)
	fragment_shader.Source(fragment)
	fragment_shader.Compile()
	fmt.Println(fragment_shader.GetInfoLog())
	defer fragment_shader.Delete()

	program := gl.CreateProgram()
	program.AttachShader(vertex_shader)
	program.AttachShader(fragment_shader)

	program.BindFragDataLocation(0, "outColor")
	program.Link()
	program.Use()
	defer program.Delete()

	positionAttrib := program.GetAttribLocation("position")
	positionAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil)
	positionAttrib.EnableArray()
	defer positionAttrib.DisableArray()

	modelMat := program.GetUniformLocation("modelView")
	projMat := program.GetUniformLocation("projection")
	spriteSize := program.GetUniformLocation("size")

	cmd := exec.Command(os.Args[1], os.Args[2:]...)
	stdoutReader, stdoutWriter := io.Pipe()
	cmd.Stdout = stdoutWriter
	input := bufio.NewReader(stdoutReader)

	stdinReader, stdinWriter := io.Pipe()
	cmd.Stdin = stdinReader

	stderr, err := cmd.StderrPipe()
	chkErr(err)

	go io.Copy(os.Stderr, stderr)

	err = cmd.Start()
	chkErr(err)

	window.SetKeyCallback(handleKey)

	go func() {
		runtime.LockOSThread()
		for !window.ShouldClose() {
			sendInput(stdinWriter)
			//fmt.Fprintf(stdinWriter, "T %v\n", time.Now())
			<-ticks
			readCommands(input)
		}
	}()

	frameCnt := 0
	queueDepth := 0
	then := time.Now()

	for !window.ShouldClose() {
		frameCnt++
		queueDepth += len(commandBus)
		if frameCnt%120 == 0 {
			fmt.Printf("Queue depth: %v. Render time: %v. Decode time: %v.\n", queueDepth/120, time.Since(then)/120, decodeTime/time.Duration(decodes))
			queueDepth = 0
			then = time.Now()
			decodeTime = time.Duration(0)
			decodes = 0
		}

		for len(commandBus) > 0 {
			(<-commandBus)()
		}

		halfwidth := camWidth / 2.0
		halfheight := camHeight / 2.0
		projection := mathgl.Ortho2D(camera.x-halfwidth, camera.x+halfwidth, camera.y+halfheight, camera.y-halfheight)
		projection = mathgl.Scale3D(camera.sx, camera.sy, 1).Mul4(projection)
		projection = mathgl.HomogRotate3DZ(camera.rot).Mul4(projection)

		projMat.UniformMatrix4f(false, (*[16]float32)(&projection))

		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		for _, sprite := range sprites {
			sMat := mathgl.Scale3D(sprite.sx, sprite.sy, 1)
			sMat = mathgl.HomogRotate3DZ(sprite.rot).Mul4(sMat)
			sMat = mathgl.Translate3D(sprite.x, sprite.y, sprite.z).Mul4(sMat)

			// temp hack bank in
			sprite.bank = 1

			sMap := findSMap(sprite.smap)

			spriteSize.Uniform2f(float32(sMap.getWidth()*sprite.cellwidth), float32(sMap.getHeight()*sprite.cellheight))

			modelMat.UniformMatrix4f(false, (*[16]float32)(&sMat))
			gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
		}

		window.SwapBuffers()
		glfw.PollEvents()

		if window.GetKey(glfw.KeyEscape) == glfw.Press {
			window.SetShouldClose(true)
		}
	}
}
Example #6
0
func NewBasicMaterial(vertexShader, fragmentShader string) *BasicMaterial {
	return &BasicMaterial{Program: Program{gl.CreateProgram()}, vertexShader: vertexShader, fragmentShader: fragmentShader}
}
func NewParticleSystem(w *gamestate.World, numParticles int, Origin mgl.Vec3, initialSpeed, MaxLifetime float32) *ParticleSystem {
	vertices := make([]ParticleVertex, numParticles)
	directions := make([]NonTransformBuffer, numParticles)

	for i := range vertices {
		dir := mgl.Vec3{rand.Float32()*2 - 1, rand.Float32()*2 - 1, rand.Float32()*2 - 1}
		for dir.Len() > 1 {
			dir = mgl.Vec3{rand.Float32()*2 - 1, rand.Float32()*2 - 1, rand.Float32()*2 - 1}
		}
		dir = dir.Mul(initialSpeed)
		vertices[i] = ParticleVertex{
			Pos1:     Origin,
			Pos2:     Origin.Sub(dir),
			Lifetime: rand.Float32() * MaxLifetime,
		}
		directions[i] = NonTransformBuffer{dir}
	}

	buffer1, buffer2, nonTransformBuffer := gl.GenBuffer(), gl.GenBuffer(), gl.GenBuffer()

	nonTransformBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(directions), directions, gl.STATIC_DRAW)

	buffer1.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), vertices, gl.STREAM_DRAW)

	buffer2.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), uintptr(0), gl.STREAM_DRAW)

	shapeData := CreateShapeDataBuffer()

	TransformProg := gl.CreateProgram()

	shader := helpers.MakeShader(gl.VERTEX_SHADER, "ParticleTFF.vs")
	TransformProg.AttachShader(shader)
	TransformProg.TransformFeedbackVaryings([]string{"v_Pos1", "v_Pos2", "v_Lifetime"}, gl.INTERLEAVED_ATTRIBS)
	TransformProg.Link()
	shader.Delete()

	TransformProg.Use()

	TransformLoc := ProgramLocations{}
	helpers.BindLocations("particle transform", TransformProg, &TransformLoc)

	renderProgram := helpers.MakeProgram("Particle.vs", "Particle.fs")
	renderProgram.Use()
	RenderLoc := RenderProgramLocations{}
	helpers.BindLocations("particle render", renderProgram, &RenderLoc)

	vaoTff1 := gl.GenVertexArray()
	vaoTff2 := gl.GenVertexArray()
	vaoRender1 := gl.GenVertexArray()
	vaoRender2 := gl.GenVertexArray()

	ps := ParticleSystem{
		TransformProg:      TransformProg,
		TransformLoc:       TransformLoc,
		RenderProg:         renderProgram,
		RenderLoc:          RenderLoc,
		VaoTff1:            vaoTff1,
		VaoTff2:            vaoTff2,
		VaoRender1:         vaoRender1,
		VaoRender2:         vaoRender2,
		Data1:              buffer1,
		Data2:              buffer2,
		ShapeData:          shapeData,
		NonTransformBuffer: nonTransformBuffer,
		NumParticles:       numParticles,
		Origin:             Origin,
		Gravity:            -9.81 / 200,
		InitialSpeed:       initialSpeed,
		MaxLifetime:        MaxLifetime,
	}

	min_h, max_h := w.HeightMap.Bounds()
	W := float32(w.HeightMap.W)
	H := float32(w.HeightMap.H)

	TransformProg.Use()
	ps.SetUniforms()
	ps.SetVaos()

	TransformProg.Use()

	ps.TransformLoc.HeightMap.Uniform1i(constants.TextureHeightMap)
	ps.TransformLoc.LowerBound.Uniform3f(0, 0, min_h)
	ps.TransformLoc.UpperBound.Uniform3f(W, H, max_h)

	return &ps
}