问题描述
我一直在努力的OpenGL ES 2.0的Android项目。我的目标是创建一个圆。从我从网上得到的帮助下,我成功地运行此code这是假设给视图中的圆形,而是我得到一个椭圆形。我试了很多办法,使其循环。任何帮助SHAL AP preciated
感谢
进口java.nio.ByteBuffer中;
进口java.nio.ByteOrder中;
进口java.nio.FloatBuffer中;进口android.opengl.GLES20;
进口android.util.Log;公共类圆{私人诠释mProgram,mPositionHandle,mColorHandle,mMVPMatrixHandle;
私人FloatBuffer mVertexBuffer;
私人浮动顶点[] =新的浮动[364 * 3]。
浮色[] = {0.63671875f,0.76953125f,0.22265625f,1.0F};私人最终字符串vertexShader code =统一mat4 uMVPMatrix;
+属性vec4 vPosition; +无效的主要(){
+= GL_POSITION * uMVPMatrix vPosition; +};私人最终字符串fragmentShader code =precision mediump浮动;
+统一vec4 vColor; +无效的主要(){
+gl_FragColor = vColor; +};圈(){
顶点[0] = 0;
顶点[1] = 0;
顶点[2] = 0; 的for(int i = 1; I< 364;我++){
顶点[(我* 3)+ 0] =(浮点)(0.5 * Math.cos((3.14 / 180)
*(浮点)ⅰ)+顶点[0]);
顶点[(我* 3)+ 1] =(浮点)(0.5 * Math.sin((3.14 / 180)
*(浮点)I)+顶点[1]);
顶点[(我* 3)+ 2] = 0;
} Log.v(螺纹,+顶点[0] +,+顶点[1] +,
+顶点[2]);
ByteBuffer的vertexByteBuffer =的ByteBuffer
.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
mVertexBuffer = vertexByteBuffer.asFloatBuffer();
mVertexBuffer.put(顶点);
mVertexBuffer.position(0);
INT vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShader code);
INT fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShader code); mProgram = GLES20.glCreateProgram(); //创建空的OpenGL ES程序
GLES20.glAttachShader(mProgram,vertexShader); //添加顶点着色器
//编程
GLES20.glAttachShader(mProgram,fragmentShader); //添加片段
//着色器程序
GLES20.glLinkProgram(mProgram);}公共静态INT loadShader(整型,字符串着色器code){ INT着色器= GLES20.glCreateShader(类型);
GLES20.glShaderSource(着色,着色器code);
GLES20.glCompileShader(着色器);
返回着色器;
}公共无效平局(浮动[] mvpMatrix){ GLES20.glUseProgram(mProgram); //获取处理到顶点着色器的vPosition成员
mPositionHandle = GLES20.glGetAttribLocation(mProgramvPosition); //启用的句柄三角形顶点
GLES20.glEnableVertexAttribArray(mPositionHandle); // prepare三角坐标数据
GLES20.glVertexAttribPointer(mPositionHandle,3,GLES20.GL_FLOAT,
假的,12,mVertexBuffer); //获取处理到片段着色器的vColor成员
mColorHandle = GLES20.glGetUniformLocation(mProgramvColor); //设置颜色绘制三角形
GLES20.glUniform4fv(mColorHandle,1,颜色,0); mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramuMVPMatrix); //应用投影和视图变换
GLES20.glUniformMatrix4fv(mMVPMatrixHandle,1,假,mvpMatrix,0); //绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN,0,364); //禁用顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);}}
和我得到的输出是这样的。
的顶点坐标跨越-1到+1(标准化)的范围 - 它似乎正在生成-0.5顶点至+0.5。
现在,哪里的GL发动机借鉴?到由一个窗口系统中提供的缓冲器 - 在这种情况下的Android窗口系统。而Android窗口系统(即在最低水平linux内核显示驱动程序)规定,有说480×640(你的屏幕截图显示宽度LT;高)宽x高的缓冲区。这样,在屏幕上描画圆具有0.5×480的宽度,但为0.5×640的高度,因此,它提供了一个椭圆形。
您将不得不缩减你Y上(屏幕宽度/ screenheight)的比例协调,才能得到真正的圆。您可以使用EGL API或Android API在应用程序中得到它。
I have been working on an openGL ES 2.0 Android project. My objective is to create a circle. From the help that i got from online, i managed to run this code which is suppose to give a circle in the view,but instead i got an oval. I tried many ways to make it circle. Any help shal appreciated
Thanks
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);
}
}
And the output i am getting is this
The vertex coordinates span a (normalised) range of -1 to +1 - And it appears you are generating vertices from -0.5 to +0.5.
Now, where does the GL engine draw ? To a buffer that is provided by a window system - in this case the Android window system. The Android window system (ie, the linux kernel display driver in the lowest level) provides a buffer that has a widthxheight of say 480x640 (your screenshot shows that width < height). So, the drawn circle on the screen has a width of 0.5*480, but height of 0.5*640, hence it gives an oval shape.
You will have to scale down your y coordinate by the ratio of (screenwidth/screenheight), to get a true circle. You can get it using either egl API or Android API in your application.
这篇关于我怎么能转换成一个椭圆绕openGL的ES2.0的Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!