您的位置:首页 > 其它

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

2015-04-24 14:23 134 查看
效果如图(里面的方体):



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

贴图图片:



第一步: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>


小感想:在三维软件渲染图片时的效果,我们要想一想怎样用代码实现,这样才真正理解代码意思!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: