рдПрдВрдбреНрд░реЙрдЗрдб рдкрд░ рдЧрд╛рдКрд╕реА рдкрд░ рдЧреНрд▓реЛ рдмреНрд▓рд░ рдЗрдлреЗрдХреНрдЯ

рдкрд░рд┐рдЪрдп


рдкрд░рд┐рдгрд╛рдо рдпрд╣ рдорд╣рд╛рдХрд╛рд╡реНрдп рдХрд╛рд░реНрдп рдХрдИ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдВрдбреНрд░реЙрдЗрдб рдПрдореБрд▓реЗрдЯрд░ рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рддреНрд╡рд░рдг рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ , рдЬреЛ рди рдХреЗрд╡рд▓ рдкреВрд░реНрдг рдЧрддрд┐ рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдУрдкрдирдЬреАрдПрд▓ рдИрдПрд╕ 2.0 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рднреА рдХрд░рддрд╛ рд╣реИред

рджреВрд╕рд░реЗ, рдкреНрдпрд╛рд░реА рдкрддреНрдиреА рдХрд╛ рдЬрдиреНрдорджрд┐рди рдЖ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдирдП рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рдпрд╛ рдЯреИрдмрд▓реЗрдЯ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкреВрд░рдХ рдЙрд╕рдХреЗ рд▓рд┐рдП рд╣рд╛рде рд╕реЗ рд▓рд┐рдЦрд╛ рдкреЛрд╕реНрдЯрдХрд╛рд░реНрдб рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реЛрдЧрд╛ред

рдпрд╣ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ - рдХрд┐рдпрд╛ рдЧрдпрд╛: рд╣рдо рдПрдВрдбреНрд░реЙрдЗрдб рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдкрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рд░реВрдкрд░реЗрдЦрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рд╢реЗрд▓реНрдл рд╕реЗ рдкреБрд░рд╛рдиреА рдбрд╛рдпрд░реЗрдХреНрдЯ 3 рдбреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВред рд╢реЗрд▓реНрдл рд╕реЗ 3 рдбреА рдлрд╝рд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб, рд░реЗрдВрдбрд░-рдЯреВ-рдЯреЗрдХреНрд╕рдЪрд░ рдФрд░ рдкреИрдХ рдСрдл рд╢реЗрдбреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЬрд╛рд╡рд╛ рдФрд░ рдУрдкрдирдЬреАрдПрд▓ рдИрдПрд╕ 2.0 рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рд╡рд╣ рдорд┐рд▓рддрд╛ рд╣реИ рдЬреЛ рддрд╕реНрд╡реАрд░ рдореЗрдВ рд╣реИред ред рдмрдзрд╛рдИ рдФрд░ рдкрд╕рдВрдж рдХрд╛ рдкрд╛рда рдмрд╛рдж рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред

рдПрдВрдбреНрд░реЙрдЗрдб рдкрд░ рдУрдкрдирдЬреАрдПрд▓ рдИрдПрд╕ 2.0 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдмрд╣реБрдд рд╣реА рдЦрдВрдбрд┐рдд рд╣реЛ рдЧрдИ, рдЬреНрдЮрд╛рди рдХреЛ рдереЛрдбрд╝рд╛-рдереЛрдбрд╝рд╛ рдХрд░рдХреЗ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ... рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдкреЛрд╕реНрдЯ рдЙрди рд▓реЛрдЧреЛрдВ рдХреА рдорджрдж рдХрд░реЗрдЧреА рдЬреЛ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореЗрд░реЗ рдЬреИрд╕реА рд╣реА рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░реЗрдВрдЧреЗред

рдФрд░ рдЕрдм рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗред

рдЯреНрд░реЗрдирд┐рдВрдЧ


рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдПрдореБрд▓реЗрдЯрд░ рдореЗрдВ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рддреНрд╡рд░рдг рд╕рдХреНрд╖рдо рд╣реИред рдпрд╣ рдпрд╛ рддреЛ AVD рдкреНрд░рдмрдВрдзрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рджреЗрдЦреЗрдВ; "рд╣рд╛рдВ" рдХрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рдирд╛ рди рднреВрд▓реЗрдВ), рдпрд╛ "hw.gpu.enabled = рд╣рд╛рдВ рдлрд╛рдЗрд▓ рдореЗрдВ рд▓рд╛рдЗрди рдЬреЛрдбрд╝рдХрд░ .android / avd / <your emulator-name> .avd / config.ini"ред "ред рдпрд╣рд╛рдВ рдПрдХ рд╕реВрдХреНрд╖реНрдорддрд╛ рд╣реИ: рд╕реНрдиреИрдкрд╢реЙрдЯ рдХреЗ рд╕рд╛рде рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рддреНрд╡рд░рдг рдЕрд╕рдВрдЧрдд рд╣реИред рддрджрдиреБрд╕рд╛рд░, рд╣рдо рдЗрд╕ рдбреЙрд╡ рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ (рдпрд╛ .ini рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ "рд╕реНрдиреИрдкрд╢реЙрдЯред рдкреНрд░рд╕реНрддреБрддреАрдХрд░рдг = рдЧрд▓рдд")ред



рдЗрд╕рдХреЗ рдмрд╛рдж, рдКрдкрд░ рджрд┐рдП рдЧрдП рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ рдЬреЛ рдЖрдкрдХреЛ рдЬрд╝рд░реВрд░рдд рд╣реИ рд╕рдм рдХреБрдЫ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд░реЗрдВрдбрд░рд░ рд╡рд░реНрдЧ рдХреЗ рд╡рдВрд╢рдЬред

