简体   繁体   English

Android OpenGL ES 2.0-旋转到位

[英]Android OpenGL ES 2.0 - Rotation in place

I would like to rotate my triangles in Z axis, but I would to do it around the center of the triangle, not the center of the screen. 我想在Z轴上旋转三角形,但要绕三角形的中心而不是屏幕的中心。 I have researched a lot on that but didn't find any resolution. 我对此进行了大量研究,但未找到任何解决方案。

Any idea of what could I try to solve it? 有什么想法可以解决吗?

public class RendererClass implements Renderer {

FloatBuffer bufferObj1;
FloatBuffer bufferObj2;

int programObj1;
int programObj2;

int positionObj1;
int positionObj2;

int rotationMatrixLocationObj1;
int rotationMatrixLocationObj2;

int colorObj1;
int colorObj2;

float[] rotationMatrixObj1 = new float[16];
float[] rotationMatrixObj2 = new float[16];

@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig config) {

    GLES20.glClearColor(0.0f, 1.0f, 1.0f, 1.0f);    

    float[] vertexObj1 = {

            -0.8f, 0.8f,
            -0.8f, 0.0f,
             0.0f, 0.0f

    };

    float[] vertexObj2 = {

             0.8f, 0.8f,
             0.8f, 0.0f,
             0.0f, 0.0f

    };

    bufferObj1 = ByteBuffer.allocateDirect(vertexObj1.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexObj1);
    bufferObj2 = ByteBuffer.allocateDirect(vertexObj2.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexObj2);

    String vssObj1 = "attribute vec4 positionObj1;" +
                     "uniform mat4 rotationMatrixObj1;" +
                     "void main(){" +
                     "gl_Position = rotationMatrixObj1 * positionObj1;" +
                     "}";

    String vssObj2 = "attribute vec4 positionObj2;" +
                     "uniform mat4 rotationMatrixObj2;" +
                     "void main(){" +
                     "gl_Position = rotationMatrixObj2 * positionObj2;" +
                     "}";

    String fssObj1 = "precision mediump float;" +
                     "uniform vec4 colorObj1;" +
                     "void main(){" +
                     "gl_FragColor = colorObj1;" +
                     "}";

    String fssObj2 = "precision mediump float;" +
                     "uniform vec4 colorObj2;" +
                     "void main(){" +
                     "gl_FragColor = colorObj2;" +
                     "}";

    int vsObj1 = glCreateShader(GL_VERTEX_SHADER);
    int vsObj2 = glCreateShader(GL_VERTEX_SHADER);

    int fsObj1 = glCreateShader(GL_FRAGMENT_SHADER);
    int fsObj2 = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(vsObj1, vssObj1);
    glShaderSource(vsObj2, vssObj2);

    glShaderSource(fsObj1, fssObj1);
    glShaderSource(fsObj2, fssObj2);

    glCompileShader(vsObj1);
    glCompileShader(vsObj2);

    glCompileShader(fsObj1);
    glCompileShader(fsObj2);

    programObj1 = glCreateProgram();
    programObj2 = glCreateProgram();

    glAttachShader(programObj1, vsObj1);
    glAttachShader(programObj2, vsObj2);

    glAttachShader(programObj1, fsObj1);
    glAttachShader(programObj2, fsObj2);

    glLinkProgram(programObj1);
    glLinkProgram(programObj2);

    positionObj1 = glGetAttribLocation(programObj1, "positionObj1");
    positionObj2 = glGetAttribLocation(programObj2, "positionObj2");

    rotationMatrixLocationObj1 = glGetUniformLocation(programObj1, "rotationMatrixObj1");
    rotationMatrixLocationObj2 = glGetUniformLocation(programObj2, "rotationMatrixObj2");       

    colorObj1 = glGetUniformLocation(programObj1, "colorObj1");
    colorObj2 = glGetUniformLocation(programObj2, "colorObj2");     

}

@Override
public void onSurfaceChanged(GL10 arg0, int width, int height) {

    Matrix.setIdentityM(rotationMatrixObj1, 0);
    Matrix.rotateM(rotationMatrixObj1, 0, MainActivity.angle, 0, 0, 1);     

    Matrix.setIdentityM(rotationMatrixObj2, 0);
    Matrix.rotateM(rotationMatrixObj2, 0, MainActivity.angle, 0, 0, -1);

}

GL10 gl;

@Override
public void onDrawFrame(GL10 glUnused) {

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);     

    onSurfaceChanged(gl, 0, 0);

    glUseProgram(programObj1);
    bufferObj1.position(0);
    glVertexAttribPointer(positionObj1, 2, GL_FLOAT, false, 0, bufferObj1);
    glEnableVertexAttribArray(positionObj1);
    glUniform4f(colorObj1, 0.0f, 0.0f, 1.0f, 1.0f);
    glUniformMatrix4fv(rotationMatrixLocationObj1, 1, false, rotationMatrixObj1, 0);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glUseProgram(programObj2);
    bufferObj2.position(0);
    glVertexAttribPointer(positionObj2, 2, GL_FLOAT, false, 0, bufferObj2);
    glEnableVertexAttribArray(positionObj2);
    glUniform4f(colorObj2, 1.0f, 0.0f, 0.0f, 1.0f);
    glUniformMatrix4fv(rotationMatrixLocationObj2, 1, false, rotationMatrixObj2, 0);
    glDrawArrays(GL_TRIANGLES, 0, 3);

}   

}

You use glDrawArrays so you can alter your triangles in your code any way you want. 您可以使用glDrawArrays来更改代码中的三角形。 Use simple trigonometry to rotate your vertices independently. 使用简单的三角函数可独立旋转顶点。

Rotation matrix rotates vertices around center of coordinate system. 旋转矩阵使顶点绕坐标系的中心旋转。 If you want to rotate scene around some other point (x0, y0, z0) you have to do this in 3 simple steps: 如果要围绕其他点(x0,y0,z0)旋转场景,则必须通过3个简单步骤进行操作:

  1. translate scene in such way that your point will be in center of coord system (by -x0, -y0, -z0) 以这样的方式转换场景,使您的点位于坐标系的中心(通过-x0,-y0,-z0)
  2. rotate 旋转
  3. translate back (by x0, y0, z0) 向后翻译(按x0,y0,z0)

Of course 3 steps of transformation are not needed, matrix multiplication can do this work for us. 当然,不需要3个转换步骤,矩阵乘法可以为我们完成这项工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM