所以我已经多次浏览了android教程,并且我经历了大量的研究和测试以及试用,但我仍然无法按照我想要的方式控制绘制形状被绘制。我决定启动另一个新的openGL项目,它是android教程的完全复制和粘贴项目,但是当谈到投影和摄像机视图时,我遇到了一个问题。我理解以下代码的工作原理:
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -3, 3, 2, 10);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
而且我知道改变这三种方法中的一种基本上应该以某种方式改变形状的方向。所以,我开始玩这些值,尽我所能,但三角形的图像保持完全相同。所以我研究了更多,并且发现着色器代码在教程中是错误的,应该看起来更像(添加了uMVPMatrix):
private final String vertexShaderCode =
"attribute vec4 vPosition;" +"attribute vec4 uMVPMatrix;"+
"void main() {" +
" gl_Position =vPosition*uMVPMatrix;" +
"}";
所以,我应用了uMVPMatrix,现在三角形已经消失了。所以,我做了更多的研究,并发现大多数人都做了uMVPMatrix * vPosition,所以我也这样做了,三角形仍然没有了。我想知道为什么我的投影和相机视图也没有像我期望的那样工作,我也希望有一段代码完全像预期的那样。安卓教程,这样我就可以有一个示例代码,也可以一直参考。
这是我的代码:
public class MainActivity extends Activity {
private GLSurfaceView mGLView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new MyGLSurfaceView(this);
setContentView(mGLView);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
// --------------------- Open Gl Code --------------------- ----------------------------------------------
class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context){
super(context);
setEGLContextClientVersion(2);
setRenderer(new MyGLRenderer());
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
Triangle mTriangle;
float [] mViewMatrix=new float[16];
float [] mMVPMatrix=new float[16];
float [] mProjectionMatrix=new float[16];
float [] mViewMatrix2=new float[16];
float [] mMVPMatrix2=new float[16];
public class MyGLRenderer implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mTriangle = new Triangle();
}
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
mTriangle.draw(mMVPMatrix);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -3, 3, 2, 7);
}
}
////////////////////Triangle//////////////////////////////////////////////////////
public class Triangle {
private FloatBuffer vertexBuffer, colorBuff;
static final int COORDS_PER_VERTEX = 3;
float triangleCoords[] = { // in counterclockwise order:
0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right
};
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f};
int mProgram;
public Triangle() {
ByteBuffer bb = ByteBuffer.allocateDirect(
triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.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); // creates OpenGL ES program executables
}
private final String vertexShaderCode =
"attribute vec4 vPosition;" +"attribute vec4 uMVPMatrix;"+
"void main() {" +
" gl_Position =vPosition*uMVPMatrix;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
public int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
static final int vertexStride = COORDS_PER_VERTEX * 4;
static final int vertexCount = 3;
public void draw(float [] mvpMatrix) {
GLES20.glUseProgram(mProgram);
int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
}
答案 0 :(得分:0)
在着色器中声明uMVPMatrix
的方式与其使用方式不符。您将其声明为vec4
属性,同时将其设置为矩阵均匀。所以顶点着色器中的声明应该是:
uniform mat4 uMVPMatrix;
这取决于你的矩阵是如何设置的,但是在GLSL着色器中从左边乘以你的向量也有点不寻常。我没有在Android中使用矩阵实用程序函数,但是从文档中我怀疑你需要将右边的向量相乘:
gl_Position = uMVPMatrix * vPosition;