不能画正方形的OpenGL ES 2.0为Android,但可以绘制三角形 [英] Can't Draw Squares in OpenGL ES 2.0 for Android, but Can Draw Triangles

查看:287
本文介绍了不能画正方形的OpenGL ES 2.0为Android,但可以绘制三角形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我把code从 HTTP://www.learnopengles .COM / Android的教训 - 一个工具入门/ ,并一直在努力绘制一个正方形(同时仍保持在后台一切)。无论出于何种原因,它显示为一个三角形。我的code将在下面提供。我知道改变GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,4),但我不能找到我缺少什么。

此外,有没有更好的方式来了解如何在类GLES20中使用的功能呢? http://developer.android.com/reference/android/opengl/GLES20.html 做得很好,提供的参数,但没有解释每个参数的意义。

我会想象我的错误是在我的code的底部,可能是在功能drawSquare,但整个文件将被粘贴在这里的情况下,我错了。

 公共类LessonOneRenderer实现GLSurfaceView.Renderer
{/ **
 *存储模型矩阵。该矩阵用于从对象空间(其中每个模型可以被认为是移动的模型
 *被位于宇宙的中心),以世界空间。
 * /
私人浮动[] = mModelMatrix新的浮动[16];/ **
 *存储视图矩阵。这可以被认为是提供了照相机。此矩阵将世界空间眼空间;
 *它定位的东西相对于我们的眼睛。
 * /
私人浮动[] = mViewMatrix新的浮动[16];/ **储存投影矩阵。这是用来投射场景到2D视口。 * /
私人浮动[] = mProjectionMatrix新的浮动[16];/ **分配存储的最终结合的矩阵。这将被传递到着色器程序。 * /
私人浮动[] = mMVPMatrix新的浮动[16];/ **存放在float缓冲区我们的模型数据。 * /
私人最终FloatBuffer mTriangle1Vertices;
私人最终FloatBuffer mTriangle2Vertices;
私人最终FloatBuffer mTriangle3Vertices;私人最终FloatBuffer mSquare1Vertices;/ **这将用于在变换矩阵通过。 * /
私人诠释mMVPMatrixHandle;/ **这将被用于传递在模型位置信息。 * /
私人诠释mPositionHandle;/ **这将被用于传递在模型的颜色信息。 * /
私人诠释mColorHandle;/ **多少每浮动字节。 * /
私人最终诠释mBytesPerFloat = 4;/ **多少每个顶点的元素。 * /
私人最终诠释mStrideBytes = 7 * mBytesPerFloat;/ **偏移的位置数据。 * /
私人最终诠释mPositionOffset = 0;/ **中元素的位置数据的大小。 * /
私人最终诠释mPositionDataSize = 3;/ **偏移的颜色数据。 * /
私人最终诠释mColorOffset = 3;/ **中的元素的颜色数据的大小。 * /
私人最终诠释mColorDataSize = 4;/ **
 *初始化模型数据。
 * /
公共LessonOneRenderer()
{
    //定义点等边三角形。    //这个三角形是红色,绿色和蓝色。
    最终浮动[] = triangle1VerticesData {
            // X,Y,Z,
            // R,G,B,A
            -0.5f,-0.25f,0.0,
            1.0F,0.0,0.0,1.0F,            0.5F,-0.25f,0.0,
            0.0,0.0,1.0F,1.0F,            0.0,0.559016994f,0.0,
            0.0,1.0F,0.0,1.0F};    //这个三角形是黄色,青色和洋红色。
    最终浮动[] = triangle2VerticesData {
            // X,Y,Z,
            // R,G,B,A
            -0.5f,-0.25f,0.0,
            1.0F,1.0F,0.0,1.0F,            0.5F,-0.25f,0.0,
            0.0,1.0F,1.0F,1.0F,            0.0,0.559016994f,0.0,
            1.0F,0.0,1.0F,1.0F};    //这个三角形是白色,灰色和黑色。
    最终浮动[] = triangle3VerticesData {
            // X,Y,Z,
            // R,G,B,A
            -0.5f,-0.25f,0.0,
            1.0F,1.0F,1.0F,1.0F,            0.5F,-0.25f,0.0,
            0.5F,0.5F,0.5F,1.0F,            0.0,0.559016994f,0.0,
            0.0,0.0,0.0,1.0F};    最终浮动[] = square1VerticesData {
            //左上角
            -0.25f,0.25f,-.5f,
            1.0F,0.0,0.0,1.0F,
            //右上
            0.25f,0.25f,-.5f,
            0.0,1.0F,0.0,1.0F,
            //左下方
            -0.25f,-0.25f,-.5f,
            1.0F,0.0,0.0,1.0F,
            //权利
            0.25f,-0.25f,-.5f,
            1.0F,0.0,0.0,1.0F};    //初始化缓冲区。
    mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * mBytesPerFloat)
    。.order(ByteOrder.nativeOrder())asFloatBuffer();
    mTriangle2Vertices = ByteBuffer.allocateDirect(triangle2VerticesData.length * mBytesPerFloat)
    。.order(ByteOrder.nativeOrder())asFloatBuffer();
    mTriangle3Vertices = ByteBuffer.allocateDirect(triangle3VerticesData.length * mBytesPerFloat)
    。.order(ByteOrder.nativeOrder())asFloatBuffer();    mSquare1Vertices = ByteBuffer.allocateDirect(square1VerticesData.length * mBytesPerFloat)
    。.order(ByteOrder.nativeOrder())asFloatBuffer();    mTriangle1Vertices.put(triangle1VerticesData).POSITION(0);
    mTriangle2Vertices.put(triangle2VerticesData).POSITION(0);
    mTriangle3Vertices.put(triangle3VerticesData).POSITION(0);
    mSquare1Vertices.put(square1VerticesData).POSITION(0);
}@覆盖
公共无效onSurfaceCreated(GL10 glUnused,EGLConfig配置)
{
    //设置背景颜色清晰为灰色。
    GLES20.glClearColor(0.5F,0.5F,0.5F,0.5F);    //起源背后的眼睛位置。
    最终浮动eyeX = 0.0;
    最终浮动eyeY = 0.0;
    最终浮动EYEZ = 1.5F;    //我们正在朝远处
    最终浮动lookX = 0.0;
    最终浮动听我= 0.0;
    最终浮动lookZ = -5.0f;    //配置了载体。这是我们的头会被人指指点点是我们拿着相机。
    最终浮动UPX = 0.0;
    最终浮动upY = 1.0F;
    最终浮动UPZ = 0.0;    //设置视图矩阵。此矩阵可以说重新present相机位置。
    //注意:在OpenGL 1中,模型视图矩阵被使用,它是一种模式的组合,并且
    //视图矩阵。在OpenGL 2,我们可以,如果我们选择单独跟踪这些矩阵。
    Matrix.setLookAtM(mViewMatrix,0,eyeX,eyeY,EYEZ,lookX,听我说,lookZ,UPX,upY,UPZ);    最后弦乐vertexShader =
        统一mat4 u_MVPMatrix; \\ n//一个不断重新presenting组合模型/视图/投影矩阵。      +属性vec4 a_Position; \\ n//每个顶点的位置信息,我们将通过英寸
      +属性vec4 a_Color; \\ n//每个顶点的颜色信息,我们将通过英寸      +变vec4 v_Color; \\ n//这将传递到片段着色器。      +无效的主要()\\ n//的入口点我们的顶点着色器。
      +{\\ N
      +v_Color = a_Color; \\ n//通过对片段着色器传递的颜色。
                                                //它将穿过三角形内插。
      +GL_POSITION = u_MVPMatrix \\ N// GL_POSITION是用于存储最终位置的特殊变量。
      +* a_Position; \\ n//由矩阵乘法顶点得到最终点
      +} \\ n; //标准化屏幕坐标。    最后弦乐fragmentShader =
        precision mediump浮动; \\ n//设置默认的precision到中等。我们不需要高的
                                                //在片段着色器precision。
      +变vec4 v_Color; \\ n//这是来自全国各地的插值顶点着色器的颜色
                                                //每个片段三角形。
      +无效的主要()\\ n//的入口点我们的片段着色器。
      +{\\ N
      +gl_FragColor = v_Color; \\ n//直接通过管道传递的颜色。
      +} \\ n;    //加载顶点着色器。
    INT vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);    如果(vertexShaderHandle!= 0)
    {
        //传入着色器源代码。
        GLES20.glShaderSource(vertexShaderHandle,vertexShader);        //编译着色器。
        GLES20.glCompileShader(vertexShaderHandle);        //获取编辑状态。
        最终诠释[] = compileStatus新INT [1];
        GLES20.glGetShaderiv(vertexShaderHandle,GLES20.GL_COMPILE_STATUS,compileStatus,0);        //如果编译失败,删除着色器。
        如果(compileStatus [0] == 0)
        {
            GLES20.glDeleteShader(vertexShaderHandle);
            vertexShaderHandle = 0;
        }
    }    如果(vertexShaderHandle == 0)
    {
        抛出新的RuntimeException(错误创建顶点着色器。);
    }    //加载在片段着色器着色器。
    INT fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);    如果(fragmentShaderHandle!= 0)
    {
        //传入着色器源代码。
        GLES20.glShaderSource(fragmentShaderHandle,fragmentShader);        //编译着色器。
        GLES20.glCompileShader(fragmentShaderHandle);        //获取编辑状态。
        最终诠释[] = compileStatus新INT [1];
        GLES20.glGetShaderiv(fragmentShaderHandle,GLES20.GL_COMPILE_STATUS,compileStatus,0);        //如果编译失败,删除着色器。
        如果(compileStatus [0] == 0)
        {
            GLES20.glDeleteShader(fragmentShaderHandle);
            fragmentShaderHandle = 0;
        }
    }    如果(fragmentShaderHandle == 0)
    {
        抛出新的RuntimeException(错误创建片段着色器。);
    }    //创建程序对象和手柄存储到它。
    INT programHandle = GLES20.glCreateProgram();    如果(programHandle!= 0)
    {
        //绑定顶点着色程序。
        GLES20.glAttachShader(programHandle,vertexShaderHandle);        //绑定片段着色器程序。
        GLES20.glAttachShader(programHandle,fragmentShaderHandle);        //绑定属性
        GLES20.glBindAttribLocation(programHandle,0,a_Position);
        GLES20.glBindAttribLocation(programHandle,1,a_Color);        //两个着色器连接成一个程序。
        GLES20.glLinkProgram(programHandle);        //获取链路状态。
        最终诠释[] = linkStatus新INT [1];
        GLES20.glGetProgramiv(programHandle,GLES20.GL_LINK_STATUS,linkStatus,0);        //如果链接失败,删除的程序。
        如果(linkStatus [0] == 0)
        {
            GLES20.glDeleteProgram(programHandle);
            programHandle = 0;
        }
    }    如果(programHandle == 0)
    {
        抛出新的RuntimeException(错误创建程序。);
    }    //设置程序处理。这些将在以后被用来在值传递给该程序。
    mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandleu_MVPMatrix);
    mPositionHandle = GLES20.glGetAttribLocation(programHandlea_Position);
    mColorHandle = GLES20.glGetAttribLocation(programHandlea_Color);    //告诉OpenGL渲染时,使用该程序。
    GLES20.glUseProgram(programHandle);
}@覆盖
公共无效onSurfaceChanged(GL10 glUnused,诠释的宽度,高度INT)
{
    // OpenGL的视口设置为大小相同的表面上。
    GLES20.glViewport(0,0,宽度,高度);    //创建一个新的透视投影矩阵。高度将保持不变
    //而宽度将根据宽高比变化。
    最终浮动比率=(浮点)宽/高;
    最终浮动左= -ratio;
    最终浮动权=比;
    最终浮动底= -1.0F;
    最终浮顶= 1.0F;
    最终浮附近= 1.0F;
    最终浮动远= 10.0f;    Matrix.frustumM(mProjectionMatrix,0,左,右,底,顶,近,远);
}@覆盖
公共无效onDrawFrame(GL10 glUnused)
{
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);    //做一个完整的旋转,每10秒。
    很长一段时间= SystemClock.uptimeMillis()%10000L;
    浮动angleInDegrees =(360.0f / 10000.0f)*((int)的时间);    //绘制直线面临的三角形。
    Matrix.setIdentityM(mModelMatrix,0);
    Matrix.rotateM(mModelMatrix,0,angleInDegrees,0.0,0.0,1.0F);
    drawTriangle(mTriangle1Vertices);    //绘制一个经翻译有点下来,旋转,平放在地面上。
    Matrix.setIdentityM(mModelMatrix,0);
    Matrix.translateM(mModelMatrix,0,0.0,-1.0F,0.0);
    Matrix.rotateM(mModelMatrix,0,90.0f,1.0F,0.0,0.0);
    Matrix.rotateM(mModelMatrix,0,angleInDegrees,0.0,0.0,1.0F);
    drawTriangle(mTriangle2Vertices);    //绘制一个经翻译一个位向右并旋转以面向左侧。
    Matrix.setIdentityM(mModelMatrix,0);
    Matrix.translateM(mModelMatrix,0,1.0F,0.0,0.0);
    Matrix.rotateM(mModelMatrix,0,90.0f,0.0,1.0F,0.0);
    Matrix.rotateM(mModelMatrix,0,angleInDegrees,0.0,0.0,1.0F);
    drawTriangle(mTriangle3Vertices);    //绘制方形面临海峡
    浮smallerAngle = -angleInDegrees;
    Matrix.setIdentityM(mModelMatrix,0);
    Matrix.translateM(mModelMatrix,0,0,0,0.0);
    Matrix.rotateM(mModelMatrix,0,smallerAngle,0.0,0.0,1.0F);
    drawSquare(mSquare1Vertices);
}/ **
 *绘制从给定的顶点数据的三角形。
 *
 * @参数aTriangleBuffer包含顶点数据的缓冲区。
 * /