рдЖрджрд░реНрд╢


рдпрд╣рд╛рдВ "рдореЙрдбрд▓" рд╢рдмреНрдж рд╕реЗ рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЧреБрд▓рд╛рдм рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЖрдк рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ рдпрд╛ рдкреВрд░реЗ рджреГрд╢реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред

рдпрд╣ рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЖрдЧреЗ рдХрд╛ рд╕рднреА рдХреЛрдб рд░реЗрдВрдбрд░рд░ рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рдЙрд╕реА рдХрдХреНрд╖рд╛ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред

рдореЙрдбрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ

рдореИрдВ рдпрд╣рд╛рдВ .3ds рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдбрд╛рдЙрдирд▓реЛрдб рдХреЛрдб рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛: рд▓рдВрдмреЗ рд╕рдордп рддрдХ, рдФрд░ рдкреЛрд╕реНрдЯ рдЙрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ (рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдкреЛрд╕реНрдЯ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ), рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рдореЙрдбрд▓ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЛрдб рджреВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд░реИрдХ рдПрдХрддреНрд░ рдХрд┐рдП рдереЗ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ, рджреВрд╕рд░реА рдмрд╛рдд, рдЗрд╕рдореЗрдВ рд▓рдЧрднрдЧ рдкреВрд░реА рддрд░рд╣ рд╕реЗ gl * рдХреЙрд▓реНрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдФрд░ рддреАрд╕рд░реЗ, рдиреАрдЪреЗ рдХреБрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдХреЗрд╡рд▓ рдкреНрд░рднрд╛рд╡ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рддреЛ рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рддреЛ, рдЕрдВрдд рдореЗрдВ, рдпреЗ рд╕рднреА рдореЙрдбрд▓ рдЗрди рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ рдлрд┐рдЯ рд╣реЛрддреЗ рд╣реИрдВ:

class Light3D { public float[] pos; public float[] color; } class Material3D { public float[] ambient; public float[] diffuse; } class FaceMat { public Material3D material; public int faces; public short[] indexBuffer; public int bufOffset; } class Object3D { public ArrayList<FaceMat> faceMats; public int vertCount; public int indCount; public int glVertices; public int glIndices; public float[] vertexBuffer; } public class Scene3D { public ArrayList<Material3D> materials; public ArrayList<Object3D> objects; public ArrayList<Light3D> lights; public float[] ambient; } 


рдпрд╣рд╛рдВ, рдЗрд╕ рддрд░рд╣ рдХреА рд╕реВрдХреНрд╖реНрдорддрд╛ рдФрд░ рджрд┐рд╢рд╛рддреНрдордХ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрдд рдХреЗ рд░реВрдк рдореЗрдВ рд╕реВрдХреНрд╖реНрдорддрд╛ рдХреЛ рдЬрд╛рдирдмреВрдЭрдХрд░ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рджреГрд╢реНрдп рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рднрд╛рд░реА рд╣реЛрдЧрд╛ред рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдХреЛрдиреЗ рдХреЗ рд╕рд░рдгреА рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдХреЗ 6 * (рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛) рд╣реЛрддреА рд╣реИ: рдкрдВрдХреНрддрд┐ рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдХреЛрдиреЗ рдФрд░ рдорд╛рдирджрдВрдбреЛрдВ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХред

рдлреНрд▓реЛрдЯ / рд▓рдШреБ рд╕рд░рдгрд┐рдпреЛрдВ рд╕реЗ рдЖрд░реЗрдЦрдг рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдмрдлрд╝рд░реНрд╕ рд╕реЗ рдпрд╣ рдХрд╛рдлреА рд╕рд╣рдиреАрдп рдерд╛ (рдбреНрд░рд╛рдЗрд╡рд░ рдФрд░ рд╡реАрдбрд┐рдпреЛ рдХреЛрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╣ рдбреЗрдЯрд╛ рддреБрд░рдВрдд рд╡реАрдбрд┐рдпреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ)ред рдПрдХ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░реЗрдВ, рдЕрд▓рдЧ рд╕реЗ рд╢реАрд░реНрд╖, рдЕрд▓рдЧ рд╕реЗ рд╕реВрдЪрдХрд╛рдВрдХред рдмрдлрд░ рдХреЛ рднрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, 0 рдХреЛ рд╕рдХреНрд░рд┐рдп рдмрдлрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордд рднреВрд▓рдирд╛ред

  int[] genbuf = new int[1]; private int createBuffer(float[] buffer) { FloatBuffer floatBuf = ByteBuffer.allocateDirect(buffer.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); floatBuf.put(buffer); floatBuf.position(0); GLES20.glGenBuffers(1, genbuf, 0); int glBuf = genbuf[0]; GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, glBuf); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffer.length * 4, floatBuf, GLES20.GL_STATIC_DRAW); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); return glBuf; } ... int i, num = scene.objects.size(); for (i = 0; i < num; i++) { Object3D obj = scene.objects.get(i); obj.glVertices = createBuffer(obj.vertexBuffer); GLES20.glGenBuffers(1, genbuf, 0); obj.glIndices = genbuf[0]; GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, obj.glIndices); GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, obj.indCount * 2, null, GLES20.GL_STATIC_DRAW); int k, mats = obj.faceMats.size(); for (k = 0; k < mats; k++) { FaceMat mat = obj.faceMats.get(k); ShortBuffer indBuf = ByteBuffer.allocateDirect(mat.indexBuffer.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer(); indBuf.put(mat.indexBuffer); indBuf.position(0); GLES20.glBufferSubData(GLES20.GL_ELEMENT_ARRAY_BUFFER, mat.bufOffset * 2, mat.indexBuffer.length * 2, indBuf); } GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); } 


