Ogdc 2013 lets remake the wheel
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Ogdc 2013 lets remake the wheel

on

  • 581 views

 

Statistics

Views

Total Views
581
Views on SlideShare
581
Embed Views
0

Actions

Likes
0
Downloads
6
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Vertex Shader - OpenGL ES graphics code for rendering the vertices of a shape.Fragment Shader - OpenGL ES code for rendering the face of a shape with colors or textures.Program - An OpenGL ES object that contains the shaders you want to use for drawing one or more shapes.
  • What’s ETC ?Why should we use ETC texture ?But ETC don’t support alpha channel !!!
  • Q&A
  • Load texturefor (inti = 0 ; i < n ; ++i) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, texture_ids[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, ...); }Use texturefor (i = 0 ; i < n; ++i) { ... glUniform1i(texture_location, i); ... glDrawElements(...); }
  • References:http://beesbuzz.biz/code/hsv_color_transforms.phphttp://www.rapidtables.com/convert/color/rgb-to-hsv.htmhttp://www.cs.rit.edu/~ncs/color/t_convert.html

Ogdc 2013 lets remake the wheel Presentation Transcript

  • 1. Nguyễn Trung Hưng Firebat Game Studio - VNG
  • 2. “DON’T RE-INVENT THE WHEEL”
  • 3. Our old “wheel”: 3D vertex shader uniform mat4 uVPMatrix; attribute vec4 aPos; void main() { gl_Position = uVPMatrix * aPos; }
  • 4. The old “wheel” was designed for
  • 5. But we only need
  • 6. Remake the old “wheel” for 2D attribute vec2 aPos; void main() { gl_Position = vec4( aPos.x/HALF_WIDTH - 1.0, 1.0 - aPos.y/HALF_HEIGHT, 0.0, 1.0); }
  • 7. • Multiply ops: 16 • Add ops: 12 • Total: 28 • Multiply ops: 2 • Add ops: 2 • Total: 4 old “wheel” 28 VS 4 new “wheel”
  • 8. ETC texture • Ericsson Texture Compression (ETC) • 6x compression 0f 24-bit RGB data • No support images with Alpha component Source: http://en.wikipedia.org/wiki/Ericsson_Texture_Compression
  • 9. Old “wheel”: std fragment shader uniform sampler2D uTexture; varying mediump vec2 vTexCoord; void main() { gl_FragColor = texture2D(uTexture, vTexCoord); }
  • 10. We need a “wheel” ETC texture + Alpha mask texture = ETC with alpha component
  • 11. Remake the “wheel” for ETC uniform sampler2D uTexture; uniform sampler2D uAlpha; varying mediump vec2 vTexCoord; void main() { vec4 color = texture2D(uTexture, vTexCoord); vec4 alpha = texture2D(uAlpha, vTexCoord); gl_FragColor = vec4(color.rgb, alpha.r); }
  • 12. • Texture size: 100M • ETC size: 16.6M • Alpha mask size: 25M • Total: 41.6M old “wheel” 100 VS 42 new “wheel”
  • 13. How to bind 2 textures and pass them to fragment shader ?
  • 14. Old “wheel” was designed for
  • 15. But we really need
  • 16. uniform sampler2D uTexture; uniform mat4 uColorTransformMatrix; varying mediump vec2 vTexCoord; void main() { Vector4 color = texture2D(uTexture, vTexCoord); gl_FragColor = uColorTransformMatrix * color; } Remake the old “wheel”
  • 17. • Textures add: 3 • Textures add: 0 old “wheel” 3 VS 0 new “wheel”
  • 18. How to make the color transform matrix?
  • 19. void CMath::MATRIX_3x3_MULTIPLY(float* A, float* B, float* result) { result[0] = A[0]*B[0] +A[3]*B[1] + A[6]*B[2]; result[1] = A[1]*B[0] + A[4]*B[1] + A[7]*B[2]; result[2] = A[2]*B[0]+ A[5]*B[1] + A[8]*B[2]; result[3] = A[0]*B[3]+ A[3]*B[4]+ A[6]*B[5]; result[4] = A[1]*B[3] + A[4]*B[4]+ A[7]*B[5]; result[5] = A[2]*B[3]+ A[5]*B[4]+ A[8]*B[5]; result[6] = A[0]*B[6]+ A[3]*B[7]+ A[6]*B[8]; result[7] = A[1]*B[6] + A[4]*B[7]+ A[7]*B[8]; result[8] = A[2]*B[6]+ A[5]*B[7]+ A[8]*B[8]; } Our old “wheel”
  • 20. m11 m12 m13 m21 m22 m23 m31 m32 m33 Old “wheel” was designed for
  • 21. We only need m11 m12 m13 m21 m22 m23 0 0 1
  • 22. Remake the old “wheel” void CMath::MATRIX_3x3_MULTIPLY(float* A, float* B, float* result) { result[0] =A[0]*B[0] + A[3]*B[1] + A[6]*0; result[1] = A[1]*B[0] + A[4]*B[1] + A[7]*0; result[2] = 0*B[0] + 0*B[1] + 1*0; result[3] = A[0]*B[3] + A[3]*B[4] + A[6]*0; result[4] =A[1]*B[3] + A[4]*B[4] + A[7]*0; result[5] = 0*B[3] + 0*B[4] + 1*0; result[6] =A[0]*B[6] + A[3]*B[7] + A[6]*1; result[7] = A[1]*B[6] + A[4]*B[7] + A[7]*1; result[8] =0*B[6] + 0*B[7] + 1*1; }
  • 23. Remake the old “wheel” void CMath::MATRIX_3x3_MULTIPLY(float* A, float* B, float* result) { result[0] =A[0]*B[0] + A[3]*B[1]; result[1] = A[1]*B[0] + A[4]*B[1]; result[3] = A[0]*B[3] + A[3]*B[4]; result[4] =A[1]*B[3] + A[4]*B[4]; result[6] =A[0]*B[6] + A[3]*B[7] + A[6]; result[7] = A[1]*B[6] + A[4]*B[7] + A[7]; }
  • 24. • Multiply ops: 27 • Add ops: 18 • Total: 45 • Multiply ops: 12 • Add ops: 8 • Total: 20 old “wheel” 45 VS 20 new “wheel”
  • 25. 1 0 tx 0 1 ty 0 0 1 If the new “wheel” only run on
  • 26. Remake the old “wheel” void CMath::MATRIX_3x3_MULTIPLY(float* A, float* B, float* result) { result[0] =1*B[0] + 0*B[1]; result[1] = 0*B[0] + 1*B[1]; result[3] = 1*B[3] + 0*B[4]; result[4] =0*B[3] + 1*B[4]; result[6] =1*B[6] + 0*B[7] + A[6]; result[7] = 0*B[6] + 1*B[7] + A[7]; }
  • 27. Remake the old “wheel” void CMath::MATRIX_3x3_MULTIPLY(float* A, float* B, float* result) { result[0] =B[0]; result[1] = B[1]; result[3] = B[3]; result[4] =B[4]; result[6] =B[6] + A[6]; result[7] = B[7] + A[7]; }
  • 28. Remake the old “wheel” void CMath::MATRIX_3x3_TRANSLATE(float* M, float tx, float ty) { M[6] += tx; M[7] += ty; }
  • 29. • Multiply ops: 27 • Add ops: 18 • Total: 45 • Multiply ops: 0 • Add ops: 2 • Total: 2 old “wheel” 45 VS 2 new “wheel”
  • 30. sx 0 0 0 sy 0 0 0 1 If the new “wheel” run on
  • 31. Remake the old “wheel” void CMath::MATRIX_3x3_SCALE(float* M, float sx, float sy) { M[0] *= sx; M[1] *= sy; M[3] *= sx; M[4] *= sy; M[6] *= sx; M[7] *= sy; }
  • 32. • Multiply ops: 27 • Add ops: 18 • Total: 45 • Multiply ops: 6 • Add ops: 0 • Total: 6 old “wheel” 45 VS 6 new “wheel”
  • 33. public float[] MakeImageVertexData(float x, float y, short w, short h) { xy[0] = x; xy[1] = y; xy[2] = x; xy[3] = (h + y); xy[4] = (w + x); xy[5] = (h + y); xy[6] = (w + x); xy[7] = y; } Our old “wheel”
  • 34. public void RenderImage(…) { glPushMatrix(); glScalef(sx, sy, sz); glTranslatef(tx, ty, tz); glRotatef(angle, vx, vy, vz); … glVertexPointer(2, GL_FLOAT, 0, vertex_data); glTexCoordPointer(2, GL_FLOAT, 0, tex_coord); glDrawElements(GL_TRIANGLES, …); glPopMatrix(); } Our old “wheel”
  • 35. MakeImageVertexData(float x, float y, short w, short h, float m11, float m12, float m21, float m22) { xy[0] = x; xy[1] = y; xy[2] = h*m12 +x; xy[3] = h*m22 + y; xy[4] = w*m11 + h*m12 + x; xy[5] = w*m21 + h*m22 + y; xy[6] = w*m11 + x; xy[7] = w*m21 + y; } Remake the old “wheel”
  • 36. public void RenderImage(…) { … glVertexPointer(2, GL_FLOAT, 0, vertex_data); glTexCoordPointer(2, GL_FLOAT, 0, tex_coord); glDrawElements(GL_TRIANGLES, …); … } Remake the old “wheel”
  • 37. old “wheel” N VS 0 new “wheel”
  • 38. Our old “wheel” • Encode binary content to string (Base64) • Use HTTP GET method • Decode url string to binary
  • 39. Our new “wheel” • No encode • Use HTTP POST method - With “Content-Type: application/octet-stream” - Maybe with "Content-Encoding: gzip“ - And "Content-MD5: …" • No decode
  • 40. HttpURLConnection http_conn = (HttpURLConnection)url.openConnection(); http_conn.setRequestMethod(”POST”); http_conn.setDoOutput(true); byte[] final_content = GZIP(_binary_data); http_conn.setRequestProperty("Content-Type", "application/octet-stream"); http_conn.setRequestProperty("Content-Encoding", "gzip"); http_conn.setRequestProperty("Content-MD5", MD5(final_content)); http_conn.setFixedLengthStreamingMode(final_content.length); //send the POST content OutputStream out = http_conn.getOutputStream(); out.write(final_content); out.close();
  • 41. old “wheel” 100KB new “wheel” 48KB
  • 42. Our old “wheel” function void UpdateMoney(int delta) { int money = ReadDB(“userid_money”); WriteDB(“userid_money”, money + delta); }
  • 43. Old “wheel” was designed for single thread But we need multi-thread !!!
  • 44. function void UpdateMoney(int delta) { 1. int money = ReadDB(“userid_money”); 2. WriteDB(“userid_money”, money + delta); } • A:1 => A:2 => B:1 => B:2 • A:1 => B:1 => A:2 => B:2 • A:1 => B:1 => B:2 => A:2 • Thread A: -100$ • Thread B: +100$
  • 45. class CompareAndSet { Object value; long token; } new “wheel”
  • 46. function boolean UpdateMoney(int delta) { 1. CAS casMoney = CasReadDB(“userid_money”); 2. return CasWriteDB( “userid_money”, casMoney.value + delta, casMoney.token); } • A:1(t1) => A:2(t2 = t1++) => B:1(t2) => B:2(t3 = t2++) • A:1(t1) => B:1(t1) => A:2(t2 = t1++) => B:2(t1 != t2) new “wheel”
  • 47. old wheel “earn” ±100$ new wheel “earn” 0$
  • 48. The “wheel” which you found on internet, may be not designed for your “vehicle”. My exp
  • 49. Understand your need if you want to remake your “wheel”. My exp
  • 50. Remaking usually helps you get a better result. My exp
  • 51. Even when it doesn’t get a better result, it always helps you gain more exp. My exp