使jpg图片能够透明的一种方法

时间:2022-06-12 04:30:36

效果如图(里面的方体):

使jpg图片能够透明的一种方法

注意:化学元素围成的圈,后面的透过方体也能看到!!!。

贴图图片:

使jpg图片能够透明的一种方法

第一步:shader的编写

顶点着色器:

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(1.0,1.0,1.0,1.0),vec4(1.0,1.0,1.0,1.0),vec4(1.0,1.0,1.0,1.0));
   
   vAmbient=ambientTemp;
   vDiffuse=diffuseTemp;
   vSpecular=specularTemp;
   vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
}                      

片元着色器:

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);    
  <span style="color:#cc0000;"> finalColor.a=(finalColor.r+finalColor.g+finalColor.b)/3.0;//核心语句!!!!!!!!!!!</span>
   gl_FragColor = finalColor*vAmbient+finalColor*vSpecular+finalColor*vDiffuse;

}   


第二步:画方体:

package com.gzdxid.utils;

import android.opengl.GLES20;

public class DrawCubeTextureLight {

	private DrawRectTextureLight frontRect = null;
	private DrawRectTextureLight leftRect = null;
	private DrawRectTextureLight bottomRect = null;
	private int flag;
	private float halfWidth;
	private float halfHeight;
	private float halfLength;
	final float tzz = 0.1f;
	final float tzs=0.0f;
	// flag==0:法线朝里;flag==1:法线朝外;
	public DrawCubeTextureLight(float width,float height,float length,int mProgram, int flag) {
		frontRect = new DrawRectTextureLight(width, height,mProgram);
		leftRect=new DrawRectTextureLight(height, length, mProgram);
		bottomRect=new DrawRectTextureLight(width, length, mProgram);
		this.flag = flag;
		this.halfWidth=width/2;
		this.halfHeight=height/2;
		this.halfLength=length/2;
	}

	// textureId:up-down-left-right-front-back
	public void drawSelf(int[] textureId) {
		<span style="color:#ff0000;">GLES20.glDisable(GLES20.GL_DEPTH_TEST);//一定要关闭,不然方体后面的元素看不到</span>
		switch (flag) {
		case 0:
			drawCube0(textureId);
			break;
		case 1:
			drawCube1(textureId);
			break;
		}
		<span style="color:#cc0000;">GLES20.glEnable(GLES20.GL_DEPTH_TEST);</span>
	}

	private void drawCube0(int[] textureId) {
		// TODO Auto-generated method stub
		// up
		MatrixState.pushMatrix();
		MatrixState.translate(0, halfHeight - tzz, 0);
		MatrixState.rotate(90, 1, 0, 0);
		bottomRect.drawSelf(textureId[0]);
		MatrixState.popMatrix();

		// down
		MatrixState.pushMatrix();
		MatrixState.translate(0, -halfHeight + tzz, 0);
		MatrixState.rotate(-90, 1, 0, 0);
		bottomRect.drawSelf(textureId[1]);
		MatrixState.popMatrix();

		// left
		MatrixState.pushMatrix();
		MatrixState.translate(-halfWidth + tzz, 0, 0);
		MatrixState.rotate(90, 0, 1, 0);
		leftRect.drawSelf(textureId[2]);
		MatrixState.popMatrix();

		// right
		MatrixState.pushMatrix();
		MatrixState.translate(halfWidth - tzz, 0, 0);
		MatrixState.rotate(-90, 0, 1, 0);
		leftRect.drawSelf(textureId[3]);
		MatrixState.popMatrix();

		// front
		MatrixState.pushMatrix();
		MatrixState.translate(0, 0, halfLength - tzz);
		MatrixState.rotate(180, 0, 1, 0);
		frontRect.drawSelf(textureId[4]);
		MatrixState.popMatrix();

		// back
		MatrixState.pushMatrix();
		MatrixState.translate(0, 0, -halfLength + tzz);
		frontRect.drawSelf(textureId[5]);
		MatrixState.popMatrix();

	}