私人无效drawTriangle(最终FloatBuffer aTriangleBuffer)
{
    //在位置信息传递
    aTriangleBuffer.position(mPositionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle,mPositionDataSize,GLES20.GL_FLOAT,假的,
            mStrideBytes,aTriangleBuffer);    GLES20.glEnableVertexAttribArray(mPositionHandle);    //在颜色信息传递
    aTriangleBuffer.position(mColorOffset);
    GLES20.glVertexAttribPointer(mColorHandle,mColorDataSize,GLES20.GL_FLOAT,假的,
            mStrideBytes,aTriangleBuffer);    GLES20.glEnableVertexAttribArray(mColorHandle);    //这个乘以模型矩阵视图矩阵,并将结果保存在MVP矩阵
    //(目前包含型号*视图)。
    Matrix.multiplyMM(mMVPMatrix,0,mViewMatrix,0,mModelMatrix,0);    //这个乘以投影矩阵模型视图矩阵,并将结果保存在MVP矩阵
    //(现在包含模型*查看*投影)。
    Matrix.multiplyMM(mMVPMatrix,0,mProjectionMatrix,0,mMVPMatrix,0);    GLES20.glUniformMatrix4fv(mMVPMatrixHandle,1,假,mMVPMatrix,0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
}私人无效drawSquare(最终FloatBuffer aSquareBuffer){
    //在位置信息传递
    aSquareBuffer.position(mPositionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle,mPositionDataSize,GLES20.GL_FLOAT,假的,
            mStrideBytes,aSquareBuffer);    GLES20.glEnableVertexAttribArray(mPositionHandle);    //在颜色信息传递
    aSquareBuffer.position(mColorOffset);
    GLES20.glVertexAttribPointer(mColorHandle,mColorDataSize,GLES20.GL_FLOAT,假的,
            mStrideBytes,aSquareBuffer);    GLES20.glEnableVertexAttribArray(mColorHandle);    //这个乘以模型矩阵视图矩阵,并将结果保存在MVP矩阵
    //(目前包含型号*视图)。
    Matrix.multiplyMM(mMVPMatrix,0,mViewMatrix,0,mModelMatrix,0);    //这个乘以投影矩阵模型视图矩阵,并将结果保存在MVP矩阵
    //(现在包含模型*查看*投影)。
    Matrix.multiplyMM(mMVPMatrix,0,mProjectionMatrix,0,mMVPMatrix,0);    GLES20.glUniformMatrix4fv(mMVPMatrixHandle,1,假,mMVPMatrix,0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,4);
}
}


