openGL es2.0 创建纹理灯光球

Love The Way You Lie 2022-08-06 13:23 229阅读 0赞

一、Java代码:

  1. package com.gzdxid.utils;
  2. import java.nio.ByteBuffer;
  3. import java.nio.ByteOrder;
  4. import java.nio.FloatBuffer;
  5. import java.util.ArrayList;
  6. import android.opengl.GLES20;
  7. public class DrawBallTextureLight {
  8. int mProgram;
  9. int muMVPMatrixHandle;
  10. int muMMatrixHandle;
  11. int muLightLocationHandle;
  12. int muCameraHandle;
  13. int maPositionHandle;
  14. int maNormalHandle;
  15. int maTexCoorHandle;
  16. FloatBuffer mVertexBuffer;
  17. FloatBuffer mTexCoorBuffer;
  18. FloatBuffer mNormalBuffer;
  19. int vCount = 0;
  20. final float UNIT_SIZE = 1f;
  21. final float angleSpan = 10f;
  22. float R = 0;
  23. public float roateX;
  24. public float roateY;
  25. public DrawBallTextureLight(float r,int mProgram) {
  26. initVertex(r);
  27. initShader(mProgram);
  28. }
  29. private void initVertex(float r) {
  30. R = r;
  31. ArrayList<Float> alVertix = new ArrayList<Float>();
  32. for (float vAngle = 90; vAngle > -90; vAngle -= angleSpan) {
  33. for (float hAngle = 360; hAngle > 0; hAngle -= angleSpan) {
  34. float x1 = getCoor(0, vAngle, hAngle);
  35. float y1 = getCoor(1, vAngle, hAngle);
  36. float z1 = getCoor(2, vAngle, hAngle);
  37. float x2 = getCoor(0, vAngle - angleSpan, hAngle);
  38. float y2 = getCoor(1, vAngle - angleSpan, hAngle);
  39. float z2 = getCoor(2, vAngle - angleSpan, hAngle);
  40. float x3 = getCoor(0, vAngle - angleSpan, hAngle - angleSpan);
  41. float y3 = getCoor(1, vAngle - angleSpan, hAngle - angleSpan);
  42. float z3 = getCoor(2, vAngle - angleSpan, hAngle - angleSpan);
  43. float x4 = getCoor(0, vAngle, hAngle - angleSpan);
  44. float y4 = getCoor(1, vAngle, hAngle - angleSpan);
  45. float z4 = getCoor(2, vAngle, hAngle - angleSpan);
  46. alVertix.add(x1);
  47. alVertix.add(y1);
  48. alVertix.add(z1);
  49. alVertix.add(x2);
  50. alVertix.add(y2);
  51. alVertix.add(z2);
  52. alVertix.add(x4);
  53. alVertix.add(y4);
  54. alVertix.add(z4);
  55. // 构建第二三角形
  56. alVertix.add(x4);
  57. alVertix.add(y4);
  58. alVertix.add(z4);
  59. alVertix.add(x2);
  60. alVertix.add(y2);
  61. alVertix.add(z2);
  62. alVertix.add(x3);
  63. alVertix.add(y3);
  64. alVertix.add(z3);
  65. }
  66. }
  67. vCount = alVertix.size() / 3;
  68. float vertices[] = new float[vCount * 3];
  69. for (int i = 0; i < alVertix.size(); i++) {
  70. vertices[i] = alVertix.get(i);
  71. }
  72. ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
  73. vbb.order(ByteOrder.nativeOrder());
  74. mVertexBuffer = vbb.asFloatBuffer();
  75. mVertexBuffer.put(vertices);
  76. mVertexBuffer.position(0);
  77. float[] texCoor = generateTexCoor(// 获取切分整图的纹理数组
  78. (int) (360 / angleSpan), // 纹理图切分的列数
  79. (int) (180 / angleSpan) // 纹理图切分的行数
  80. );
  81. ByteBuffer llbb = ByteBuffer.allocateDirect(texCoor.length * 4);
  82. llbb.order(ByteOrder.nativeOrder());// 设置字节顺序
  83. mTexCoorBuffer = llbb.asFloatBuffer();
  84. mTexCoorBuffer.put(texCoor);
  85. mTexCoorBuffer.position(0);
  86. mNormalBuffer=mVertexBuffer;
  87. }
  88. private void initShader(int mProgram) {
  89. this.mProgram=mProgram;
  90. muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
  91. muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
  92. muLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
  93. muCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
  94. maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
  95. maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
  96. maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
  97. }
  98. public void drawSelf(int texId){
  99. MatrixState.rotate(roateX, 1, 0, 0);
  100. MatrixState.rotate(roateY, 0, 1, 0);
  101. GLES20.glUseProgram(mProgram);
  102. GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
  103. GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
  104. GLES20.glUniform3fv(muLightLocationHandle, 1, MatrixState.lightPositionFB);
  105. GLES20.glUniform3fv(muCameraHandle, 1, MatrixState.cameraFB);
  106. GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertexBuffer);
  107. GLES20.glVertexAttribPointer(maTexCoorHandle, 2, GLES20.GL_FLOAT, false, 2 * 4, mTexCoorBuffer);
  108. GLES20.glVertexAttribPointer(maNormalHandle, 3, GLES20.GL_FLOAT, false, 3*4, mNormalBuffer);
  109. GLES20.glEnableVertexAttribArray(maPositionHandle);
  110. GLES20.glEnableVertexAttribArray(maNormalHandle);
  111. GLES20.glEnableVertexAttribArray(maTexCoorHandle);
  112. GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
  113. GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
  114. GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
  115. }
  116. private float getCoor(int which, float vAngle, float hAngle) {
  117. switch (which) {
  118. case 0:// x
  119. return (float) (R * UNIT_SIZE * Math.cos(Math.toRadians(vAngle)) * Math.cos(Math.toRadians(hAngle)));
  120. case 1:// y
  121. return (float) (R * UNIT_SIZE * Math.sin(Math.toRadians(vAngle)));
  122. case 2:// z
  123. return (float) (R * UNIT_SIZE * Math.cos(Math.toRadians(vAngle)) * Math.sin(Math.toRadians(hAngle)));
  124. }
  125. return 0;
  126. }
  127. // 自动切分纹理产生纹理数组的方法
  128. public float[] generateTexCoor(int bw, int bh) {
  129. float[] result = new float[bw * bh * 6 * 2];
  130. float sizew = 1.0f / bw;// 列数
  131. float sizeh = 1.0f / bh;// 行数
  132. int c = 0;
  133. for (int i = 0; i < bh; i++) {
  134. for (int j = 0; j < bw; j++) {
  135. // 每行列一个矩形,由两个三角形构成,共六个点,12个纹理坐标
  136. float s = j * sizew;
  137. float t = i * sizeh;
  138. result[c++] = s;
  139. result[c++] = t;
  140. result[c++] = s;
  141. result[c++] = t + sizeh;
  142. result[c++] = s + sizew;
  143. result[c++] = t;
  144. result[c++] = s + sizew;
  145. result[c++] = t;
  146. result[c++] = s;
  147. result[c++] = t + sizeh;
  148. result[c++] = s + sizew;
  149. result[c++] = t + sizeh;
  150. }
  151. }
  152. return result;
  153. }
  154. }