рд╡рд░реНрдЯреЗрдХреНрд╕ рдмрдлрд░ рдкреАрдврд╝реА рдПрдХ рдХреНрд╡рд╛рдб рдмрдирд╛рддреЗ рд╕рдордп рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рд╣реИред

рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рд╢реЗрдбреНрд╕

рджреГрд╢реНрдп рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрдб рдмрдирд╛рдПрдБ:

  private final String vertexShaderCode = "precision mediump float;\n" + "uniform mat4 uMVPMatrix;\n" + "uniform mat4 uMVMatrix;\n" + "uniform mat3 uNMatrix;\n" + "uniform vec4 uAmbient;\n" + "uniform vec4 uDiffuse;\n" + "const int MaxLights = 8;\n" + "struct LightSourceParameters {\n" + " bool enabled;\n" + " vec4 color;\n" + " vec3 position;\n" + "};\n" + "uniform LightSourceParameters uLight[MaxLights];\n" + "attribute vec4 vPosition;\n" + "attribute vec3 vNormal;\n" + "varying vec4 FrontColor;\n" + "vec4 light_point_view_local(vec3 epos, vec3 normal, int idx);\n" + "void main() {\n" + " gl_Position = uMVPMatrix * vPosition;\n" + " vec4 epos = uMVMatrix * vPosition;\n" + " vec3 normal =uNMatrix * vNormal;\n" + " vec4 vcolor = uAmbient;\n" + " int i;\n" + " for (i = 0; i < MaxLights; i++) {\n" + " if (uLight[i].enabled) {\n" + " vcolor += light_point_view_local(epos.xyz, normal, i);\n" + " }\n" + " }\n" + " FrontColor = clamp(vcolor, 0.0, 1.0);\n" + "}\n" + "vec4 light_point_view_local(vec3 epos, vec3 normal, int idx) {\n" + " vec3 vert2light = uLight[idx].position - epos;\n" + " vec3 ldir = normalize(vert2light);\n" + " float NdotL = dot(normal, ldir);\n" + " vec4 outCol = vec4(0.0, 0.0, 0.0, 1.0);\n" + " if (NdotL > 0.0) {\n" + " outCol = uLight[idx].color * uDiffuse * NdotL;\n" + " }\n" + " return outCol;\n" + "}\n"; private final String fragmentShaderCode = "precision mediump float;\n" + "varying vec4 FrontColor;\n" + "void main() {\n" + " gl_FragColor = FrontColor;\n" + "}\n"; private int mProgram; private int maPosition; private int maNormal; private int muMVPMatrix; private int muMVMatrix; private int muNMatrix; private int muAmbient; private int muDiffuse; private int[] muLightOn = new int[8]; private int[] muLightPos = new int[8]; private int[] muLightCol = new int[8]; 


рд╣рдо рдЙрдиреНрд╣реЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╕реНрдерд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

  private int loadShader(int type, String shaderCode) { int shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, shaderCode); GLES20.glCompileShader(shader); Log.i("Shader", GLES20.glGetShaderInfoLog(shader)); return shader; } private int Compile(String vs, String fs) { int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vs); int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fs); int prog = GLES20.glCreateProgram(); // create empty OpenGL Program GLES20.glAttachShader(prog, vertexShader); // add the vertex shader to program GLES20.glAttachShader(prog, fragmentShader); // add the fragment shader to program GLES20.glLinkProgram(prog); // creates OpenGL program executables return prog; } ... mProgram = Compile(vertexShaderCode, fragmentShaderCode); // get handle to the vertex shader's vPosition member maPosition = GLES20.glGetAttribLocation(mProgram, "vPosition"); maNormal = GLES20.glGetAttribLocation(mProgram, "vNormal"); muMVPMatrix = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); muMVMatrix = GLES20.glGetUniformLocation(mProgram, "uMVMatrix"); muNMatrix = GLES20.glGetUniformLocation(mProgram, "uNMatrix"); muAmbient = GLES20.glGetUniformLocation(mProgram, "uAmbient"); muDiffuse = GLES20.glGetUniformLocation(mProgram, "uDiffuse"); int i; for (i = 0; i < 8; i++) { muLightOn[i] = GLES20.glGetUniformLocation(mProgram, String.format("uLight[%d].enabled", i)); muLightPos[i] = GLES20.glGetUniformLocation(mProgram, String.format("uLight[%d].position", i)); muLightCol[i] = GLES20.glGetUniformLocation(mProgram, String.format("uLight[%d].color", i)); } 


рдореИрдВ рдЗрди рд╢реЗрдбреНрд╕ рдХреЗ рдХрд╛рдо рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛: рдЦрдВрдб рдПрдХ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддреБрдЪреНрдЫ рд╣реИ, рдФрд░ рд╢реАрд░реНрд╖ рдПрдХ рд╕рд░реНрд╡рд╡реНрдпрд╛рдкреА рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдп рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред

рдореЙрдбрд▓ рд░реЗрдВрдбрд░рд┐рдВрдЧ

рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкрд░рд┐рд╡рд░реНрддрди рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдореЙрдбрд▓, рд╡реНрдпреВ рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рддреИрдпрд╛рд░ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореЗрд░рд╛ рд░реЛрд╕реЗрдЯ рдЖрд╕рд╛рдиреА рд╕реЗ рдШреВрдорддрд╛ рд╣реИ)ред рдореЙрдбрд▓-рд╡реНрдпреВ рдХреЗ рдХрд╛рдо рд╕реЗ рд╣рдо рдХреЗрд╡рд▓ рд░реЛрдЯреЗрд╢рди рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдорд╛рдирджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдкреНрд░рддрд┐рдкрд╛рджрди рд╕рд░рд▓ рдФрд░ рд╕реБрдЦрдж рд╣реИ: рд╣рдо рдкрд╣рд▓реЗ рдмрдирд╛рдП рдЧрдП рдмрдлрд╝рд░реНрд╕ рд▓реЗрддреЗ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВ, рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЖрдВрдЦ-рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд╡реНрдпреВ рдореИрдЯреНрд░рд┐рдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

  private void DrawScene() { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glUseProgram(mProgram); GLES20.glEnable(GLES20.GL_CULL_FACE); GLES20.glEnable(GLES20.GL_DEPTH_TEST); Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix, 0); // Apply a ModelView Projection transformation GLES20.glUniformMatrix4fv(muMVPMatrix, 1, false, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muMVMatrix, 1, false, mMVMatrix, 0); int i, j, num; for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) mNMatrix[i*3 + j] = mMVMatrix[i*4 + j]; GLES20.glUniformMatrix3fv(muNMatrix, 1, false, mNMatrix, 0); num = min(scene.lights.size(), 8); float[] eyepos = new float[3]; for (i = 0; i < num; i++) { Light3D light = scene.lights.get(i); for (j = 0; j < 3; j++) { eyepos[j] = mVMatrix[4*3 + j]; for (k = 0; k < 3; k++) eyepos[j] += light.pos[k] * mVMatrix[k*4 + j]; } GLES20.glUniform1i(muLightOn[i], 1); GLES20.glUniform3fv(muLightPos[i], 1, eyepos, 0); GLES20.glUniform4fv(muLightCol[i], 1, light.color, 0); } for (i = num; i < 8; i++) GLES20.glUniform1i(muLightOn[i], 0); // Prepare the triangle data GLES20.glEnableVertexAttribArray(maPosition); GLES20.glEnableVertexAttribArray(maNormal); num = scene.objects.size(); for (i = 0; i < num; i++) { Object3D obj = scene.objects.get(i); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, obj.glVertices); GLES20.glVertexAttribPointer(maPosition, 3, GLES20.GL_FLOAT, false, 24, 0); GLES20.glVertexAttribPointer(maNormal, 3, GLES20.GL_FLOAT, false, 24, 12); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, obj.glIndices); int mats = obj.faceMats.size(); for (j = 0; j < mats; j++) { FaceMat mat = obj.faceMats.get(j); for (int k = 0; k < 3; k++) mAmbient[k] = mat.material.ambient[k] * scene.ambient[k]; GLES20.glUniform4fv(muAmbient, 1, mAmbient, 0); GLES20.glUniform4fv(muDiffuse, 1, mat.material.diffuse, 0); GLES20.glDrawElements(GLES20.GL_TRIANGLES, mat.indexBuffer.length, GLES20.GL_UNSIGNED_SHORT, mat.bufOffset * 2); } GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); } GLES20.glDisableVertexAttribArray(maPosition); GLES20.glDisableVertexAttribArray(maNormal); } 


рдХреЛрдИ рдкреНрд░рднрд╛рд╡ рджреГрд╢реНрдп рдирд╣реАрдВ
рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдмрдирд╛рд╡рдЯ рдХреЗ рдмрд┐рдирд╛ рджреГрд╢реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рд╕рд╛рдордЧреНрд░реА рдФрд░ рдЖрда рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рд╛рдеред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд╕ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЗрддрдиреЗ рдЫреЛрдЯреЗ рдкрд░реНрджреЗ рдкрд░, рдмрдирд╛рд╡рдЯ рдХреА рдЕрдм рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрд╣ рдЗрддрдирд╛ рдЕрдЪреНрдЫрд╛ рджрд┐рдЦрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВ рдЕрднреА рднреА рдПрдХ рдЪрдордХ рдЪрд╛рд╣рддреЗ рд╣реИрдВ!

рдЕрдм рдордЬрд╝реЗрджрд╛рд░ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП: рдЗрд╕ рджреГрд╢реНрдп рдХреЛ рдПрдХ рдмрдирд╛рд╡рдЯ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВред

рдЯреНрд░реИрдХреНрдЯрд░


рд╣рдореЗрдВ рдкрд╣рд▓реЗ рджреГрд╢реНрдп рдХреЗ рдЕрдВрддрд┐рдо "рдЪрдордХ" рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЧреЙрд╕рд┐рдпрди рдХрд▓рдВрдХ рдХреЛ рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рджреВрд╕рд░реЗ, рдПрдХ рдХреНрд╡рд╛рдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдХреНрд╡рд╛рдб рдХреНрд░рд┐рдПрд╢рди

рд╣рдо рдХреЛрдиреЗ рдФрд░ рдмрдирд╛рд╡рдЯ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рдмрдлрд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рд╢реЗрдбрд░ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ - рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рд╕рдорд╛рди рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╢реЗрдбрд░реНрд╕ рдФрд░ рднреА рд╕рд░рд▓ рд╣реЛ рдЧрдП рд╣реИрдВ:

  private final String quadVS = "precision mediump float;\n" + "attribute vec4 vPosition;\n" + "attribute vec4 vTexCoord0;\n" + "varying vec4 TexCoord0;\n" + "void main() {\n" + " gl_Position = vPosition;\n" + " TexCoord0 = vTexCoord0;\n" + "}\n"; private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "varying vec4 TexCoord0;\n" + "void main() {\n" + " gl_FragColor = texture2D(uTexture0, TexCoord0.xy);\n" + "}\n"; private int mQProgram; private int maQPosition; private int maQTexCoord; private int muQTexture; private int glQuadVB; ... final float quadv[] = { -1, 1, 0, 0, 1, -1, -1, 0, 0, 0, 1, 1, 0, 1, 1, 1, -1, 0, 1, 0 }; glQuadVB = createBuffer(quadv); mQProgram = Compile(quadVS, quadFS); maQPosition = GLES20.glGetAttribLocation(mQProgram, "vPosition"); maQTexCoord = GLES20.glGetAttribLocation(mQProgram, "vTexCoord0"); muQTexture = GLES20.glGetUniformLocation(mQProgram, "uTexture0"); 


рдмрдирд╛рд╡рдЯ рдмрдлрд╝рд░реНрд╕ рддреИрдпрд╛рд░ рдХрд░рдирд╛

рд╣рдо рдПрдХ рдмрд╛рд░ рдореЗрдВ рджреЛ 256x256 рдмрдлрд╝рд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рдпрд╣ рдСрдирд░рдлреЗрд╕рдлреИрдВрдЧреНрдб рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

  private int filterBuf1; private int filterBuf2; private int renderTex1; private int renderTex2; public int scrWidth; public int scrHeight; public int texWidth; public int texHeight; ... private int makeRenderTarget(int width, int height, int[] handles) { GLES20.glGenTextures(1, genbuf, 0); int renderTex = genbuf[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); IntBuffer texBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder()).asIntBuffer(); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, texBuffer); GLES20.glGenRenderbuffers(1, genbuf, 0); int depthBuf = genbuf[0]; GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthBuf); GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, width, height); GLES20.glGenFramebuffers(1, genbuf, 0); int frameBuf = genbuf[0]; GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuf); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex, 0); GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthBuf); int res = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); handles[0] = frameBuf; handles[1] = renderTex; return res; } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { ratio = (float) width / height; int[] handles = new int[2]; scrWidth = width; scrHeight = height; texWidth = 256; texHeight = 256; makeRenderTarget(texWidth, texHeight, handles); filterBuf1 = handles[0]; renderTex1 = handles[1]; makeRenderTarget(texWidth, texHeight, handles); filterBuf2 = handles[0]; renderTex2 = handles[1]; } 


рдкреНрд░рддреНрдпреЗрдХ рдмрдирд╛рд╡рдЯ рдмрдлрд░ рдХреЗ рд╕рд╛рде рджреЛ рдЪрд░ рдЬреБрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВ: рдмрдирд╛рд╡рдЯ рд╣реА рдФрд░ рдлреНрд░реЗрдо рдмрдлрд░ (рдореИрдВ рдЯреЗрдУрдЯреЛрд▓реЙрдЬреА рдХреЗ рд▓рд┐рдП рдорд╛рдлреА рдЪрд╛рд╣рддрд╛ рд╣реВрдВ)ред

/ рд╕реЗ рдмрдирд╛рд╡рдЯ рддрдХ рдХреНрд╡реЗрдВрдбрд░ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди

рдмрд╕ рдХреБрдЫ рд╣реА рдлрд╝рдВрдХреНрд╢рди: рдПрдХ рд╡рд░реНрддрдорд╛рди рд╕реНрд░реЛрдд рдФрд░ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХрд╛ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ (0 рд╣рдорд╛рд░реА рд╕реНрдХреНрд░реАрди рд╣реИ, рдмрд╛рдХреА рдлреНрд░реЗрдо рдмрдлрд╝рд░реНрд╕ рдкрд╣рд▓реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ), рджреВрд╕рд░рд╛ рдПрдХ рдХреНрд╡рд╛рдб рдбреНрд░реЙ рдХрд░рддрд╛ рд╣реИред

  private void setRenderTexture(int frameBuf, int texture) { if (frameBuf == 0) GLES20.glViewport(0, 0, scrWidth, scrHeight); else GLES20.glViewport(0, 0, texWidth, texHeight); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuf); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); } private void DrawQuad() { GLES20.glUseProgram(mQProgram); GLES20.glDisable(GLES20.GL_DEPTH_TEST); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, glQuadVB); GLES20.glEnableVertexAttribArray(maQPosition); GLES20.glVertexAttribPointer(maQPosition, 3, GLES20.GL_FLOAT, false, 20, 0); GLES20.glEnableVertexAttribArray(maQTexCoord); GLES20.glVertexAttribPointer(maQTexCoord, 2, GLES20.GL_FLOAT, false, 20, 12); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glUniform1i(muQTexture, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(maQPosition); GLES20.glDisableVertexAttribArray(maQTexCoord); } 