解决方案

我假设你是很新的OpenGL ES 2.0的编程。所以,你开始3.D-变换矩阵玩耍(如,建模,可视,或投影)之前,请先尝试这个基本的例子(渲染矩形) -

 公共类GLES20Renderer实现渲染{
    私人诠释_rectangleProgram;
    私人诠释_rectangleAPositionLocation;
    私人FloatBuffer _rectangleVFB;    公共无效onSurfaceCreated(GL10 GL,EGLConfig配置){
        gl.glClearColor(0.0,0.0,0.0,1);
        initShapes();
        INT _rectangleVertexShader = loadShader(GLES20.GL_VERTEX_SHADER,_rectangleVertexShader code);
        INT _rectangleFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,_rectangleFragmentShader code);
        _rectangleProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(_rectangleProgram,_rectangleVertexShader);
        GLES20.glAttachShader(_rectangleProgram,_rectangleFragmentShader);
        GLES20.glLinkProgram(_rectangleProgram);
        _rectangleAPositionLocation = GLES20.glGetAttribLocation(_rectangleProgram。负责);
    }    公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
        gl.glViewport(0,0,宽度,高度);
    }    公共无效onDrawFrame(GL10 GL){
        gl.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);        GLES20.glUseProgram(_rectangleProgram);
        GLES20.glVertexAttribPointer(_rectangleAPositionLocation,3,GLES20.GL_FLOAT,假的,12,_rectangleVFB);
        GLES20.glEnableVertexAttribArray(_rectangleAPositionLocation);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,6);
    }    私人无效initShapes(){
        浮rectangleVFA [] = {
                    0,0,0,
                    0,0.5F,0,
                    0.75f​​,0.5F,0,
                    0.75f​​,0.5F,0,
                    0.75f​​,0,0,
                    0,0,0,
                };
        ByteBuffer的rectangleVBB = ByteBuffer.allocateDirect(rectangleVFA.length * 4);
        rectangleVBB.order(ByteOrder.nativeOrder());
        _rectangleVFB = rectangleVBB.asFloatBuffer();
        _rectangleVFB.put(rectangleVFA);
        _rectangleVFB.position(0);
    }    私人最终字符串_rectangleVertexShader code =
            属性vec4。负责; \\ n
        +无效的主要(){\\ n
        += GL_POSITION。负责; \\ n
        +} \\ n;    私人最终字符串_rectangleFragmentShader code =
            无效的主要(){\\ n
        +gl_FragColor = vec4(1,1,1,1); \\ n
        +} \\ n;    私人诠释loadShader(整型,字符串源){
        INT着色器= GLES20.glCreateShader(类型);
        GLES20.glShaderSource(着色器,源);
        GLES20.glCompileShader(着色器);
        返回着色器;
    }}