二、顶点着色器:

  1. uniform mat4 uMVPMatrix; //总变换矩阵
  2. uniform mat4 uMMatrix; //变换矩阵
  3. uniform vec3 uLightLocation; //光源位置
  4. uniform vec3 uCamera; //摄像机位置
  5. attribute vec3 aPosition; //顶点位置
  6. attribute vec3 aNormal; //顶点法向量
  7. attribute vec2 aTexCoor; //顶点纹理坐标
  8. //用于传递给片元着色器的变量
  9. varying vec4 vAmbient;
  10. varying vec4 vDiffuse;
  11. varying vec4 vSpecular;
  12. varying vec2 vTextureCoord;
  13. //定位光光照计算的方法
  14. void pointLight( //定位光光照计算的方法
  15. in vec3 normal, //法向量
  16. inout vec4 ambient, //环境光最终强度
  17. inout vec4 diffuse, //散射光最终强度
  18. inout vec4 specular, //镜面光最终强度
  19. in vec3 lightLocation, //光源位置
  20. in vec4 lightAmbient, //环境光强度
  21. in vec4 lightDiffuse, //散射光强度
  22. in vec4 lightSpecular //镜面光强度
  23. ){
  24. ambient=lightAmbient; //直接得出环境光的最终强度
  25. vec3 normalTarget=aPosition+normal; //计算变换后的法向量
  26. vec3 newNormal=(uMMatrix*vec4(normalTarget,1)).xyz-(uMMatrix*vec4(aPosition,1)).xyz;
  27. newNormal=normalize(newNormal); //对法向量规格化
  28. //计算从表面点到摄像机的向量
  29. vec3 eye= normalize(uCamera-(uMMatrix*vec4(aPosition,1)).xyz);
  30. //计算从表面点到光源位置的向量vp
  31. vec3 vp= normalize(lightLocation-(uMMatrix*vec4(aPosition,1)).xyz);
  32. vp=normalize(vp);//格式化vp
  33. vec3 halfVector=normalize(vp+eye); //求视线与光线的半向量
  34. float shininess=50.0; //粗糙度,越小越光滑
  35. float nDotViewPosition=max(0.0,dot(newNormal,vp)); //求法向量与vp的点积与0的最大值
  36. diffuse=lightDiffuse*nDotViewPosition; //计算散射光的最终强度
  37. float nDotViewHalfVector=dot(newNormal,halfVector); //法线与半向量的点积
  38. float powerFactor=max(0.0,pow(nDotViewHalfVector,shininess)); //镜面反射光强度因子
  39. specular=lightSpecular*powerFactor; //计算镜面光的最终强度
  40. }
  41. void main()
  42. {
  43. gl_Position = uMVPMatrix * vec4(aPosition,1); //根据总变换矩阵计算此次绘制此顶点位置
  44. vec4 ambientTemp, diffuseTemp, specularTemp; //存放环境光、散射光、镜面反射光的临时变量
  45. pointLight(normalize(aNormal),ambientTemp,diffuseTemp,specularTemp,uLightLocation,
  46. vec4(0.8,0.8,0.8,1.0),vec4(0.8,0.8,0.8,1.0),vec4(1.0,1.0,1.0,1.0));
  47. vAmbient=ambientTemp;
  48. vDiffuse=diffuseTemp;
  49. vSpecular=specularTemp;
  50. vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
  51. }

三、片源着色器:

  1. precision mediump float;
  2. uniform sampler2D sTexture;//纹理内容数据
  3. //接收从顶点着色器过来的参数
  4. varying vec4 vAmbient;
  5. varying vec4 vDiffuse;
  6. varying vec4 vSpecular;
  7. varying vec2 vTextureCoord;
  8. void main()
  9. {
  10. //将计算出的颜色给此片元
  11. vec4 finalColor=texture2D(sTexture, vTextureCoord);
  12. //给此片元颜色值
  13. gl_FragColor = finalColor*vAmbient+finalColor*vSpecular+finalColor*vDiffuse;
  14. }

发表评论

表情:
评论列表 (有 0 条评论,229人围观)

还没有评论,来说两句吧...

相关阅读

    相关 openGL纹理

    纹理压缩技术已经广泛应用在各种3D游戏之中,它们包括:DXTC(Direct X Texture Compress,DirectX纹理压缩,以S3TC为基础)、S3TC(S3