рд╕реНрд╡рд░реВрдк рдореЗрдВ рджреГрд╢реНрдп рдЪреВрдВрдХрд┐ рдкреНрд░рднрд╛рд╡ рдХрдИ рдкрд╛рд╕реЛрдВ рдореЗрдВ рд╕реБрдкрд░рдЗрдореНрдкреЛрдЬ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдЯреЗрдХреНрд╕рдЪрд░ рдХрдо рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдХреНрд╡рд╛рдб рдкрд░ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХрд╛ рдирддреАрдЬрд╛ рдХреБрдЫ рдРрд╕рд╛ рд╣реА рд╣реЛрдЧрд╛ рдЬреИрд╕рд╛ рддрд╕реНрд╡реАрд░ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдУрд╣! рдмрд╕ рдереЛрдбрд╝рд╛ рд╕рд╛ рдмрдЪрд╛ рд╣реИ: рдПрдХ рдЬреЛрдбрд╝реЗ рдФрд░ рдЕрдзрд┐рдХ shaders рдФрд░ рдХреЛрдб рдХреЗ рдХреБрдЫ рдмреНрд▓реЙрдХ!

рдЧреЙрд╕рд┐рдпрди рдмреНрд▓рд░


рдЗрд╕ рддрд░рд╣ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдпрд╛рдореА рдзреБрдВрдзрд▓рд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╣рдорд╛рд░реЗ рдлреНрд░реЗрдо рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП, 44 рдкрдбрд╝реЛрд╕реА рдкрд┐рдХреНрд╕рд▓ рд▓рд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЙрдирдХреЗ рд░рдВрдЧреЛрдВ рдХреЛ рдЧреМрд╕рд┐рдпрди рд╡рд┐рддрд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рдЬрди рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ 11 рдкрд╛рд╕ рдореЗрдВ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рдореВрд▓ рджреГрд╢реНрдп рдХреЗ 4 рдкрд┐рдХреНрд╕реЗрд▓ рдкрд░рд┐рдгрд╛рдореА рдЫрд╡рд┐ рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЬрд╛рдПрдВрдЧреЗред рддрджрдиреБрд╕рд╛рд░, рдЕрд▓рдЧ-рдЕрд▓рдЧ рдСрдлрд╕реЗрдЯ рдХреЗ рд╕рд╛рде рд╢реЗрдбреНрд╕ рдХреЛ рдПрдХ рд╣реА рдкрд╛рд╕ рдореЗрдВ рдЪрд╛рд░ рдмрдирд╛рд╡рдЯ рдХреЛ рдУрд╡рд░рд▓реИрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдмреЗрд╢рдХ, рдЖрдк рдХрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдкрдиреЗ рд╕реНрд╡рд╛рдж рдХреЛ рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЖрдк рдЙрд╕ рд▓реЛрд╣реЗ рдХреЛ рдЦреАрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕ рдкрд░ рдЖрдк рд╕реНрд╡реАрдХрд╛рд░реНрдп рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪрд▓рд╛рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВред

рдкреНрд░рднрд╛рд╡ рджреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдХреНрд╖реИрддрд┐рдЬ рдФрд░ рд▓рдВрдмрд╡рддред рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдХреБрдЫ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЧрд╛рдКрд╕реА рд╕рдорд░реНрдерди рдбреЗрдЯрд╛

 class FilterKernelElement { public float du; public float dv; public float coef; } ... float mOffsets[] = new float[4]; private float[] pix_mult = new float[4]; private FilterKernelElement[] mvGaussian1D = new FilterKernelElement[44]; private float mfPerTexelWidth; private float mfPerTexelHeight; ... float cent = (mvGaussian1D.length - 1.0f) / 2.0f, radi; for (int u = 0; u < mvGaussian1D.length; u++) { FilterKernelElement el = mvGaussian1D[u] = new FilterKernelElement(); el.du = ((float)u) - cent - 0.1f; el.dv = 0.0f; radi = (el.du * el.du) / (cent * cent); el.coef = (float)((0.24/Math.exp(radi*0.18)) + 0.41/Math.exp(radi*4.5)); } float rr = texWidth / (float) texHeight; float rs = rr / ratio; mfPerTexelWidth = rs / texWidth; mfPerTexelHeight = 1.0f / texHeight; 


рдЕрдВрдд рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЛ рдкрд╣рд▓реВ рдЕрдиреБрдкрд╛рдд рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ: рдмрдирд╛рд╡рдЯ рдмрдлрд░ рдХреЗ рд╡рд┐рдкрд░реАрдд рд╕реНрдХреНрд░реАрди, рд╡рд░реНрдЧ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рдпреЛрдЬрди рдХреЗ рдмрд┐рдирд╛ рдЪрдордХ рдХреБрдЫ рд╣рдж рддрдХ рдЪрдкрдЯрд╛ рд╣реЛ рдЬрд╛рдПрдЧреАред

