Exemplo n.º 1
0
func LoadTexture(name string) (tex gl.Texture, err error) {
	imgFile, err := asset.Open(name)
	if err != nil {
		return
	}
	img, _, err := image.Decode(imgFile)
	if err != nil {
		return
	}

	rgba := image.NewRGBA(img.Bounds())
	image_draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, image_draw.Src)

	tex = gl.CreateTexture()
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, tex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexImage2D(
		gl.TEXTURE_2D,
		0,
		rgba.Rect.Size().X,
		rgba.Rect.Size().Y,
		gl.RGBA,
		gl.UNSIGNED_BYTE,
		rgba.Pix)

	return
}
Exemplo n.º 2
0
func (video *Video) drawFrame() {
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	gl.UseProgram(video.prog)
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, video.texture)

	log.Print("Reading")
	frame := <-video.pixelBuffer
	buf := make([]float32, len(frame))
	log.Print("Read frame")

	for k, v := range frame {
		buf[k] = float32(v)
	}

	log.Print("Writing")
	if video.pixelBuffer != nil {
		gl.TexImage2D(gl.TEXTURE_2D, 0, 256, 256, gl.RGBA,
			gl.UNSIGNED_SHORT_4_4_4_4, f32.Bytes(binary.LittleEndian, buf...))
	}
	log.Print("Wrote")

	gl.DrawArrays(gl.TRIANGLES, 0, 6)
	video.fpsmanager.FramerateDelay()
}
Exemplo n.º 3
0
// NewImage creates an Image of the given size.
//
// Both a host-memory *image.RGBA and a GL texture are created.
func NewImage(w, h int) *Image {
	dx := roundToPower2(w)
	dy := roundToPower2(h)

	// TODO(crawshaw): Using VertexAttribPointer we can pass texture
	// data with a stride, which would let us use the exact number of
	// pixels on the host instead of the rounded up power 2 size.
	m := image.NewRGBA(image.Rect(0, 0, dx, dy))

	glimage.Do(glInit)

	img := &Image{
		RGBA:      m.SubImage(image.Rect(0, 0, w, h)).(*image.RGBA),
		Texture:   gl.GenTexture(),
		texWidth:  dx,
		texHeight: dy,
	}
	// TODO(crawshaw): We don't have the context on a finalizer. Find a way.
	// runtime.SetFinalizer(img, func(img *Image) { gl.DeleteTexture(img.Texture) })
	gl.BindTexture(gl.TEXTURE_2D, img.Texture)
	gl.TexImage2D(gl.TEXTURE_2D, 0, dx, dy, gl.RGBA, gl.UNSIGNED_BYTE, nil)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

	return img
}
Exemplo n.º 4
0
func (w *windowImpl) Draw(src2dst f64.Aff3, src screen.Texture, sr image.Rectangle, op draw.Op, opts *screen.DrawOptions) {
	t := src.(*textureImpl)
	a := w.vertexAff3(sr)

	gl.UseProgram(w.s.texture.program)
	writeAff3(w.s.texture.mvp, mul(a, src2dst))

	// OpenGL's fragment shaders' UV coordinates run from (0,0)-(1,1),
	// unlike vertex shaders' XY coordinates running from (-1,+1)-(+1,-1).
	//
	// We are drawing a rectangle PQRS, defined by two of its
	// corners, onto the entire texture. The two quads may actually
	// be equal, but in the general case, PQRS can be smaller.
	//
	//	(0,0) +---------------+ (1,0)
	//	      |  P +-----+ Q  |
	//	      |    |     |    |
	//	      |  S +-----+ R  |
	//	(0,1) +---------------+ (1,1)
	//
	// The PQRS quad is always axis-aligned. First of all, convert
	// from pixel space to texture space.
	tw := float64(t.size.X)
	th := float64(t.size.Y)
	px := float64(sr.Min.X-0) / tw
	py := float64(sr.Min.Y-0) / th
	qx := float64(sr.Max.X-0) / tw
	sy := float64(sr.Max.Y-0) / th
	// Due to axis alignment, qy = py and sx = px.
	//
	// The simultaneous equations are:
	//	  0 +   0 + a02 = px
	//	  0 +   0 + a12 = py
	//	a00 +   0 + a02 = qx
	//	a10 +   0 + a12 = qy = py
	//	  0 + a01 + a02 = sx = px
	//	  0 + a11 + a12 = sy
	writeAff3(w.s.texture.uvp, f64.Aff3{
		qx - px, 0, px,
		0, sy - py, py,
	})

	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, t.id)
	gl.Uniform1i(w.s.texture.sample, 0)

	gl.BindBuffer(gl.ARRAY_BUFFER, w.s.texture.quadXY)
	gl.EnableVertexAttribArray(w.s.texture.pos)
	gl.VertexAttribPointer(w.s.texture.pos, 2, gl.FLOAT, false, 0, 0)

	gl.BindBuffer(gl.ARRAY_BUFFER, w.s.texture.quadUV)
	gl.EnableVertexAttribArray(w.s.texture.inUV)
	gl.VertexAttribPointer(w.s.texture.inUV, 2, gl.FLOAT, false, 0, 0)

	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)

	gl.DisableVertexAttribArray(w.s.texture.pos)
	gl.DisableVertexAttribArray(w.s.texture.inUV)
}
Exemplo n.º 5
0
func (t *textureImpl) Upload(dp image.Point, src screen.Buffer, sr image.Rectangle, sender screen.Sender) {
	// TODO: adjust if dp is outside dst bounds, or sr is outside src bounds.
	gl.BindTexture(gl.TEXTURE_2D, t.id)
	m := src.RGBA().SubImage(sr).(*image.RGBA)
	b := m.Bounds()
	// TODO check m bounds smaller than t.size
	gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, b.Dx(), b.Dy(), gl.RGBA, gl.UNSIGNED_BYTE, m.Pix)
	// TODO: send a screen.UploadedEvent.
}
Exemplo n.º 6
0
func (e *Engine) Draw(c size.Event) {

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

	gl.ClearColor(0.2, 0.2, 0.2, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.Clear(gl.DEPTH_BUFFER_BIT)

	gl.UseProgram(e.shader.program)

	m := mgl32.Perspective(0.785, float32(c.WidthPt/c.HeightPt), 0.1, 10.0)
	gl.UniformMatrix4fv(e.shader.projection, m[:])

	eye := mgl32.Vec3{0, 0, 8}
	center := mgl32.Vec3{0, 0, 0}
	up := mgl32.Vec3{0, 1, 0}

	m = mgl32.LookAtV(eye, center, up)
	gl.UniformMatrix4fv(e.shader.view, m[:])

	m = mgl32.HomogRotate3D(float32(e.touchLoc.X/c.WidthPt-0.5)*3.14*2, mgl32.Vec3{0, 1, 0})
	gl.UniformMatrix4fv(e.shader.modelx, m[:])

	m = mgl32.HomogRotate3D(float32(e.touchLoc.Y/c.HeightPt-0.5)*3.14, mgl32.Vec3{1, 0, 0})
	gl.UniformMatrix4fv(e.shader.modely, m[:])

	coordsPerVertex := 3
	for _, obj := range e.shape.Objs {
		gl.BindBuffer(gl.ARRAY_BUFFER, obj.coord)
		gl.EnableVertexAttribArray(e.shader.vertCoord)

		gl.VertexAttribPointer(e.shader.vertCoord, coordsPerVertex, gl.FLOAT, false, 12, 0)

		if obj.useuv == true {
			gl.Uniform1i(e.shader.useuv, 1)
			texCoordsPerVertex := 2
			gl.BindBuffer(gl.ARRAY_BUFFER, obj.uvcoord)
			gl.EnableVertexAttribArray(e.shader.vertTexCoord)
			gl.VertexAttribPointer(e.shader.vertTexCoord, texCoordsPerVertex, gl.FLOAT, false, 8, 0)

			gl.BindTexture(gl.TEXTURE_2D, obj.tex)
		} else {
			gl.Uniform1i(e.shader.useuv, 0)
			gl.Uniform4f(e.shader.color, obj.color[0], obj.color[1], obj.color[2], obj.color[3])
		}
		gl.DrawArrays(gl.TRIANGLES, 0, obj.vcount)
		if obj.useuv {
			gl.DisableVertexAttribArray(e.shader.vertTexCoord)
		}
		gl.DisableVertexAttribArray(e.shader.vertCoord)
	}

	debug.DrawFPS(c)
}
Exemplo n.º 7
0
func (e *Engine) Draw(c size.Event) {

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

	gl.ClearColor(0.5, 0.8, 0.8, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.Clear(gl.DEPTH_BUFFER_BIT)

	gl.UseProgram(e.shader.program)

	gl.Uniform3fv(e.shader.lightdir, []float32{0.5, 0.6, 0.7})

	m := mgl32.Perspective(1.3, float32(c.WidthPt/c.HeightPt), 0.1, 10.0)
	gl.UniformMatrix4fv(e.shader.projectionmatrix, m[:])

	eye := mgl32.Vec3{0, 0, 0.2}
	center := mgl32.Vec3{0, 0, 0}
	up := mgl32.Vec3{0, 1, 0}

	m = mgl32.LookAtV(eye, center, up)
	gl.UniformMatrix4fv(e.shader.viewmatrix, m[:])

	m = mgl32.HomogRotate3D((e.touchx/float32(c.WidthPt)-0.5)*6.28, mgl32.Vec3{0, 1, 0})
	gl.UniformMatrix4fv(e.shader.modelmatrix, m[:])

	m = mgl32.HomogRotate3D((e.touchx/float32(c.WidthPt)-0.5)*6.28, mgl32.Vec3{0, -1, 0})
	gl.UniformMatrix4fv(e.shader.lightmatrix, m[:])

	coordsPerVertex := 3
	for _, obj := range e.shape.Objs {
		gl.BindBuffer(gl.ARRAY_BUFFER, obj.coord)
		gl.EnableVertexAttribArray(e.shader.vertCoord)
		gl.VertexAttribPointer(e.shader.vertCoord, coordsPerVertex, gl.FLOAT, false, 12, 0)

		texCoordsPerVertex := 2
		gl.BindBuffer(gl.ARRAY_BUFFER, obj.uvcoord)
		gl.EnableVertexAttribArray(e.shader.texcoord)
		gl.VertexAttribPointer(e.shader.texcoord, texCoordsPerVertex, gl.FLOAT, false, 8, 0)

		gl.BindBuffer(gl.ARRAY_BUFFER, obj.normal)
		gl.EnableVertexAttribArray(e.shader.normal)
		gl.VertexAttribPointer(e.shader.normal, 3, gl.FLOAT, false, 12, 0)

		gl.BindTexture(gl.TEXTURE_2D, obj.tex)

		gl.DrawArrays(gl.TRIANGLES, 0, obj.vcount)

		gl.DisableVertexAttribArray(e.shader.texcoord)
		gl.DisableVertexAttribArray(e.shader.normal)
		gl.DisableVertexAttribArray(e.shader.vertCoord)
	}

	debug.DrawFPS(c)
}
Exemplo n.º 8
0
func onPaint(sz size.Event) {
	gl.ClearColor(rgb(156), rgb(39), rgb(176), 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)

	var rotationMatrix = []float32{
		f32.Cos(-alpha), -f32.Sin(-alpha), 0.0,
		f32.Sin(-alpha), f32.Cos(-alpha), 0.0,
		0.0, 0.0, 1.0,
	}

	gl.UseProgram(program)
	// setting color
	gl.Uniform4f(color, rgb(255), rgb(255), rgb(255), 1)
	gl.UniformMatrix3fv(matrixId, rotationMatrix)
	gl.Uniform1f(resolutionId, resIndex)

	gl.BindBuffer(gl.ARRAY_BUFFER, swasBuffer)

	gl.EnableVertexAttribArray(position)
	gl.VertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0)
	gl.DrawArrays(gl.LINES, 0, 16)
	gl.DisableVertexAttribArray(position)

	gl.UseProgram(texProgram)
	// setting color
	gl.Uniform4f(color2, rgb(130), rgb(50), rgb(80), 1)
	gl.Uniform1f(resolutionId2, resIndex)
	gl.UniformMatrix3fv(matrixId2, rotationMatrix)

	gl.BindBuffer(gl.ARRAY_BUFFER, quadBuffer)
	gl.EnableVertexAttribArray(position2)
	gl.VertexAttribPointer(position2, 3, gl.FLOAT, false, 0, 0)

	gl.BindBuffer(gl.ARRAY_BUFFER, quadTexBuffer)
	gl.EnableVertexAttribArray(textureCoords)
	gl.VertexAttribPointer(textureCoords, 2, gl.FLOAT, false, 0, 0)

	gl.Uniform1i(gl.GetUniformLocation(texProgram, "myTexture"), 0)
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, textureId)

	gl.DrawArrays(gl.TRIANGLES, 0, 6)
	gl.DisableVertexAttribArray(position2)
	gl.DisableVertexAttribArray(textureCoords)

	if spin == true {
		alpha += 0.1
	}

	if alpha >= 360 {
		alpha = 0.0
	}

}
Exemplo n.º 9
0
func (video *Video) initGL() {
	log.Print("Initing")
	video.fpsmanager = gfx.NewFramerate()
	video.fpsmanager.SetFramerate(60)

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

	log.Print("Creating program")
	video.prog = createProgram(vertShaderSrcDef, fragShaderSrcDef)
	log.Print("Attrib loc 1")
	posAttrib := attribLocation(video.prog, "vPosition")
	log.Print("Attrib loc 2")
	texCoordAttr := attribLocation(video.prog, "vTexCoord")
	log.Print("Uniform loc 1")
	paletteLoc := uniformLocation(video.prog, "palette")
	log.Print("Uniform loc 2")
	video.textureUni = uniformLocation(video.prog, "texture")

	log.Print("Gen Texture")
	video.texture = genTexture()
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, video.texture)

	log.Print("TexParam")
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)

	gl.UseProgram(video.prog)
	gl.EnableVertexAttribArray(posAttrib)
	gl.EnableVertexAttribArray(texCoordAttr)

	gl.Uniform3iv(paletteLoc, nes.SPaletteRgb)

	log.Print("VertBO")
	vertVBO := genBuffer()
	checkGLError()
	gl.BindBuffer(gl.ARRAY_BUFFER, vertVBO)
	verts := f32.Bytes(binary.LittleEndian, -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, verts, gl.STATIC_DRAW)

	textCoorBuf := genBuffer()
	checkGLError()
	gl.BindBuffer(gl.ARRAY_BUFFER, textCoorBuf)
	texVerts := f32.Bytes(binary.LittleEndian, 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, texVerts, gl.STATIC_DRAW)

	gl.VertexAttribPointer(posAttrib, 2, gl.FLOAT, false, 0, 0)
	gl.VertexAttribPointer(texCoordAttr, 2, gl.FLOAT, false, 0, 0)
	log.Print("Started")
}
Exemplo n.º 10
0
func (e *Engine) Draw(c size.Event) {
	since := time.Now().Sub(e.started)
	//gl.Enable()

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

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

	gl.UseProgram(e.shader.program)

	m := mgl32.Perspective(0.785, float32(c.WidthPt/c.HeightPt), 0.1, 10.0)
	gl.UniformMatrix4fv(e.shader.projection, m[:])

	eye := mgl32.Vec3{3, 3, 3}
	center := mgl32.Vec3{0, 0, 0}
	up := mgl32.Vec3{0, 1, 0}

	m = mgl32.LookAtV(eye, center, up)
	gl.UniformMatrix4fv(e.shader.view, m[:])

	m = mgl32.HomogRotate3D(float32(since.Seconds()), mgl32.Vec3{0, 1, 0})
	gl.UniformMatrix4fv(e.shader.model, m[:])

	gl.BindBuffer(gl.ARRAY_BUFFER, e.shape.buf)

	coordsPerVertex := 3
	texCoordsPerVertex := 2
	vertexCount := len(cubeData) / (coordsPerVertex + texCoordsPerVertex)

	gl.EnableVertexAttribArray(e.shader.vertCoord)
	gl.VertexAttribPointer(e.shader.vertCoord, coordsPerVertex, gl.FLOAT, false, 20, 0) // 4 bytes in float, 5 values per vertex

	gl.EnableVertexAttribArray(e.shader.vertTexCoord)
	gl.VertexAttribPointer(e.shader.vertTexCoord, texCoordsPerVertex, gl.FLOAT, false, 20, 12)

	gl.BindTexture(gl.TEXTURE_2D, e.shape.texture)

	gl.DrawArrays(gl.TRIANGLES, 0, vertexCount)

	gl.DisableVertexAttribArray(e.shader.vertCoord)

	debug.DrawFPS(c)
}
Exemplo n.º 11
0
func (e *Engine) Draw(c event.Config) {
	since := time.Now().Sub(e.started)

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

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

	gl.UseProgram(e.shader.program)

	// Setup MVP
	var m mgl.Mat4
	m = mgl.Perspective(0.785, float32(c.Width/c.Height), 0.1, 10.0)
	gl.UniformMatrix4fv(e.shader.projection, m[:])

	m = mgl.LookAtV(
		mgl.Vec3{3, 3, 3}, // eye
		mgl.Vec3{0, 0, 0}, // center
		mgl.Vec3{0, 1, 0}, // up
	)
	gl.UniformMatrix4fv(e.shader.view, m[:])

	m = mgl.HomogRotate3D(float32(since.Seconds()), mgl.Vec3{0, 1, 0})
	gl.UniformMatrix4fv(e.shader.model, m[:])

	// Draw our shape
	gl.BindBuffer(gl.ARRAY_BUFFER, e.shape.buf)

	gl.EnableVertexAttribArray(e.shader.vertCoord)
	gl.VertexAttribPointer(e.shader.vertCoord, e.shape.coordsPerVertex, gl.FLOAT, false, 20, 0) // 4 bytes in float, 5 values per vertex

	gl.EnableVertexAttribArray(e.shader.vertTexCoord)
	gl.VertexAttribPointer(e.shader.vertTexCoord, e.shape.texCoordsPerVertex, gl.FLOAT, false, 20, 12)

	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, e.shape.texture)

	gl.DrawArrays(gl.TRIANGLES, 0, e.shape.vertexCount)

	gl.DisableVertexAttribArray(e.shader.vertCoord)

	//debug.DrawFPS(c)
}
Exemplo n.º 12
0
func onStart() {
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)

	texture := loadImages("495.png")

	textureId = gl.CreateTexture()
	gl.BindTexture(gl.TEXTURE_2D, textureId)

	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)

	gl.TexImage2D(gl.TEXTURE_2D, 0, texture.Rect.Size().X, texture.Rect.Size().Y, gl.RGBA, gl.UNSIGNED_BYTE, texture.Pix)

	// loading Shaders & linking programs
	program = createProgram("vShader.vs", "fShader.vs")
	texProgram = createProgram("vTexShader.vs", "fTexShader.vs")

	quadBuffer = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, quadBuffer)
	gl.BufferData(gl.ARRAY_BUFFER, quadData, gl.STATIC_DRAW)

	quadTexBuffer = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, quadTexBuffer)
	gl.BufferData(gl.ARRAY_BUFFER, quadTexData, gl.STATIC_DRAW)

	swasBuffer = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, swasBuffer)
	gl.BufferData(gl.ARRAY_BUFFER, swastikaData, gl.STATIC_DRAW)

	position = gl.GetAttribLocation(program, "position")
	color = gl.GetUniformLocation(program, "color")
	matrixId = gl.GetUniformLocation(program, "rotationMatrix")
	resolutionId = gl.GetUniformLocation(program, "resIndex")

	position2 = gl.GetAttribLocation(texProgram, "position")
	textureCoords = gl.GetAttribLocation(texProgram, "texCoords")
	matrixId2 = gl.GetUniformLocation(texProgram, "rotationMatrix")
	resolutionId2 = gl.GetUniformLocation(texProgram, "resIndex")
	color2 = gl.GetUniformLocation(texProgram, "color")
}
Exemplo n.º 13
0
// init creates an underlying GL texture for a key.
// Must be called with a valid GL context.
// Must hold tm.Mutex before calling.
func (tm *texmapCache) init(key texmapKey) {
	tex := tm.texs[key]
	if tex.gltex.Value != 0 {
		panic(fmt.Sprintf("attempting to init key (%v) with valid texture", key))
	}
	tex.gltex = gl.CreateTexture()

	gl.BindTexture(gl.TEXTURE_2D, tex.gltex)
	gl.TexImage2D(gl.TEXTURE_2D, 0, tex.width, tex.height, gl.RGBA, gl.UNSIGNED_BYTE, nil)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

	for _, t := range tm.toDelete {
		gl.DeleteTexture(t)
	}
	tm.toDelete = nil
}
Exemplo n.º 14
0
func (s *screenImpl) NewTexture(size image.Point) (screen.Texture, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if !gl.IsProgram(s.texture.program) {
		p, err := compileProgram(textureVertexSrc, textureFragmentSrc)
		if err != nil {
			return nil, err
		}
		s.texture.program = p
		s.texture.pos = gl.GetAttribLocation(p, "pos")
		s.texture.mvp = gl.GetUniformLocation(p, "mvp")
		s.texture.uvp = gl.GetUniformLocation(p, "uvp")
		s.texture.inUV = gl.GetAttribLocation(p, "inUV")
		s.texture.sample = gl.GetUniformLocation(p, "sample")
		s.texture.quadXY = gl.CreateBuffer()
		s.texture.quadUV = gl.CreateBuffer()

		gl.BindBuffer(gl.ARRAY_BUFFER, s.texture.quadXY)
		gl.BufferData(gl.ARRAY_BUFFER, quadXYCoords, gl.STATIC_DRAW)
		gl.BindBuffer(gl.ARRAY_BUFFER, s.texture.quadUV)
		gl.BufferData(gl.ARRAY_BUFFER, quadUVCoords, gl.STATIC_DRAW)
	}

	t := &textureImpl{
		id:   gl.CreateTexture(),
		size: size,
	}

	gl.BindTexture(gl.TEXTURE_2D, t.id)
	gl.TexImage2D(gl.TEXTURE_2D, 0, size.X, size.Y, gl.RGBA, gl.UNSIGNED_BYTE, nil)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

	return t, nil
}
Exemplo n.º 15
0
func (shape *Skybox) Draw(camera Camera) {
	shader := shape.shader

	gl.DepthFunc(gl.LEQUAL)
	gl.DepthMask(false)

	projection, view := camera.Projection(), camera.View().Mat3().Mat4()
	gl.UniformMatrix4fv(shader.Uniform("projection"), projection[:])
	gl.UniformMatrix4fv(shader.Uniform("view"), view[:])

	gl.BindTexture(gl.TEXTURE_CUBE_MAP, shape.Texture)

	gl.BindBuffer(gl.ARRAY_BUFFER, shape.VBO)
	gl.EnableVertexAttribArray(shader.Attrib("vertCoord"))
	gl.VertexAttribPointer(shader.Attrib("vertCoord"), vertexDim, gl.FLOAT, false, shape.Stride(), 0)

	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, shape.IBO)
	gl.DrawElements(gl.TRIANGLES, len(shape.indices), gl.UNSIGNED_BYTE, 0)
	gl.DisableVertexAttribArray(shader.Attrib("vertCoord"))

	gl.DepthMask(true)
	gl.DepthFunc(gl.LESS)
}
Exemplo n.º 16
0
// Draw draws the srcBounds part of the image onto a parallelogram, defined by
// three of its corners, in the current GL framebuffer.
func (img *Image) Draw(topLeft, topRight, bottomLeft geom.Point, srcBounds image.Rectangle) {
	// TODO(crawshaw): Adjust viewport for the top bar on android?
	gl.UseProgram(glimage.program)

	{
		// We are drawing a parallelogram PQRS, defined by three of its
		// corners, onto the entire GL framebuffer ABCD. The two quads may
		// actually be equal, but in the general case, PQRS can be smaller,
		// and PQRS is not necessarily axis-aligned.
		//
		//	A +---------------+ B
		//	  |  P +-----+ Q  |
		//	  |    |     |    |
		//	  |  S +-----+ R  |
		//	D +---------------+ C
		//
		// There are two co-ordinate spaces: geom space and framebuffer space.
		// In geom space, the ABCD rectangle is:
		//
		//	(0, 0)           (geom.Width, 0)
		//	(0, geom.Height) (geom.Width, geom.Height)
		//
		// and the PQRS quad is:
		//
		//	(topLeft.X,    topLeft.Y)    (topRight.X, topRight.Y)
		//	(bottomLeft.X, bottomLeft.Y) (implicit,   implicit)
		//
		// In framebuffer space, the ABCD rectangle is:
		//
		//	(-1, +1) (+1, +1)
		//	(-1, -1) (+1, -1)
		//
		// First of all, convert from geom space to framebuffer space. For
		// later convenience, we divide everything by 2 here: px2 is half of
		// the P.X co-ordinate (in framebuffer space).
		px2 := -0.5 + float32(topLeft.X/geom.Width)
		py2 := +0.5 - float32(topLeft.Y/geom.Height)
		qx2 := -0.5 + float32(topRight.X/geom.Width)
		qy2 := +0.5 - float32(topRight.Y/geom.Height)
		sx2 := -0.5 + float32(bottomLeft.X/geom.Width)
		sy2 := +0.5 - float32(bottomLeft.Y/geom.Height)
		// Next, solve for the affine transformation matrix
		//	    [ a00 a01 a02 ]
		//	a = [ a10 a11 a12 ]
		//	    [   0   0   1 ]
		// that maps A to P:
		//	a × [ -1 +1 1 ]' = [ 2*px2 2*py2 1 ]'
		// and likewise maps B to Q and D to S. Solving those three constraints
		// implies that C maps to R, since affine transformations keep parallel
		// lines parallel. This gives 6 equations in 6 unknowns:
		//	-a00 + a01 + a02 = 2*px2
		//	-a10 + a11 + a12 = 2*py2
		//	+a00 + a01 + a02 = 2*qx2
		//	+a10 + a11 + a12 = 2*qy2
		//	-a00 - a01 + a02 = 2*sx2
		//	-a10 - a11 + a12 = 2*sy2
		// which gives:
		//	a00 = (2*qx2 - 2*px2) / 2 = qx2 - px2
		// and similarly for the other elements of a.
		glimage.mvp.WriteAffine(&f32.Affine{{
			qx2 - px2,
			px2 - sx2,
			qx2 + sx2,
		}, {
			qy2 - py2,
			py2 - sy2,
			qy2 + sy2,
		}})
	}

	{
		// Mapping texture co-ordinates is similar, except that in texture
		// space, the ABCD rectangle is:
		//
		//	(0,0) (1,0)
		//	(0,1) (1,1)
		//
		// and the PQRS quad is always axis-aligned. First of all, convert
		// from pixel space to texture space.
		w := float32(img.texWidth)
		h := float32(img.texHeight)
		px := float32(srcBounds.Min.X-img.Rect.Min.X) / w
		py := float32(srcBounds.Min.Y-img.Rect.Min.Y) / h
		qx := float32(srcBounds.Max.X-img.Rect.Min.X) / w
		sy := float32(srcBounds.Max.Y-img.Rect.Min.Y) / h
		// Due to axis alignment, qy = py and sx = px.
		//
		// The simultaneous equations are:
		//	  0 +   0 + a02 = px
		//	  0 +   0 + a12 = py
		//	a00 +   0 + a02 = qx
		//	a10 +   0 + a12 = qy = py
		//	  0 + a01 + a02 = sx = px
		//	  0 + a11 + a12 = sy
		glimage.uvp.WriteAffine(&f32.Affine{{
			qx - px,
			0,
			px,
		}, {
			0,
			sy - py,
			py,
		}})
	}

	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, img.Texture)
	gl.Uniform1i(glimage.textureSample, 0)

	gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadXY)
	gl.EnableVertexAttribArray(glimage.pos)
	gl.VertexAttribPointer(glimage.pos, 2, gl.FLOAT, false, 0, 0)

	gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadUV)
	gl.EnableVertexAttribArray(glimage.inUV)
	gl.VertexAttribPointer(glimage.inUV, 2, gl.FLOAT, false, 0, 0)

	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)

	gl.DisableVertexAttribArray(glimage.pos)
	gl.DisableVertexAttribArray(glimage.inUV)
}
Exemplo n.º 17
0
// Upload copies the host image data to the GL device.
func (img *Image) Upload() {
	gl.BindTexture(gl.TEXTURE_2D, img.Texture)
	gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, img.texWidth, img.texHeight, gl.RGBA, gl.UNSIGNED_BYTE, img.Pix)
}
Exemplo n.º 18
0
// Upload copies the host image data to the GL device.
func (img *Image) Upload() {
	tex := texmap.get(*img.key)
	gl.BindTexture(gl.TEXTURE_2D, tex.gltex)
	gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, tex.width, tex.height, gl.RGBA, gl.UNSIGNED_BYTE, img.RGBA.Pix)
}