我一直在开发一个openGL ES 2.0 Android项目。我的目标是创建一个圆圈。从我从网上获得的帮助,我设法运行这个代码,假设在视图中给出一个圆圈,但我得到了一个椭圆形。我尝试了很多方法让它成为循环。任何帮助都要赞赏
由于
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import android.util.Log;
public class Circle {
private int mProgram, mPositionHandle, mColorHandle, mMVPMatrixHandle;
private FloatBuffer mVertexBuffer;
private float vertices[] = new float[364 * 3];
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
private final String vertexShaderCode = "uniform mat4 uMVPMatrix;"
+ "attribute vec4 vPosition;" + "void main() {"
+ " gl_Position = uMVPMatrix * vPosition;" + "}";
private final String fragmentShaderCode = "precision mediump float;"
+ "uniform vec4 vColor;" + "void main() {"
+ " gl_FragColor = vColor;" + "}";
Circle() {
vertices[0] = 0;
vertices[1] = 0;
vertices[2] = 0;
for (int i = 1; i < 364; i++) {
vertices[(i * 3) + 0] = (float) (0.5 * Math.cos((3.14 / 180)
* (float) i) + vertices[0]);
vertices[(i * 3) + 1] = (float) (0.5 * Math.sin((3.14 / 180)
* (float) i) + vertices[1]);
vertices[(i * 3) + 2] = 0;
}
Log.v("Thread", "" + vertices[0] + "," + vertices[1] + ","
+ vertices[2]);
ByteBuffer vertexByteBuffer = ByteBuffer
.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
mVertexBuffer = vertexByteBuffer.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader
// to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment
// shader to program
GLES20.glLinkProgram(mProgram);
}
public static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT,
false, 12, mVertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 364);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
我得到的输出就是这个
答案 0 :(得分:1)
顶点坐标跨越一个(标准化的)-1到+1的范围 - 看起来你正在生成从-0.5到+0.5的顶点。
现在,GL引擎在哪里绘制?到窗口系统提供的缓冲区 - 在这种情况下是Android窗口系统。 Android窗口系统(即最低级别的Linux内核显示驱动程序)提供了一个宽度x高度为480x640的缓冲区(屏幕截图显示宽度&lt; height)。因此,屏幕上绘制的圆圈宽度为0.5 * 480,但高度为0.5 * 640,因此呈椭圆形。
您必须按(屏幕宽度/屏幕高度)的比例缩小y坐标才能得到真正的圆。您可以在应用程序中使用egl API或Android API来获取它。