我正在尝试制作我的第一个应用程序。基于OpenGl,我试图绘制一个三角形,并且wHEN
运行应用程序。它只显示没有三角形的黑屏。
1 - 我不知道我的错误在哪里? 2 - 是否有任何好的书籍/教程适合初学者操作Android?
三角类:
public class Triangle {
private FloatBuffer vertxBuffer;
protected static byte indices[] = {
//Face definition:
0,1,3, //lower-right triangle of the face is drawn with vertices vertices[0]->vertices[1]->vertices[3] (->vertices[0])
0,3,2 //upper-right triangle of the face is drawn with vertices vertices[0]->vertices[3]->vertices[2] (->vertices[0])
};
public float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
public Triangle() {
// float has 4 bytes, so we allocate for each coordinate 4 bytes.
//what is the difference between ByteBuffer.allocateDirect AND ByteBuffer.allocate???
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
// allocate the memory from the byte buffer
vertxBuffer = vertexByteBuffer.asFloatBuffer();
//fill the vertex buffer with the vertices
vertxBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexByteBuffer.position(0);
}
protected static ByteBuffer indexBuffer;
static {
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
public void draw(GL10 gl) {
// Because we store the Triangle vertices " Coordinates " in a FloatBuffer
// we need to enable OpenGL to read from it.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//set the color for the Triangle (r, g, b, alpha) alpha is between 0-1
gl.glColor4f(2.0f, 1.0f, 0.0f, 0.5f);
// point to our vertex buffer to extract the vertices from it.
//(numberOfVertices, Which type of data the buffer Holds, offset, our Buffer containing the Vertices)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertxBuffer);
//draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3 );
gl.glDrawElements(gl.GL_TRIANGLES, indices.length, gl.GL_UNSIGNED_BYTE, indexBuffer);
//disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
GLRenderer类:
public class GLRenderer implements Renderer{
private Triangle triangle;
public GLRenderer() {
this.triangle = new Triangle();
}
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// clear screen and depth buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// reset the mode view matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f);
triangle.draw(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
if (height == 0) {
height = 1;
}
//Reset the current View Port
gl.glViewport(0, 0, width, height);
//Select the Projection Matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
// Reset the Projection Matrix
gl.glLoadIdentity();
// calculate the aspect ratio of the window
GLU.gluPerspective(gl, 45.0f, (float) width/(float) height, 0.1f , 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
gl.glClearColor(0, 0, 0, 1.0f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glDisable(GL10.GL_DITHER);
}
}
OpenGlRenderActivity类:
public class OpenGLRenderActivity extends Activity {
/** Called when the activity is first created. */
private GLSurfaceView gLSurfaceView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
gLSurfaceView = new GLSurfaceView(this);
gLSurfaceView.setRenderer(new GLRenderer());
setContentView(gLSurfaceView);
}
@Override
protected void onResume() {
super.onResume();
gLSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
gLSurfaceView.onPause();
}
}
答案 0 :(得分:4)
我认为你需要为你的顶点声明索引(为了组成直线和面):
protected static byte indices[] = {
//Face definition:
0,1,3, //lower-right triangle of the face is drawn with vertices vertices[0]->vertices[1]->vertices[3] (->vertices[0])
0,3,2 //upper-right triangle of the face is drawn with vertices vertices[0]->vertices[3]->vertices[2] (->vertices[0])
};
protected static ByteBuffer indexBuffer;
static {
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
然后将这些索引传递给您的绘图调用:
(替换
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3 );
带
gl.glDrawElements(GL.GL_TRIANGLES, indices.length, GL.GL_UNSIGNED_BYTE, indexBuffer)
;
)
至于教程,你在这里有很好的Android版Nehe教程:
http://insanitydesign.com/wp/projects/nehe-android-ports/
它的代码比文本解释更多,但它们让你开始变得非常慢,而且代码很好。实际上我认为最早的一个tutrials就像你在这里尝试一样绘制一个三角形。
答案 1 :(得分:2)
您的三角形被近剪裁平面剪裁。尝试将其移动到gluPerspective的近和远值之间的范围内。
答案 2 :(得分:1)
This android tutorial提到了vertexShader,fragmentShader和Program的要求。我可能错过了它,但我在代码中没有看到与此相关的任何内容。在我的例子中,隐形三角形的修复是在我的fragmentShader中修复一个类型o。