Esempio n. 1
0
func (t *Texture) ReadTextureFromGPU() []byte {
	t.Bind()
	b := gl.GenBuffer()
	b.Bind(gl.PIXEL_UNPACK_BUFFER)
	gl.BufferData(gl.PIXEL_UNPACK_BUFFER, t.Width()*t.Height()*t.PixelSize(), 0, gl.STREAM_DRAW)
	//gl.GetTexImage(t.target, 0, t.format, buffer)
	b.Bind(gl.PIXEL_UNPACK_BUFFER)

	gl.TexSubImage2D(t.target, 0, 0, 0, t.Width(), t.Height(), t.format, t.typ, unsafe.Pointer(uintptr(0)))
	b.Bind(gl.PIXEL_UNPACK_BUFFER)

	l := t.Width() * t.Height() * t.PixelSize()

	gl.BufferData(gl.PIXEL_UNPACK_BUFFER, t.Width()*t.Height()*t.PixelSize(), 0, gl.STREAM_DRAW)
	ptr := gl.MapBuffer(gl.PIXEL_UNPACK_BUFFER, gl.WRITE_ONLY)

	var x []byte
	s := (*reflect.SliceHeader)(unsafe.Pointer(&x))
	s.Data = uintptr(ptr)
	s.Len = l
	s.Cap = l

	gl.UnmapBuffer(gl.PIXEL_UNPACK_BUFFER)

	return x
}
Esempio n. 2
0
func (v *Video) initGL() {
	if gl.Init() != 0 {
		panic(sdl.GetError())
	}

	gl.ClearColor(0.0, 0.0, 0.0, 1.0)
	gl.Enable(gl.CULL_FACE)
	gl.Enable(gl.DEPTH_TEST)

	v.prog = createProgram(vertShaderSrcDef, fragShaderSrcDef)
	posAttrib := v.prog.GetAttribLocation("vPosition")
	texCoordAttr := v.prog.GetAttribLocation("vTexCoord")
	v.textureUni = v.prog.GetAttribLocation("texture")

	v.texture = gl.GenTexture()
	gl.ActiveTexture(gl.TEXTURE0)
	v.texture.Bind(gl.TEXTURE_2D)

	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)

	v.prog.Use()
	posAttrib.EnableArray()
	texCoordAttr.EnableArray()

	vertVBO := gl.GenBuffer()
	vertVBO.Bind(gl.ARRAY_BUFFER)
	verts := []float32{-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0}
	gl.BufferData(gl.ARRAY_BUFFER, len(verts)*int(unsafe.Sizeof(verts[0])), &verts[0], gl.STATIC_DRAW)

	textCoorBuf := gl.GenBuffer()
	textCoorBuf.Bind(gl.ARRAY_BUFFER)
	texVerts := []float32{0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0}
	gl.BufferData(gl.ARRAY_BUFFER, len(texVerts)*int(unsafe.Sizeof(texVerts[0])), &texVerts[0], gl.STATIC_DRAW)

	posAttrib.AttribPointer(2, gl.FLOAT, false, 0, uintptr(0))
	texCoordAttr.AttribPointer(2, gl.FLOAT, false, 0, uintptr(0))
}
func NewLineRenderer() *LineRenderer {
	renderer := LineRenderer{}
	renderer.Prog = helpers.MakeProgram("Line.vs", "Line.fs")
	renderer.Prog.Use()
	renderer.vao = gl.GenVertexArray()
	renderer.vao.Bind()
	helpers.BindLocations("line", renderer.Prog, &renderer.RenLoc)
	renderer.buffer = gl.GenBuffer()
	renderer.buffer.Bind(gl.ARRAY_BUFFER)
	helpers.SetAttribPointers(&renderer.RenLoc, &debug.LineVertex{}, false)

	fmt.Println("Line render location ", renderer.RenLoc)
	return &renderer
}
func CreateShapeDataBuffer() gl.Buffer {
	fmt.Println("CreateShapeDataBuffer:")

	particleShape := []ParticleShapeVertex{
		{mgl.Vec4{-R, -R, 0, 1}, mgl.Vec2{0, 1}},
		{mgl.Vec4{R, -R, 0, 1}, mgl.Vec2{1, 1}},
		{mgl.Vec4{R, R, 0, 1}, mgl.Vec2{1, 0}},
		{mgl.Vec4{-R, R, 0, 1}, mgl.Vec2{0, 0}},
	}

	particleShapeBuffer := gl.GenBuffer()
	particleShapeBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(particleShape), particleShape, gl.STATIC_DRAW)

	return particleShapeBuffer
}
Esempio n. 5
0
func (drawer *SpriteDrawer) Draw(sprites []Sprite) {

	gl.Viewport(0, 0, drawer.width, drawer.height)

	if len(sprites) == 0 {
		return
	}

	drawer.Use()
	drawer.Texture.Bind(gl.TEXTURE_2D_ARRAY)

	tmp := drawer.GetTransform().To32()
	drawer.camera_uniform.UniformMatrix2x3f(false, &tmp)

	vertexbuffer := gl.GenBuffer()
	defer vertexbuffer.Delete()
	vertexbuffer.Bind(gl.ARRAY_BUFFER)

	stride := int(unsafe.Sizeof(sprites[0]))

	gl.BufferData(gl.ARRAY_BUFFER, stride*len(sprites), sprites, gl.STREAM_DRAW)

	var transform1, transform2, texcoords, texlevel gl.AttribLocation
	transform1 = 0
	transform2 = 1
	texcoords = 2
	texlevel = 3

	transform1.AttribPointer(3, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Transform))
	transform2.AttribPointer(3, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Transform)+unsafe.Sizeof(sprites[0].Transform[0])*3)
	texcoords.AttribPointer(4, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].TextureLeft))
	texlevel.AttribPointer(1, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Layer))

	transform1.EnableArray()
	transform2.EnableArray()
	texcoords.EnableArray()
	texlevel.EnableArray()

	gl.DrawArrays(gl.POINTS, 0, len(sprites))

	transform1.DisableArray()
	transform2.DisableArray()
	texcoords.DisableArray()
	texlevel.DisableArray()
}
Esempio n. 6
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)
		}
	}
}
Esempio n. 7
0
func GenBuffer() VBO {
	return VBO(gl.GenBuffer())
}
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
}
func LoadMeshToGpu(mesh *Mesh, renLoc *RenderLocations) (rd RenderData) {
	rd.VAO = gl.GenVertexArray()
	rd.VAO.Bind()

	{
		vertices := mesh.Vertices
		verticesType := reflect.TypeOf(vertices)
		if verticesType.Kind() != reflect.Slice {
			panic("Vertices is not a slice")
		}
		rd.Vertices = gl.GenBuffer()
		rd.Vertices.Bind(gl.ARRAY_BUFFER)
		gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), vertices, gl.STATIC_DRAW)
		rd.Numverts = reflect.ValueOf(vertices).Len()
		helpers.SetAttribPointers(renLoc, reflect.ValueOf(vertices).Index(0).Addr().Interface(), false)
		switch mesh.Mode {
		case Points:
			rd.Mode = gl.POINTS
		case LineStrip:
			rd.Mode = gl.LINE_STRIP
		case LineLoop:
			rd.Mode = gl.LINE_LOOP
		case Lines:
			rd.Mode = gl.LINES
		case TriangleStrip:
			rd.Mode = gl.TRIANGLE_STRIP
		case TriangleFan:
			rd.Mode = gl.TRIANGLE_FAN
		case Triangles:
			rd.Mode = gl.TRIANGLES
		default:
			panic("unsupported mode")
		}
	}

	if indices := mesh.Indices; indices != nil {
		indicesType := reflect.TypeOf(indices)
		if indicesType.Kind() != reflect.Slice {
			panic("Indices is not a slice")
		}
		rd.Indices = gl.GenBuffer()
		rd.Indices.Bind(gl.ELEMENT_ARRAY_BUFFER)
		gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, helpers.ByteSizeOfSlice(indices), indices, gl.STATIC_DRAW)
		rd.Numverts = reflect.ValueOf(indices).Len()
		switch indicesType.Elem().Kind() {
		case reflect.Uint8, reflect.Int8:
			rd.IndexType = gl.UNSIGNED_BYTE
		case reflect.Uint16, reflect.Int16:
			rd.IndexType = gl.UNSIGNED_SHORT
		case reflect.Uint32, reflect.Int32:
			rd.IndexType = gl.UNSIGNED_INT
		default:
			panic(fmt.Sprint("unsupported index type", indicesType.Elem().Kind()))
		}
	}

	if instanceData := mesh.InstanceData; instanceData != nil {
		Type := reflect.TypeOf(instanceData)
		if Type.Kind() != reflect.Slice {
			panic("InstanceData is not a slice")
		}
		rd.InstanceData = gl.GenBuffer()
		rd.InstanceData.Bind(gl.ARRAY_BUFFER)
		gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(instanceData), instanceData, gl.STATIC_DRAW)
		helpers.SetAttribPointers(renLoc, reflect.ValueOf(instanceData).Index(0).Addr().Interface(), true)

		rd.NumInstances = reflect.ValueOf(instanceData).Len()
	}
	return
}