Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/go/src/golang.org/x/mobile/gl/glutil/glimage.go

Issue 1275153002: Remove third_party/golang.org/x/mobile as it is no longer used with Go 1.5. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Remove golang.org/x/mobile Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build linux darwin
6
7 package glutil
8
9 import (
10 "encoding/binary"
11 "image"
12 "sync"
13
14 "golang.org/x/mobile/f32"
15 "golang.org/x/mobile/geom"
16 "golang.org/x/mobile/gl"
17 )
18
19 var glimage struct {
20 sync.Once
21 quadXY gl.Buffer
22 quadUV gl.Buffer
23 program gl.Program
24 pos gl.Attrib
25 mvp gl.Uniform
26 uvp gl.Uniform
27 inUV gl.Attrib
28 textureSample gl.Uniform
29 }
30
31 func glInit() {
32 var err error
33 glimage.program, err = CreateProgram(vertexShader, fragmentShader)
34 if err != nil {
35 panic(err)
36 }
37
38 glimage.quadXY = gl.GenBuffer()
39 glimage.quadUV = gl.GenBuffer()
40
41 gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadXY)
42 gl.BufferData(gl.ARRAY_BUFFER, gl.STATIC_DRAW, quadXYCoords)
43 gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadUV)
44 gl.BufferData(gl.ARRAY_BUFFER, gl.STATIC_DRAW, quadUVCoords)
45
46 glimage.pos = gl.GetAttribLocation(glimage.program, "pos")
47 glimage.mvp = gl.GetUniformLocation(glimage.program, "mvp")
48 glimage.uvp = gl.GetUniformLocation(glimage.program, "uvp")
49 glimage.inUV = gl.GetAttribLocation(glimage.program, "inUV")
50 glimage.textureSample = gl.GetUniformLocation(glimage.program, "textureS ample")
51 }
52
53 // Image bridges between an *image.RGBA and an OpenGL texture.
54 //
55 // The contents of the embedded *image.RGBA can be uploaded as a
56 // texture and drawn as a 2D quad.
57 //
58 // The number of active Images must fit in the system's OpenGL texture
59 // limit. The typical use of an Image is as a texture atlas.
60 type Image struct {
61 *image.RGBA
62
63 Texture gl.Texture
64 texWidth int
65 texHeight int
66 }
67
68 // NewImage creates an Image of the given size.
69 //
70 // Both a host-memory *image.RGBA and a GL texture are created.
71 func NewImage(w, h int) *Image {
72 dx := roundToPower2(w)
73 dy := roundToPower2(h)
74
75 // TODO(crawshaw): Using VertexAttribPointer we can pass texture
76 // data with a stride, which would let us use the exact number of
77 // pixels on the host instead of the rounded up power 2 size.
78 m := image.NewRGBA(image.Rect(0, 0, dx, dy))
79
80 glimage.Do(glInit)
81
82 img := &Image{
83 RGBA: m.SubImage(image.Rect(0, 0, w, h)).(*image.RGBA),
84 Texture: gl.GenTexture(),
85 texWidth: dx,
86 texHeight: dy,
87 }
88 // TODO(crawshaw): We don't have the context on a finalizer. Find a way.
89 // runtime.SetFinalizer(img, func(img *Image) { gl.DeleteTexture(img.Tex ture) })
90 gl.BindTexture(gl.TEXTURE_2D, img.Texture)
91 gl.TexImage2D(gl.TEXTURE_2D, 0, dx, dy, gl.RGBA, gl.UNSIGNED_BYTE, nil)
92 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
93 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
94 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
95 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
96
97 return img
98 }
99
100 func roundToPower2(x int) int {
101 x2 := 1
102 for x2 < x {
103 x2 *= 2
104 }
105 return x2
106 }
107
108 // Upload copies the host image data to the GL device.
109 func (img *Image) Upload() {
110 gl.BindTexture(gl.TEXTURE_2D, img.Texture)
111 gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, img.texWidth, img.texHeight, gl .RGBA, gl.UNSIGNED_BYTE, img.Pix)
112 }
113
114 // Draw draws the srcBounds part of the image onto a parallelogram, defined by
115 // three of its corners, in the current GL framebuffer.
116 func (img *Image) Draw(topLeft, topRight, bottomLeft geom.Point, srcBounds image .Rectangle) {
117 // TODO(crawshaw): Adjust viewport for the top bar on android?
118 gl.UseProgram(glimage.program)
119
120 {
121 // We are drawing a parallelogram PQRS, defined by three of its
122 // corners, onto the entire GL framebuffer ABCD. The two quads m ay
123 // actually be equal, but in the general case, PQRS can be small er,
124 // and PQRS is not necessarily axis-aligned.
125 //
126 // A +---------------+ B
127 // | P +-----+ Q |
128 // | | | |
129 // | S +-----+ R |
130 // D +---------------+ C
131 //
132 // There are two co-ordinate spaces: geom space and framebuffer space.
133 // In geom space, the ABCD rectangle is:
134 //
135 // (0, 0) (geom.Width, 0)
136 // (0, geom.Height) (geom.Width, geom.Height)
137 //
138 // and the PQRS quad is:
139 //
140 // (topLeft.X, topLeft.Y) (topRight.X, topRight.Y)
141 // (bottomLeft.X, bottomLeft.Y) (implicit, implicit)
142 //
143 // In framebuffer space, the ABCD rectangle is:
144 //
145 // (-1, +1) (+1, +1)
146 // (-1, -1) (+1, -1)
147 //
148 // First of all, convert from geom space to framebuffer space. F or
149 // later convenience, we divide everything by 2 here: px2 is hal f of
150 // the P.X co-ordinate (in framebuffer space).
151 px2 := -0.5 + float32(topLeft.X/geom.Width)
152 py2 := +0.5 - float32(topLeft.Y/geom.Height)
153 qx2 := -0.5 + float32(topRight.X/geom.Width)
154 qy2 := +0.5 - float32(topRight.Y/geom.Height)
155 sx2 := -0.5 + float32(bottomLeft.X/geom.Width)
156 sy2 := +0.5 - float32(bottomLeft.Y/geom.Height)
157 // Next, solve for the affine transformation matrix
158 // [ a00 a01 a02 ]
159 // a = [ a10 a11 a12 ]
160 // [ 0 0 1 ]
161 // that maps A to P:
162 // a × [ -1 +1 1 ]' = [ 2*px2 2*py2 1 ]'
163 // and likewise maps B to Q and D to S. Solving those three cons traints
164 // implies that C maps to R, since affine transformations keep p arallel
165 // lines parallel. This gives 6 equations in 6 unknowns:
166 // -a00 + a01 + a02 = 2*px2
167 // -a10 + a11 + a12 = 2*py2
168 // +a00 + a01 + a02 = 2*qx2
169 // +a10 + a11 + a12 = 2*qy2
170 // -a00 - a01 + a02 = 2*sx2
171 // -a10 - a11 + a12 = 2*sy2
172 // which gives:
173 // a00 = (2*qx2 - 2*px2) / 2 = qx2 - px2
174 // and similarly for the other elements of a.
175 glimage.mvp.WriteAffine(&f32.Affine{{
176 qx2 - px2,
177 px2 - sx2,
178 qx2 + sx2,
179 }, {
180 qy2 - py2,
181 py2 - sy2,
182 qy2 + sy2,
183 }})
184 }
185
186 {
187 // Mapping texture co-ordinates is similar, except that in textu re
188 // space, the ABCD rectangle is:
189 //
190 // (0,0) (1,0)
191 // (0,1) (1,1)
192 //
193 // and the PQRS quad is always axis-aligned. First of all, conve rt
194 // from pixel space to texture space.
195 w := float32(img.texWidth)
196 h := float32(img.texHeight)
197 px := float32(srcBounds.Min.X-img.Rect.Min.X) / w
198 py := float32(srcBounds.Min.Y-img.Rect.Min.Y) / h
199 qx := float32(srcBounds.Max.X-img.Rect.Min.X) / w
200 sy := float32(srcBounds.Max.Y-img.Rect.Min.Y) / h
201 // Due to axis alignment, qy = py and sx = px.
202 //
203 // The simultaneous equations are:
204 // 0 + 0 + a02 = px
205 // 0 + 0 + a12 = py
206 // a00 + 0 + a02 = qx
207 // a10 + 0 + a12 = qy = py
208 // 0 + a01 + a02 = sx = px
209 // 0 + a11 + a12 = sy
210 glimage.uvp.WriteAffine(&f32.Affine{{
211 qx - px,
212 0,
213 px,
214 }, {
215 0,
216 sy - py,
217 py,
218 }})
219 }
220
221 gl.ActiveTexture(gl.TEXTURE0)
222 gl.BindTexture(gl.TEXTURE_2D, img.Texture)
223 gl.Uniform1i(glimage.textureSample, 0)
224
225 gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadXY)
226 gl.EnableVertexAttribArray(glimage.pos)
227 gl.VertexAttribPointer(glimage.pos, 2, gl.FLOAT, false, 0, 0)
228
229 gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadUV)
230 gl.EnableVertexAttribArray(glimage.inUV)
231 gl.VertexAttribPointer(glimage.inUV, 2, gl.FLOAT, false, 0, 0)
232
233 gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
234
235 gl.DisableVertexAttribArray(glimage.pos)
236 gl.DisableVertexAttribArray(glimage.inUV)
237 }
238
239 var quadXYCoords = f32.Bytes(binary.LittleEndian,
240 -1, +1, // top left
241 +1, +1, // top right
242 -1, -1, // bottom left
243 +1, -1, // bottom right
244 )
245
246 var quadUVCoords = f32.Bytes(binary.LittleEndian,
247 0, 0, // top left
248 1, 0, // top right
249 0, 1, // bottom left
250 1, 1, // bottom right
251 )
252
253 const vertexShader = `#version 100
254 uniform mat3 mvp;
255 uniform mat3 uvp;
256 attribute vec3 pos;
257 attribute vec2 inUV;
258 varying vec2 UV;
259 void main() {
260 vec3 p = pos;
261 p.z = 1.0;
262 gl_Position = vec4(mvp * p, 1);
263 UV = (uvp * vec3(inUV, 1)).xy;
264 }
265 `
266
267 const fragmentShader = `#version 100
268 precision mediump float;
269 varying vec2 UV;
270 uniform sampler2D textureSample;
271 void main(){
272 gl_FragColor = texture2D(textureSample, UV);
273 }
274 `
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698