	private void drawCube1(int[] textureId) {

		// up
		MatrixState.pushMatrix();
		MatrixState.translate(0, halfHeight - tzs, 0);
		MatrixState.rotate(-90, 1, 0, 0);
		bottomRect.drawSelf(textureId[0]);
		MatrixState.popMatrix();

		// down
		MatrixState.pushMatrix();
		MatrixState.translate(0, -halfHeight + tzs, 0);
		MatrixState.rotate(90, 1, 0, 0);
		bottomRect.drawSelf(textureId[1]);
		MatrixState.popMatrix();

		// left
		MatrixState.pushMatrix();
		MatrixState.translate(-halfWidth + tzs, 0, 0);
		MatrixState.rotate(-90, 0, 1, 0);
		leftRect.drawSelf(textureId[3]);
		MatrixState.popMatrix();

		// right
		MatrixState.pushMatrix();
		MatrixState.translate(halfWidth - tzs, 0, 0);
		MatrixState.rotate(90, 0, 1, 0);
		leftRect.drawSelf(textureId[2]);
		MatrixState.popMatrix();

		// front
		MatrixState.pushMatrix();
		MatrixState.translate(0, 0, halfLength - tzs);
		frontRect.drawSelf(textureId[4]);
		MatrixState.popMatrix();

		// back
		MatrixState.pushMatrix();
		MatrixState.translate(0, 0, -halfLength + tzs);
		MatrixState.rotate(180, 0, 1, 0);
		frontRect.drawSelf(textureId[5]);
		MatrixState.popMatrix();

	}

}

补:画平面代码:

package com.gzdxid.utils;
import java.nio.FloatBuffer;
import android.opengl.GLES20;


//纹理矩形
public class DrawRectTextureLight 
{	
	int mProgram;//自定义渲染管线着色器程序id
    int muMVPMatrixHandle;//总变换矩阵引用
    int maPositionHandle; //顶点位置属性引用 
    int maTexCoorHandle; //顶点纹理坐标属性引用 
    String mVertexShader;//顶点着色器    	 
    String mFragmentShader;//片元着色器
	
	FloatBuffer   mVertexBuffer;//顶点坐标数据缓冲
	FloatBuffer   mTexCoorBuffer;//顶点纹理坐标数据缓冲
    int vCount=0;   
    
    public DrawRectTextureLight(float width, float height, int mProgram)
    {    	
    	initVertexData(width, height);
		intShader(mProgram);
    }
    
    //初始化顶点坐标与着色数据的方法
    public void initVertexData(float width, float height)
    {
    	vCount = 6;
		float w = width / 2;
		float h = height / 2;
		float vertices[] = new float[] { 
		-w,  h, 0,
		-w, -h, 0,
		 w, -h, 0,
		 w, -h, 0,
		 w,  h, 0,
		-w,  h, 0,

		};
		mVertexBuffer=UtilBufferTransfer.getFloatBuffer(vertices);

		float texCoor[] = new float[] { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 };
		mTexCoorBuffer=UtilBufferTransfer.getFloatBuffer(texCoor);

    }

    //初始化shader
    public void intShader(int mProgam)
    {
    	this.mProgram = mProgam;
    	muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");  
        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
        maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
    }
    
    public void drawSelf(int texId)
    {        
    	 GLES20.glUseProgram(mProgram); 
         GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0); 
         GLES20.glVertexAttribPointer  
         (
         		maPositionHandle,   
         		3, 
         		GLES20.GL_FLOAT, 
         		false,
                3*4,   
                mVertexBuffer
         );       
         GLES20.glVertexAttribPointer  
         (
        		maTexCoorHandle, 
         		2, 
         		GLES20.GL_FLOAT, 
         		false,
                2*4,   
                mTexCoorBuffer
         );   
         GLES20.glEnableVertexAttribArray(maPositionHandle);  
         GLES20.glEnableVertexAttribArray(maTexCoorHandle);  
         
         GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
         
         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount); 
    }
}

第三步:应用

                       <span style="color:#ff0000;"> GLES20.glEnable(GLES20.GL_BLEND);
			GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);</span>
			MatrixState.pushMatrix();
			MatrixState.translate(0, 0, offsetZ);
			MatrixState.rotate(angleRotateCube, 0, 1, 0);
			MatrixState.rotate(-angleRotateZ, 0, 0, 1);
			centerCube.drawSelf(cubeId);
			MatrixState.popMatrix();
			<span style="color:#ff0000;">GLES20.glDisable(GLES20.GL_BLEND);</span>


小感想:在三维软件渲染图片时的效果,我们要想一想怎样用代码实现,这样才真正理解代码意思!!!