Ogdc 2013 lets remake the wheel
-
Author
son-aris -
Category
Technology
-
view
279 -
download
0
Embed Size (px)
Transcript of Ogdc 2013 lets remake the wheel
- 1.Nguyn Trung Hng Firebat Game Studio - VNG
2. DONT 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 doesnt get a better result, it always helps you gain more exp. My exp