• openGL es2.0 创建纹理灯光球


    package com.gzdxid.utils;
    
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    import java.util.ArrayList;
    
    import android.opengl.GLES20;
    
    public class DrawBallTextureLight {
    
    	int mProgram;
    	int muMVPMatrixHandle;
    	int muMMatrixHandle;
    	int muLightLocationHandle;
    	int muCameraHandle;
    	
    	int maPositionHandle;
    	int maNormalHandle;
    	int maTexCoorHandle;
    
    	FloatBuffer mVertexBuffer;
    	FloatBuffer mTexCoorBuffer;
    	FloatBuffer mNormalBuffer;
    
    	int vCount = 0;
    	final float UNIT_SIZE = 1f;
    	final float angleSpan = 10f;
    	float R = 0;
    	
    	public float roateX;
    	public float roateY;
    	
    	public DrawBallTextureLight(float r,int mProgram) {
    		initVertex(r);
    		initShader(mProgram);
    	}
    
    	private void initVertex(float r) {
    		R = r;
    		ArrayList<Float> alVertix = new ArrayList<Float>();
    		for (float vAngle = 90; vAngle > -90; vAngle -= angleSpan) {
    			for (float hAngle = 360; hAngle > 0; hAngle -= angleSpan) {
    				float x1 = getCoor(0, vAngle, hAngle);
    				float y1 = getCoor(1, vAngle, hAngle);
    				float z1 = getCoor(2, vAngle, hAngle);
    
    				float x2 = getCoor(0, vAngle - angleSpan, hAngle);
    				float y2 = getCoor(1, vAngle - angleSpan, hAngle);
    				float z2 = getCoor(2, vAngle - angleSpan, hAngle);
    
    				float x3 = getCoor(0, vAngle - angleSpan, hAngle - angleSpan);
    				float y3 = getCoor(1, vAngle - angleSpan, hAngle - angleSpan);
    				float z3 = getCoor(2, vAngle - angleSpan, hAngle - angleSpan);
    
    				float x4 = getCoor(0, vAngle, hAngle - angleSpan);
    				float y4 = getCoor(1, vAngle, hAngle - angleSpan);
    				float z4 = getCoor(2, vAngle, hAngle - angleSpan);
    
    				alVertix.add(x1);
    				alVertix.add(y1);
    				alVertix.add(z1);
    				alVertix.add(x2);
    				alVertix.add(y2);
    				alVertix.add(z2);
    				alVertix.add(x4);
    				alVertix.add(y4);
    				alVertix.add(z4);
    				// 构建第二三角形
    				alVertix.add(x4);
    				alVertix.add(y4);
    				alVertix.add(z4);
    				alVertix.add(x2);
    				alVertix.add(y2);
    				alVertix.add(z2);
    				alVertix.add(x3);
    				alVertix.add(y3);
    				alVertix.add(z3);
    			}
    		}
    		
    		vCount = alVertix.size() / 3;
    		
    		float vertices[] = new float[vCount * 3];
    		for (int i = 0; i < alVertix.size(); i++) {
    			vertices[i] = alVertix.get(i);
    		}
    		ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    		vbb.order(ByteOrder.nativeOrder());
    		mVertexBuffer = vbb.asFloatBuffer();
    		mVertexBuffer.put(vertices);
    		mVertexBuffer.position(0);
    
    		float[] texCoor = generateTexCoor(// 获取切分整图的纹理数组
    				(int) (360 / angleSpan), // 纹理图切分的列数
    				(int) (180 / angleSpan) // 纹理图切分的行数
    		);
    		ByteBuffer llbb = ByteBuffer.allocateDirect(texCoor.length * 4);
    		llbb.order(ByteOrder.nativeOrder());// 设置字节顺序
    		mTexCoorBuffer = llbb.asFloatBuffer();
    		mTexCoorBuffer.put(texCoor);
    		mTexCoorBuffer.position(0);
    		
    		mNormalBuffer=mVertexBuffer;
    	}
    
    	private void initShader(int mProgram) {
    		this.mProgram=mProgram;
    		muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    		muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix"); 
    		muLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
    		muCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera"); 
            
    		maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
    		maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
    		maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
    	}
    	
    	public void drawSelf(int texId){
    		MatrixState.rotate(roateX, 1, 0, 0);
    		MatrixState.rotate(roateY, 0, 1, 0);
    		
    		GLES20.glUseProgram(mProgram);
    		GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
    		GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);    
            GLES20.glUniform3fv(muLightLocationHandle, 1, MatrixState.lightPositionFB);
            GLES20.glUniform3fv(muCameraHandle, 1, MatrixState.cameraFB);
            
    		GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertexBuffer);
    		GLES20.glVertexAttribPointer(maTexCoorHandle, 2, GLES20.GL_FLOAT, false, 2 * 4, mTexCoorBuffer);
    		GLES20.glVertexAttribPointer(maNormalHandle, 3, GLES20.GL_FLOAT, false, 3*4, mNormalBuffer);
    		GLES20.glEnableVertexAttribArray(maPositionHandle);
    		GLES20.glEnableVertexAttribArray(maNormalHandle);
    		GLES20.glEnableVertexAttribArray(maTexCoorHandle);
    		
    		GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
    		GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
    	}
    	
    
    	private float getCoor(int which, float vAngle, float hAngle) {
    		switch (which) {
    		case 0:// x
    			return (float) (R * UNIT_SIZE * Math.cos(Math.toRadians(vAngle)) * Math.cos(Math.toRadians(hAngle)));
    		case 1:// y
    			return (float) (R * UNIT_SIZE * Math.sin(Math.toRadians(vAngle)));
    		case 2:// z
    			return (float) (R * UNIT_SIZE * Math.cos(Math.toRadians(vAngle)) * Math.sin(Math.toRadians(hAngle)));
    		}
    		return 0;
    	}
    
    	// 自动切分纹理产生纹理数组的方法
    	public float[] generateTexCoor(int bw, int bh) {
    		float[] result = new float[bw * bh * 6 * 2];
    		float sizew = 1.0f / bw;// 列数
    		float sizeh = 1.0f / bh;// 行数
    		int c = 0;
    		for (int i = 0; i < bh; i++) {
    			for (int j = 0; j < bw; j++) {
    				// 每行列一个矩形,由两个三角形构成,共六个点,12个纹理坐标
    				float s = j * sizew;
    				float t = i * sizeh;
    				result[c++] = s;
    				result[c++] = t;
    				result[c++] = s;
    				result[c++] = t + sizeh;
    				result[c++] = s + sizew;
    				result[c++] = t;
    				result[c++] = s + sizew;
    				result[c++] = t;
    				result[c++] = s;
    				result[c++] = t + sizeh;
    				result[c++] = s + sizew;
    				result[c++] = t + sizeh;
    			}
    		}
    		return result;
    	}
    		
    }
    
    <span style="font-family: Arial; font-size: 14px; line-height: 26px;">二、顶点着色器:</span>
    
    <span style="font-family: Arial; font-size: 14px; line-height: 26px;"></span><pre name="code" class="cpp">uniform mat4 uMVPMatrix; //总变换矩阵
    uniform mat4 uMMatrix; //变换矩阵
    uniform vec3 uLightLocation;	//光源位置
    uniform vec3 uCamera;	//摄像机位置
    attribute vec3 aPosition;  //顶点位置
    attribute vec3 aNormal;    //顶点法向量
    attribute vec2 aTexCoor;    //顶点纹理坐标
    //用于传递给片元着色器的变量
    varying vec4 vAmbient;
    varying vec4 vDiffuse;
    varying vec4 vSpecular;
    varying vec2 vTextureCoord;  
    //定位光光照计算的方法
    void pointLight(					//定位光光照计算的方法
      in vec3 normal,				//法向量
      inout vec4 ambient,			//环境光最终强度
      inout vec4 diffuse,				//散射光最终强度
      inout vec4 specular,			//镜面光最终强度
      in vec3 lightLocation,			//光源位置
      in vec4 lightAmbient,			//环境光强度
      in vec4 lightDiffuse,			//散射光强度
      in vec4 lightSpecular			//镜面光强度
    ){
      ambient=lightAmbient;			//直接得出环境光的最终强度  
      vec3 normalTarget=aPosition+normal;	//计算变换后的法向量
      vec3 newNormal=(uMMatrix*vec4(normalTarget,1)).xyz-(uMMatrix*vec4(aPosition,1)).xyz;
      newNormal=normalize(newNormal); 	//对法向量规格化
      //计算从表面点到摄像机的向量
      vec3 eye= normalize(uCamera-(uMMatrix*vec4(aPosition,1)).xyz);  
      //计算从表面点到光源位置的向量vp
      vec3 vp= normalize(lightLocation-(uMMatrix*vec4(aPosition,1)).xyz);  
      vp=normalize(vp);//格式化vp
      vec3 halfVector=normalize(vp+eye);	//求视线与光线的半向量    
      float shininess=50.0;				//粗糙度,越小越光滑
      float nDotViewPosition=max(0.0,dot(newNormal,vp)); 	//求法向量与vp的点积与0的最大值
      diffuse=lightDiffuse*nDotViewPosition;				//计算散射光的最终强度
      float nDotViewHalfVector=dot(newNormal,halfVector);	//法线与半向量的点积 
      float powerFactor=max(0.0,pow(nDotViewHalfVector,shininess)); 	//镜面反射光强度因子
      specular=lightSpecular*powerFactor;    			//计算镜面光的最终强度
    }
    
    
    void main()     
    { 
       gl_Position = uMVPMatrix * vec4(aPosition,1); //根据总变换矩阵计算此次绘制此顶点位置  
       
       vec4 ambientTemp, diffuseTemp, specularTemp;   //存放环境光、散射光、镜面反射光的临时变量      
       pointLight(normalize(aNormal),ambientTemp,diffuseTemp,specularTemp,uLightLocation,
       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));
       
       vAmbient=ambientTemp;
       vDiffuse=diffuseTemp;
       vSpecular=specularTemp;
       vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
    }                      

    三、片源着色器:
    
    
    <span style="font-family: Arial; font-size: 14px; line-height: 26px;"><span style="font-family: Arial; font-size: 14px; line-height: 26px;"></span></span><pre name="code" class="cpp">precision mediump float;
    uniform sampler2D sTexture;//纹理内容数据
    //接收从顶点着色器过来的参数
    varying vec4 vAmbient;
    varying vec4 vDiffuse;
    varying vec4 vSpecular;
    varying vec2 vTextureCoord;
    
    void main()                         
    {    
       //将计算出的颜色给此片元
       vec4 finalColor=texture2D(sTexture, vTextureCoord);    
       //给此片元颜色值
       gl_FragColor = finalColor*vAmbient+finalColor*vSpecular+finalColor*vDiffuse;
    
    }   


    
    
    
    


  • 相关阅读:
    Python之Pyautogui模块20180125《PYTHON快速上手让繁琐的工作自动化》18章
    〈Android 群英传-神兵利器〉第7章一个的寂寞与一群人的狂欢
    一,Android Studio笔记
    一、探索 Android Studio
    微服务之网关:Ocelot+Consul实现动态集群扩展
    MacOS任意降级
    微服务之注册服务与发现:Consul在Windows下安装使用
    .Net Core中使用 AutoMapper
    .Net Core中使用Swagger
    .NetCore中使用EF Core
  • 原文地址:https://www.cnblogs.com/Anzhongliu/p/6092119.html
Copyright © 2020-2023  润新知