рдЧреЙрд╕ рд╢реЗрдбреНрд╕

  private final String gaussVS = "precision mediump float;\n" + "attribute vec4 vPosition;\n" + "attribute vec4 vTexCoord0;\n" + "uniform vec4 uTexOffset0;\n" + "uniform vec4 uTexOffset1;\n" + "uniform vec4 uTexOffset2;\n" + "uniform vec4 uTexOffset3;\n" + "varying vec4 TexCoord0;\n" + "varying vec4 TexCoord1;\n" + "varying vec4 TexCoord2;\n" + "varying vec4 TexCoord3;\n" + "void main() {\n" + " gl_Position = vPosition;\n" + " TexCoord0 = vTexCoord0 + uTexOffset0;\n" + " TexCoord1 = vTexCoord0 + uTexOffset1;\n" + " TexCoord2 = vTexCoord0 + uTexOffset2;\n" + " TexCoord3 = vTexCoord0 + uTexOffset3;\n" + "}\n"; private final String gaussFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform vec4 uTexCoef0;\n" + "uniform vec4 uTexCoef1;\n" + "uniform vec4 uTexCoef2;\n" + "uniform vec4 uTexCoef3;\n" + "varying vec4 TexCoord0;\n" + "varying vec4 TexCoord1;\n" + "varying vec4 TexCoord2;\n" + "varying vec4 TexCoord3;\n" + "void main() {\n" + " vec4 c0 = texture2D(uTexture0, TexCoord0.xy);\n" + " vec4 c1 = texture2D(uTexture0, TexCoord1.xy);\n" + " vec4 c2 = texture2D(uTexture0, TexCoord2.xy);\n" + " vec4 c3 = texture2D(uTexture0, TexCoord3.xy);\n" + " gl_FragColor = uTexCoef0 * c0 + uTexCoef1 * c1 + uTexCoef2 * c2 + uTexCoef3 * c3;\n" + "}\n"; private int mGProgram; private int maGPosition; private int maGTexCoord; private int muGTexture; private int[] muGTexCoef = new int[4]; private int[] muGTexOffset = new int[4]; ... mGProgram = Compile(gaussVS, gaussFS); maGPosition = GLES20.glGetAttribLocation(mGProgram, "vPosition"); maGTexCoord = GLES20.glGetAttribLocation(mGProgram, "vTexCoord0"); muGTexture = GLES20.glGetUniformLocation(mGProgram, "uTexture0"); for (i = 0; i < 4; i++) { muGTexOffset[i] = GLES20.glGetUniformLocation(mGProgram, String.format("uTexOffset%d", i)); muGTexCoef[i] = GLES20.glGetUniformLocation(mGProgram, String.format("uTexCoef%d", i)); } 


рдЧреЙрд╕ рдбреНрд░рд╛рдЗрдВрдЧ

рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЕрдХреНрд╖ рдкрд░ рдзреБрдВрдзрд▓рд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛: рдпрд╛ рддреЛ рдХреНрд╖реИрддрд┐рдЬ рдпрд╛ рд▓рдВрдмрд╡рдд, рдФрд░ рдХрдИ рдкрд╛рд╕ рдореЗрдВред рдЗрд╕реАрд▓рд┐рдП рджреЛ рдмрдирд╛рд╡рдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА!

  private void DrawGauss(boolean invert) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLES20.glUseProgram(mGProgram); GLES20.glDisable(GLES20.GL_DEPTH_TEST); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, glQuadVB); GLES20.glEnableVertexAttribArray(maGPosition); GLES20.glVertexAttribPointer(maGPosition, 3, GLES20.GL_FLOAT, false, 20, 0); GLES20.glEnableVertexAttribArray(maGTexCoord); GLES20.glVertexAttribPointer(maGTexCoord, 2, GLES20.GL_FLOAT, false, 20, 12); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glUniform1i(muGTexture, 0); int i, n, k; for (i = 0; i < mvGaussian1D.length; i += 4) { for (n = 0; n < 4; n++) { FilterKernelElement pE = mvGaussian1D[i + n]; for (k = 0; k < 4; k++) pix_mult[k] = pE.coef * 0.10f; GLES20.glUniform4fv(muGTexCoef[n], 1, pix_mult, 0); mOffsets[0] = mfPerTexelWidth * (invert ? pE.dv : pE.du); mOffsets[1] = mfPerTexelHeight * (invert ? pE.du : pE.dv); GLES20.glUniform4fv(muGTexOffset[n], 1, mOffsets, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); } GLES20.glDisableVertexAttribArray(maGPosition); GLES20.glDisableVertexAttribArray(maGTexCoord); } 


рдпрд╣ рдХреНрд░рдорд╢рдГ рдХреНрд╖реИрддрд┐рдЬ рдФрд░ рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдзрдмреНрдмрд╛ рдХреЗ рдмрд╛рдж рдкрд░рд┐рдгрд╛рдо рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

рдХреНрд╖реИрддрд┐рдЬ рдзреБрдВрдзрд▓рд╛ рдХреЗ рдмрд╛рджрдКрд░реНрдзреНрд╡рд╛рдзрд░ рдврд╛рдмреЗ рдХреЗ рдмрд╛рдж

рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛


рдЕрдВрддрд┐рдо рдЪрд░рдг: рд╕рднреА рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдкреВрд░реЗ рдлреНрд░реЗрдо рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ред рдореЙрдбрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЙрд╕ рдкрд░ рдПрдХ рдЪрдордХ рдбрд╛рд▓реЗрдВред

  @Override public void onDrawFrame(GL10 arg0) { setRenderTexture(filterBuf1, 0); DrawScene(); GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE); setRenderTexture(filterBuf2, renderTex1); DrawGauss(false); setRenderTexture(filterBuf1, renderTex2); DrawGauss(true); GLES20.glDisable(GLES20.GL_BLEND); setRenderTexture(0, 0); DrawScene(); GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE); setRenderTexture(0, renderTex1); DrawQuad(); GLES20.glDisable(GLES20.GL_BLEND); } 