更多,它们中的 -
HTTP://www.a$p$pss.com/9781430250531

So i took code from http://www.learnopengles.com/android-lesson-one-getting-started/ and have been trying to draw a square (while still keeping everything else in the background). For whatever reason, it shows up as a triangle. My code will be provided below. I knew to change GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 4), but I can't find out what else I'm missing.

Furthermore, is there a better way to find out how to use functions within the class GLES20? http://developer.android.com/reference/android/opengl/GLES20.html does a good job providing parameters, but doesn't explain what each parameter does.

I would imagine my error is at the bottom of my code, probably in the function drawSquare, but the entire file will be pasted here in case I'm mistaken.

public class LessonOneRenderer implements GLSurfaceView.Renderer 
{/**
 * Store the model matrix. This matrix is used to move models from object space (where each model can be thought
 * of being located at the center of the universe) to world space.
 */
private float[] mModelMatrix = new float[16];

/**
 * Store the view matrix. This can be thought of as our camera. This matrix transforms world space to eye space;
 * it positions things relative to our eye.
 */
private float[] mViewMatrix = new float[16];

/** Store the projection matrix. This is used to project the scene onto a 2D viewport. */
private float[] mProjectionMatrix = new float[16];

/** Allocate storage for the final combined matrix. This will be passed into the shader program. */
private float[] mMVPMatrix = new float[16];

/** Store our model data in a float buffer. */
private final FloatBuffer mTriangle1Vertices;
private final FloatBuffer mTriangle2Vertices;
private final FloatBuffer mTriangle3Vertices;

private final FloatBuffer mSquare1Vertices;

/** This will be used to pass in the transformation matrix. */
private int mMVPMatrixHandle;

/** This will be used to pass in model position information. */
private int mPositionHandle;

/** This will be used to pass in model color information. */
private int mColorHandle;

/** How many bytes per float. */
private final int mBytesPerFloat = 4;

/** How many elements per vertex. */
private final int mStrideBytes = 7 * mBytesPerFloat;    

/** Offset of the position data. */
private final int mPositionOffset = 0;

/** Size of the position data in elements. */
private final int mPositionDataSize = 3;    

/** Offset of the color data. */
private final int mColorOffset = 3;

/** Size of the color data in elements. */
private final int mColorDataSize = 4;       

/**
 * Initialize the model data.
 */
public LessonOneRenderer()
{   
    // Define points for equilateral triangles.

    // This triangle is red, green, and blue.
    final float[] triangle1VerticesData = {
            // X, Y, Z, 
            // R, G, B, A
            -0.5f, -0.25f, 0.0f, 
            1.0f, 0.0f, 0.0f, 1.0f,

            0.5f, -0.25f, 0.0f,
            0.0f, 0.0f, 1.0f, 1.0f,

            0.0f, 0.559016994f, 0.0f, 
            0.0f, 1.0f, 0.0f, 1.0f};

    // This triangle is yellow, cyan, and magenta.
    final float[] triangle2VerticesData = {
            // X, Y, Z, 
            // R, G, B, A
            -0.5f, -0.25f, 0.0f, 
            1.0f, 1.0f, 0.0f, 1.0f,

            0.5f, -0.25f, 0.0f, 
            0.0f, 1.0f, 1.0f, 1.0f,

            0.0f, 0.559016994f, 0.0f, 
            1.0f, 0.0f, 1.0f, 1.0f};

    // This triangle is white, gray, and black.
    final float[] triangle3VerticesData = {
            // X, Y, Z, 
            // R, G, B, A
            -0.5f, -0.25f, 0.0f, 
            1.0f, 1.0f, 1.0f, 1.0f,

            0.5f, -0.25f, 0.0f, 
            0.5f, 0.5f, 0.5f, 1.0f,

            0.0f, 0.559016994f, 0.0f, 
            0.0f, 0.0f, 0.0f, 1.0f};

    final float[] square1VerticesData = {
            //topleft
            -0.25f, 0.25f, -.5f,
            1.0f, 0.0f, 0.0f, 1.0f,
            //top right
            0.25f,0.25f, -.5f,
            0.0f, 1.0f, 0.0f, 1.0f,
            //bottom left
            -0.25f, -0.25f, -.5f,
            1.0f, 0.0f, 0.0f, 1.0f,
            //right
            0.25f, -0.25f, -.5f,
            1.0f, 0.0f, 0.0f, 1.0f};



    // Initialize the buffers.
    mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mTriangle2Vertices = ByteBuffer.allocateDirect(triangle2VerticesData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mTriangle3Vertices = ByteBuffer.allocateDirect(triangle3VerticesData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();

    mSquare1Vertices = ByteBuffer.allocateDirect(square1VerticesData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();

    mTriangle1Vertices.put(triangle1VerticesData).position(0);
    mTriangle2Vertices.put(triangle2VerticesData).position(0);
    mTriangle3Vertices.put(triangle3VerticesData).position(0);
    mSquare1Vertices.put(square1VerticesData).position(0);
}

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
{
    // Set the background clear color to gray.
    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);

    // Position the eye behind the origin.
    final float eyeX = 0.0f;
    final float eyeY = 0.0f;
    final float eyeZ = 1.5f;

    // We are looking toward the distance
    final float lookX = 0.0f;
    final float lookY = 0.0f;
    final float lookZ = -5.0f;

    // Set our up vector. This is where our head would be pointing were we holding the camera.
    final float upX = 0.0f;
    final float upY = 1.0f;
    final float upZ = 0.0f;

    // Set the view matrix. This matrix can be said to represent the camera position.
    // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
    // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
    Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);

    final String vertexShader =
        "uniform mat4 u_MVPMatrix;      \n"     // A constant representing the combined model/view/projection matrix.

      + "attribute vec4 a_Position;     \n"     // Per-vertex position information we will pass in.
      + "attribute vec4 a_Color;        \n"     // Per-vertex color information we will pass in.              

      + "varying vec4 v_Color;          \n"     // This will be passed into the fragment shader.

      + "void main()                    \n"     // The entry point for our vertex shader.
      + "{                              \n"
      + "   v_Color = a_Color;          \n"     // Pass the color through to the fragment shader. 
                                                // It will be interpolated across the triangle.
      + "   gl_Position = u_MVPMatrix   \n"     // gl_Position is a special variable used to store the final position.
      + "               * a_Position;   \n"     // Multiply the vertex by the matrix to get the final point in                                                                   
      + "}                              \n";    // normalized screen coordinates.

    final String fragmentShader =
        "precision mediump float;       \n"     // Set the default precision to medium. We don't need as high of a 
                                                // precision in the fragment shader.                
      + "varying vec4 v_Color;          \n"     // This is the color from the vertex shader interpolated across the 
                                                // triangle per fragment.             
      + "void main()                    \n"     // The entry point for our fragment shader.
      + "{                              \n"
      + "   gl_FragColor = v_Color;     \n"     // Pass the color directly through the pipeline.          
      + "}                              \n";                                                

    // Load in the vertex shader.
    int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

    if (vertexShaderHandle != 0) 
    {
        // Pass in the shader source.
        GLES20.glShaderSource(vertexShaderHandle, vertexShader);

        // Compile the shader.
        GLES20.glCompileShader(vertexShaderHandle);

        // Get the compilation status.
        final int[] compileStatus = new int[1];
        GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

        // If the compilation failed, delete the shader.
        if (compileStatus[0] == 0) 
        {               
            GLES20.glDeleteShader(vertexShaderHandle);
            vertexShaderHandle = 0;
        }
    }

    if (vertexShaderHandle == 0)
    {
        throw new RuntimeException("Error creating vertex shader.");
    }

    // Load in the fragment shader shader.
    int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

    if (fragmentShaderHandle != 0) 
    {
        // Pass in the shader source.
        GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);

        // Compile the shader.
        GLES20.glCompileShader(fragmentShaderHandle);

        // Get the compilation status.
        final int[] compileStatus = new int[1];
        GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

        // If the compilation failed, delete the shader.
        if (compileStatus[0] == 0) 
        {               
            GLES20.glDeleteShader(fragmentShaderHandle);
            fragmentShaderHandle = 0;
        }
    }

    if (fragmentShaderHandle == 0)
    {
        throw new RuntimeException("Error creating fragment shader.");
    }

    // Create a program object and store the handle to it.
    int programHandle = GLES20.glCreateProgram();

    if (programHandle != 0) 
    {
        // Bind the vertex shader to the program.
        GLES20.glAttachShader(programHandle, vertexShaderHandle);           

        // Bind the fragment shader to the program.
        GLES20.glAttachShader(programHandle, fragmentShaderHandle);

        // Bind attributes
        GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
        GLES20.glBindAttribLocation(programHandle, 1, "a_Color");

        // Link the two shaders together into a program.
        GLES20.glLinkProgram(programHandle);

        // Get the link status.
        final int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);

        // If the link failed, delete the program.
        if (linkStatus[0] == 0) 
        {               
            GLES20.glDeleteProgram(programHandle);
            programHandle = 0;
        }
    }

