我正在学习如何使用OpenGL ES 1.0(我被告知最好从" 1.0" /" 1.1")开始。
我正在尝试使用透明纹理和顶点索引在Android设备上创建transperent 3D地球,但是我遇到的问题是我无法理解,并且无法在互联网上找到任何解决方案。
问题是,根据相机旋转的角度,我的地球仪会停止渲染"背面"球体或球体背面纹理。在下图中,您可以看到如果我将摄像机向同一方向旋转会发生什么。
链接到图片:CLICK HERE(我没有直接添加图片的声誉,抱歉)
你能帮助我吗?我的错是什么,为什么"回来"正在消失?"球"类:
package com.example.OpenGL_Testing.openGl.geometry;
import com.example.OpenGL_Testing.openGl.Texture;
import javax.microedition.khronos.opengles.GL10;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
public class Sphere {
float step = 5f; // density of sphere; step in degrees
float[] verArray;
float[] texIndex;
short[] verIndex;
private FloatBuffer vBuff;
private FloatBuffer tBuff;
private ShortBuffer iBuff;
public final float mCenterX, mCenterY, mCenterZ;
public final float mRadius;
private final GL10 mGL;
private int stepsPai, stepsTheta;
private Texture texture;
public Sphere(float mRadius, float mCenterX, float mCenterY, float mCenterZ, GL10 mGL) {
this.mGL = mGL;
// sphere parameters
this.mRadius = mRadius;
this.mCenterX = mCenterX;
this.mCenterY = mCenterY;
this.mCenterZ = mCenterZ;
stepsPai = (int) (180f / step) ; //sphere vertical 'lines'
stepsTheta = (int) (360f / step) + 1; //sphere horizontal 'lines'
// create sphere 'dots'
createVerticesBuff();
createIndexingBuffer();
}
private float[] createVerticesArray() {
float[] vertices = new float[stepsPai * stepsTheta * 3];
int n = 0;
float cRadius, cHeight, co, si;
for (float pai = 180f - step; pai > 0f; pai -= step) {
cRadius = (float) Math.sin((pai + step) * Math.PI / 180f);
cHeight = (float) Math.cos((pai + step) * Math.PI / 180f);
for (float theta = 0.0f; theta <= 360f; theta += step) {
co = (float) Math.cos(theta * Math.PI / 180f);
si = -(float) Math.sin(theta * Math.PI / 180f);
vertices[n * 3] = mRadius * (cRadius * co) + mCenterX;
vertices[n * 3 + 1] = mRadius * (cHeight) + mCenterY;
vertices[n * 3 + 2] = mRadius * (cRadius * si) + mCenterZ;
n ++;
}
}
return vertices;
}
public FloatBuffer createVerticesBuff() {
// create array
verArray = createVerticesArray();
// create buffer
if (vBuff == null) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verArray.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vBuff = byteBuffer.asFloatBuffer();
vBuff.put(verArray);
vBuff.flip();
}
return vBuff;
}
public short[] createIndexingArray() {
short[] indexies = new short[verArray.length*2];
int n=0;
for (int i = 0; i < stepsPai-1; i++) {
for (int j = 0; j < stepsTheta; j++) {
indexies[n] = (short) (i*stepsTheta+j);
indexies[n+1] = (short) ((i+1)*stepsTheta+j);
indexies[n+2] = (short) ((i+1)*stepsTheta+j+1);
indexies[n+3] = indexies[n+2];
indexies[n+4] = (short) (i*stepsTheta+j+1);
indexies[n+5] = indexies[n];
n+=6;
}
}
return indexies;
}
public void createIndexingBuffer(){
// create array
verIndex = createIndexingArray();
//create buffer
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verIndex.length * 2);
byteBuffer.order(ByteOrder.nativeOrder());
iBuff = byteBuffer.asShortBuffer();
iBuff.put(verIndex);
iBuff.flip();
}
public void draw() {
// setup vertices buffer
mGL.glEnableClientState(GL10.GL_VERTEX_ARRAY);
vBuff.position(0);
mGL.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuff);
// setup texture
if (texture != null) {
mGL.glEnable(GL10.GL_TEXTURE_2D);
mGL.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
tBuff.position(0);
mGL.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tBuff);
}
// display poligons on screen
mGL.glDrawElements(GL10.GL_TRIANGLES, verIndex.length, GL10.GL_UNSIGNED_SHORT, iBuff);
// reset settings
if (texture != null) {
mGL.glDisable(GL10.GL_TEXTURE_2D);
mGL.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
} else {
mGL.glColor4f(1, 1, 1, 1);
}
mGL.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
public void setTexture(Texture texture) {
if (this.texture != null) {
this.texture.dispose();
}
this.texture = texture;
// create array
texIndex = new float[stepsPai * stepsTheta * 2 * 2];
int n = 0;
for (float pai = 0f; pai < 180f; pai += step) {
for (float theta = 0.0f; theta <= 360f; theta += step) {
texIndex[n] = theta / 360f;
texIndex[n + 1] = pai / 180f;
n += 2;
}
}
// create buffer
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(texIndex.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
tBuff = byteBuffer.asFloatBuffer();
tBuff.put(texIndex);
tBuff.flip();
// bind texture
texture.bind();
}
}
&#34;世界&#34;类
package com.example.OpenGL_Testing.openGl;
import android.opengl.GLSurfaceView;
import android.support.v4.view.GestureDetectorCompat;
import android.view.MotionEvent;
import android.view.View;
import com.example.OpenGL_Testing.MyApp;
import com.example.OpenGL_Testing.MyGestureListener;
import com.example.OpenGL_Testing.Screen;
import com.example.OpenGL_Testing.openGl.geometry.Sphere;
import com.example.OpenGL_Testing.openGl.geometry.Sphere2;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by Aleksandr.Tsatski on 11.11.2014.
*/
public class WorldMap implements Screen {
GLSurfaceView glView;
static final int VERTEX_SIZE = (3) * 4;
Sphere sphere;
GL10 gl;
private GestureDetectorCompat mDetector;
final Object stateChanged = new Object();
public WorldMap(final GLSurfaceView glView, final GL10 gl) {
this.glView = glView;
this.gl = gl;
sphere = new Sphere(400, 0, 0, 0, gl);
}
private void setupGestureListener(final GLSurfaceView glView, final GL10 gl) {
final MyGestureListener listener = new MyGestureListener();
listener.setGestureFeedBackListener(new MyGestureListener.Feedback() {
@Override
public void onFeedback(final int event, final float parameter1, final float parameter2) {
glView.queueEvent(new Runnable() {
@Override
public void run() {
switch (event) {
case MyGestureListener.SCROLL:
gl.glRotatef(parameter1/10, 0f, 1f, 0f);
gl.glRotatef(-parameter2/10, 0f, 0f, 1f);
break;
default:
break;
}
}
});
}
});
glView.post(new Runnable() {
@Override
public void run() {
mDetector = new GestureDetectorCompat(MyApp.getAppContext(), listener);
}
});
glView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mDetector.onTouchEvent(motionEvent);
}
});
}
@Override
public void present(float deltaTime) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
sphere.draw();
}
@Override
public void resume() {
gl.glClearColor(1, 0, 0, 1);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
setupGestureListener(glView, gl);
sphere.setTexture(new Texture(gl, "world_map.png"));
}
@Override
public void pause() {
}
@Override
public void dispose() {
}
}