рдХреБрд▓:
1. рдкрд╣рд▓реА рдмрдирд╛рд╡рдЯ рдореЗрдВ рдПрдХ рджреГрд╢реНрдп рдмрдирд╛рдПрдВ;
2. рдкрд╣рд▓реА рдмрдирд╛рд╡рдЯ рдХреЗ рд▓рд┐рдП, рдХреНрд╖реИрддрд┐рдЬ рдзреБрдВрдзрд▓рд╛ рдХрд░реЗрдВ, рджреВрд╕рд░реЗ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдЪрд╛рдПрдВ;
3. рдЦрдбрд╝реА рджреВрд╕рд░реА рдмрдирд╛рд╡рдЯ рдХреЛ рдзреБрдВрдзрд▓рд╛ рдХрд░реЗрдВ, рдкрд╣рд▓реЗ рдХреЛ рдмрдЪрд╛рдПрдВ;
4. рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рдореЛрдб рдореЗрдВ рдПрдХ рджреГрд╢реНрдп рдЦреАрдВрдЪрддреЗ рд╣реИрдВ;
5. рдПрдХ рдХреНрд╡рд╛рдб рдХреА рдорджрдж рд╕реЗ рджреГрд╢реНрдп рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдкрд╣рд▓реА рдмрдирд╛рд╡рдЯ рд▓рд╛рдЧреВ рдХрд░реЗрдВ;
6. рд╣реЛ рдЧрдпрд╛!

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рджреГрд╢реНрдп рдХреЗрд╡рд▓ рдПрдХ рдмрдирд╛рд╡рдЯ рдкрд░, рдПрдХ рдмрд╛рд░ рдЦреАрдВрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреБрд░рдВрдд рдПрдХ рдХреНрд╡рд╛рдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдХреНрд░реАрди рдмрдлрд░ рдкрд░ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЗрд╕реЗ рдХреЙрдкреА рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рднреНрдп рддрд╕реНрд╡реАрд░ рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рдорд╛рди рд╣реА рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдХреА рдмрдирд╛рд╡рдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдФрд░ рдпрд╣ рдЗрд╕рдХреЗ рдзрдмреНрдмрд╛ рдХреЛ рдХрд╛рдлреА рдзреАрдорд╛ рдХрд░ рджреЗрдЧрд╛ред

рд╡реИрд╕реЗ, рдкрд░рд┐рдгрд╛рдореА рдХрд╛рд░реНрдпрдХреНрд░рдо рдПрдХ рдЕрдЪреНрдЫрд╛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдлрд╝рд┐рд▓реНрд░реЗрдЯ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдХреЗрд╡рд▓ "рд▓реЗрдХрд┐рди": рдпрд╣ рдХреНрд╡рд╛рд▓рдХреЙрдо рдкреНрд░реЛрд╕реЗрд╕рд░ (рд╕реНрд░реЛрдд рджреГрд╢реНрдп рдХреЗ shader рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛) рдкрд░ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдЕрднреА рднреА рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдирд╣реАрдВ рдкрддрд╛ рдЪрд▓ рдкрд╛рдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдЕрдВрдд рддрдХ рдбрд┐рдмрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХрд▓ рдПрдЪрдЯреАрд╕реА рдбрд┐рд╡рд╛рдЗрд╕ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдм рдХреБрдЫ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд╛рд╡рд░рд╡реАрдЖрд░ 540 (рдкреБрд░рд╛рдиреЗ рдЧреИрд▓реЗрдХреНрд╕реА рдПрд╕ рдкрд░), рдорд╛рд▓реА 400 (рдПрд╕ 2, рдЯреИрдм 7.7, рдиреЛрдЯ) рдФрд░ рдПрдореБрд▓реЗрдЯрд░ рдореЗрдВ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЕрдкрдбреЗрдЯ: рдкреНрд░рдХрд╛рд╢рди рдХреЗ рдмрд╛рдж рд╕реЗ рдХрдИ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реБрдИ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд▓реЗрдЦ рдХреЛ рдереЛрдбрд╝рд╛ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореЙрдбрд▓ рд╢реЗрдбрд░ рдХреЛрдб (рд╡рд░реНрдЯреЗрдХреНрд╢реИрдбрд░рдХреЛрдб, рдХрдИ рд▓рд╛рдЗрдиреЗрдВ рд╣рдЯрд╛ рджреА рдЧрдИ), рдбреНрд░реЙрд╕реНрдХреАрди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХреЛрдб (рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рдордиреНрд╡рдп рдХреЛ рдЖрдВрдЦ-рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рдмрджрд▓рдирд╛) рдФрд░ рдЕрдВрддрд┐рдо рд░реЗрдВрдбрд░рд┐рдВрдЧ (onDrawFrame) рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛, рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП (рдУрд╡рд░рдПрдХреНрд╕рдкреЛрдЬрд░ рдЧрд╛рдпрдм рд╣реЛ рдЧрдП)ред рдмрд╛рдХреА рд╕рдм рд╡рд╣реА рд░рд╣рддрд╛ рд╣реИред

рдЕрдкрдбреЗрдЯ 2: рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдкреЛрд╕реНрдЯ .3ds рддреИрдпрд╛рд░ рд╣реИред

рдЕрджреНрдпрддрди 3: рдХреНрд╡рд╛рд▓рдХреЙрдо рдкрд░ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЗ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдпрд╣ рд▓рд╛рдЗрди рдЫрд╛рдпрд╛рджрд╛рд░ рдореЗрдВ рд╣реИ
 for (i = 0; i < uLights; i++) 

рдареАрдХ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ рдХрд┐рд╕рдиреЗ рд╕реЛрдЪрд╛ рд╣реЛрдЧрд╛? редред
рд╢реЗрдбреНрд╕ рдФрд░ рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЕрдм рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред

Source: https://habr.com/ru/post/In144831/


All Articles