    if (programHandle == 0)
    {
        throw new RuntimeException("Error creating program.");
    }

    // Set program handles. These will later be used to pass in values to the program.
    mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");        
    mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
    mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");        

    // Tell OpenGL to use this program when rendering.
    GLES20.glUseProgram(programHandle);        
}   

@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) 
{
    // Set the OpenGL viewport to the same size as the surface.
    GLES20.glViewport(0, 0, width, height);

    // Create a new perspective projection matrix. The height will stay the same
    // while the width will vary as per aspect ratio.
    final float ratio = (float) width / height;
    final float left = -ratio;
    final float right = ratio;
    final float bottom = -1.0f;
    final float top = 1.0f;
    final float near = 1.0f;
    final float far = 10.0f;

    Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
}   

@Override
public void onDrawFrame(GL10 glUnused) 
{
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);                    

    // Do a complete rotation every 10 seconds.
    long time = SystemClock.uptimeMillis() % 10000L;
    float angleInDegrees = (360.0f / 10000.0f) * ((int) time);

    // Draw the triangle facing straight on.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
    drawTriangle(mTriangle1Vertices);

    // Draw one translated a bit down and rotated to be flat on the ground.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 0.0f, -1.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, 90.0f, 1.0f, 0.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
    drawTriangle(mTriangle2Vertices);

    // Draw one translated a bit to the right and rotated to be facing to the left.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 1.0f, 0.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, 90.0f, 0.0f, 1.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
    drawTriangle(mTriangle3Vertices);

    // Draw square facing strait on
    float smallerAngle =  -angleInDegrees;
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 0, 0, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, smallerAngle, 0.0f, 0.0f, 1.0f);        
    drawSquare(mSquare1Vertices);
}   

