[英]Center rectangle-object in the screen by using glOrthof in Android with opengles 2, with java
I'm working on the examples of the book OpenGlEs 2 for Android. I did the first example, for drawing a rectangle of base 9, and height 14, by using the below array for defining the coordinates我正在为 Android 编写 OpenGlEs 2 一书的示例。我做了第一个示例,通过使用下面的数组定义坐标来绘制底数为 9、高度为 14 的矩形
private float[] tableVerticesWithTriangles = {
//Triangle
0f, 0f,
9f, 14f,
0f, 14f,
//Triangle 2
0f, 0f,
9f, 0f,
9f, 14f
};
The rectangle is appearing as in the example, the white rectangle in the top right corner:矩形出现在示例中,右上角的白色矩形:
The code I'm working on is in the repository https://github.com/quimperval/opengles-android-rectangle我正在处理的代码位于存储库https://github.com/quimperval/opengles-android-rectangle
Now in the book the author centers the rectangle by modifying the coordinates of the rectangle, however as far as I know, openGl can take care of that by using a projection matrix.现在在书中,作者通过修改矩形的坐标使矩形居中,但据我所知,openGl 可以通过使用投影矩阵来解决这个问题。 So, I modified the vertex shader for using a projection Matrix所以,我修改了顶点着色器以使用投影矩阵
attribute vec4 a_Position;
attribute mat4 u_Projection;
void main(){
gl_Position = u_Projection * a_Position;
}
And in the CRenderer class I added the below variables在 CRenderer class 中,我添加了以下变量
private static final String U_PROJECTION = "u_Projection";
int projectionMatrixLocation;
and the和
float[] projectionMatrix = new float[16];
And in the onSurfaceChanged method I added the logic for considering the aspectRatio在 onSurfaceChanged 方法中,我添加了考虑 aspectRatio 的逻辑
@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
glViewport(0, 0, width, height);
// Calculate the projection matrix
float aspectRatio = width > height ?
(float) width / (float) height :
(float) height / (float) width;
if (width > height) {
// Landscape
glOrthof(-aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
} else {
// Portrait or square
glOrthof(-1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
}
projectionMatrixLocation = glGetUniformLocation(program, "u_Projection");
glUniformMatrix4fv(projectionMatrixLocation, 1, false, projectionMatrix, 0);
}
In the onDrawFrame I didn't do changes.在 onDrawFrame 中我没有做任何改变。
When I compile and install the application in the emulator, It crashes, with the error:当我在模拟器中编译和安装应用程序时,它崩溃了,并出现错误:
2022-12-31 14:45:23.971 10499-10521/com.perval.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 10521 (GLThread 411) 2022-12-31 14:45:23.971 10499-10521/com.perval.myapplication A/libc:致命信号 11 (SIGSEGV),代码 1,tid 10521 (GLThread 411) 中的故障地址 0x0
Am I missing some operation?我错过了一些操作吗?
I expect to center the rectangle (of any dimensions) in the screen of the device.我希望将矩形(任意尺寸)置于设备屏幕的中心。
I believe the answer is that you are:我相信答案是你是:
glGetUniformLocation()
不检查glGetUniformLocation()
的响应As you are accessing a uniform with glGetUniformLocation
, you should declare it in your shader like so:当您使用glGetUniformLocation
访问制服时,您应该在着色器中声明它,如下所示:
uniform mat4 u_Projection;
I manage to find another way to achive the result I need, by using the below code in the onSurfaceChangedMethod通过在 onSurfaceChangedMethod 中使用以下代码,我设法找到另一种方法来实现我需要的结果
@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
glViewport(0,0, width, height);
/*orthoM
*projectionMarix - float[] m - the destination array
* mOffset - the offset in to m which the result is written
* float left - the minimum range of the x-axis
* float right - the maximum range of the x-axis
* float bottom - the minimum range of the y-axis
* float top - the maximum range ot the y-axis
* float near - the minimum range of the z-axis
* float far - the maximum range of the z-axis
*
*/
float boundingBoxWidth = 300;
float boundingBoxHeight = 300;
float aspectRatio;
if(width>height){
//Landscape
aspectRatio = (float) width / (float) height;
orthoM(projectionMatrix, 0, -aspectRatio*boundingBoxHeight, aspectRatio*boundingBoxHeight, -boundingBoxHeight, boundingBoxHeight, -1f, 1f);
} else {
//Portrait or square
aspectRatio = (float) height / (float) width;
orthoM(projectionMatrix, 0, -boundingBoxWidth, boundingBoxWidth, -boundingBoxWidth*aspectRatio, boundingBoxWidth*aspectRatio, -1f, 1f);
}
}
In that way I got the behaviour I wanted, place an object in the center of the screen, and the object has vertex coordinates outside of the surface extents (-1,-1) to (1,1).这样我得到了我想要的行为,在屏幕中央放置一个 object,object 的顶点坐标在表面范围 (-1,-1) 到 (1,1) 之外。
The key is to know the width and the height of the collision box of the object I want to draw, then it is just a matter of scaling the left, right or bottom/top variables based on the orientation of the screen, with the aspectRatio variable.关键是要知道我要绘制的 object 的碰撞框的宽度和高度,然后只需根据屏幕的方向缩放左、右或底部/顶部变量,使用 aspectRatio多变的。 I placed the code in the repository:我将代码放在存储库中:
https://github.com/quimperval/opengl-es-android-draw-object https://github.com/quimperval/opengl-es-android-draw-object
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.