/**
 * Draws a triangle from the given vertex data.
 * 
 * @param aTriangleBuffer The buffer containing the vertex data.
 */
private void drawTriangle(final FloatBuffer aTriangleBuffer)
{       
    // Pass in the position information
    aTriangleBuffer.position(mPositionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aTriangleBuffer);        

    GLES20.glEnableVertexAttribArray(mPositionHandle);        

    // Pass in the color information
    aTriangleBuffer.position(mColorOffset);
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aTriangleBuffer);        

    GLES20.glEnableVertexAttribArray(mColorHandle);

    // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
    // (which currently contains model * view).
    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
    // (which now contains model * view * projection).
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);                               
}

private void drawSquare(final FloatBuffer aSquareBuffer) {
    // Pass in the position information
    aSquareBuffer.position(mPositionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aSquareBuffer);        

    GLES20.glEnableVertexAttribArray(mPositionHandle);        

    // Pass in the color information
    aSquareBuffer.position(mColorOffset);
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aSquareBuffer);        

    GLES20.glEnableVertexAttribArray(mColorHandle);

    // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
    // (which currently contains model * view).
    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
    // (which now contains model * view * projection).
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 4);                             
}
}

解决方案

I'm assuming that you are very new to OpenGL ES 2.0 programming. So, before you start playing around with 3.D-transformation matrices (such as, for modeling, viewing, or projection) please try this basic example first (to render a rectangle) -

public class GLES20Renderer implements Renderer {
    private int _rectangleProgram;
    private int _rectangleAPositionLocation;
    private FloatBuffer _rectangleVFB;

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1);
        initShapes();
        int _rectangleVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, _rectangleVertexShaderCode);
        int _rectangleFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, _rectangleFragmentShaderCode);
        _rectangleProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(_rectangleProgram, _rectangleVertexShader);
        GLES20.glAttachShader(_rectangleProgram, _rectangleFragmentShader);
        GLES20.glLinkProgram(_rectangleProgram);
        _rectangleAPositionLocation = GLES20.glGetAttribLocation(_rectangleProgram, "aPosition");
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        GLES20.glUseProgram(_rectangleProgram);
        GLES20.glVertexAttribPointer(_rectangleAPositionLocation, 3, GLES20.GL_FLOAT, false, 12, _rectangleVFB);
        GLES20.glEnableVertexAttribArray(_rectangleAPositionLocation);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
    }

    private void initShapes()  {
        float rectangleVFA[] = {
                    0,      0,      0,
                    0,      0.5f,   0,
                    0.75f,  0.5f,   0,
                    0.75f,  0.5f,   0,
                    0.75f,  0,      0,
                    0,      0,      0,
                };
        ByteBuffer rectangleVBB = ByteBuffer.allocateDirect(rectangleVFA.length * 4);
        rectangleVBB.order(ByteOrder.nativeOrder());
        _rectangleVFB = rectangleVBB.asFloatBuffer();
        _rectangleVFB.put(rectangleVFA);
        _rectangleVFB.position(0);
    }

    private final String _rectangleVertexShaderCode = 
            "attribute vec4 aPosition;              \n"
        +   "void main() {                          \n"
        +   " gl_Position = aPosition;              \n"
        +   "}                                      \n";

    private final String _rectangleFragmentShaderCode = 
            "void main() {                          \n"
        +   " gl_FragColor = vec4(1,1,1,1);         \n"
        +   "}                                      \n";

    private int loadShader(int type, String source)  {
        int shader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(shader, source);
        GLES20.glCompileShader(shader);
        return shader;
    }

}

More of these at - http://www.apress.com/9781430250531

这篇关于不能画正方形的OpenGL ES 2.0为Android,但可以绘制三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