来自 gluUnProject 的 IllegalArgumentException
我收到此错误消息
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): FATAL EXCEPTION: GLThread 9
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): java.lang.IllegalArgumentException: length - offset < n
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.Matrix.multiplyMV(Native Method)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.GLU.gluUnProject(GLU.java:237)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.app.ui.GLSurfaceRenderer.vector3(GLSurfaceRenderer.java:70)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.app.ui.GLSurfaceRenderer.onDrawFrame(GLSurfaceRenderer.java:103)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1332)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
使用以下代码:
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.util.*;
public class GLSurfaceRenderer implements Renderer{
public static float setx, sety;
private static float posx, posy, posz = 100;
private double speed;
private static float rotation;
private static float statrotation;
public static boolean isPressed;
private static FlatColoredSquare square;
private static FlatColoredSquare statSquare;
public final static String TAG = "input";
public GLSurfaceRenderer () {
square = new FlatColoredSquare();
statSquare = new FlatColoredSquare();
rotation = (float) Math.floor(Math.random()*361);
speed = 0.1;
}
public void vector3 (GL11 gl){
int[] viewport = new int[4];
float[] modelview = new float[16];
float[] projection = new float[16];
float winx, winy, winz;
float[] newcoords = new float[3];
gl.glGetIntegerv(GL11.GL_VIEWPORT, viewport, 0);
((GL11) gl).glGetFloatv(GL11.GL_MODELVIEW_MATRIX, modelview, 0);
((GL11) gl).glGetFloatv(GL11.GL_PROJECTION_MATRIX, projection, 0);
winx = (float)setx;
winy = (float)viewport[3] - sety;
winz = 0;
GLU.gluUnProject(winx, winy, winz, modelview, 0, projection, 0, viewport, 0, newcoords, 0);
posx = (int)newcoords[1];
posy = (int)newcoords[2];
posz = (int)newcoords[3];
Log.d(TAG, "vector3 Used");
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glScalef(100, 100, 0);
gl.glPushMatrix();
gl.glRotatef(rotation, 0, 0, 1);
gl.glTranslatef((float) speed/10, 0, 0);
square.draw(gl);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef(posx, posy, posz);
gl.glRotatef(statrotation,0,0,1);
statSquare.draw(gl);
gl.glPopMatrix();
statrotation++;
speed++;
Log.d(TAG, "Frame Drawn");
vector3((GL11) gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, -width, width, -height, height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
}
请注意,我尝试在 Draw 方法中调用 vector3() 方法,该方法似乎有效,因为它读取的内容足以在实际方法中找出错误。错误是在这一行抛出的。
GLU.gluUnProject(winx, winy, winz, modelview, 0, projection, 0, viewport, 0, newcoords, 0);
请注意,在抛出错误时,setx 和 sety 应等于 0,因为屏幕尚未被触摸。
该错误可能与我的 glSurfaceView 有关吗?
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.*;
import android.view.MotionEvent;
public class Input extends GLSurfaceView {
public GLSurfaceRenderer glSurfaceRenderer;
public float setx, sety;
public final static String TAG = "input";
public Input(Context context) {
super(context);
glSurfaceRenderer = new GLSurfaceRenderer();
setRenderer(glSurfaceRenderer);
}
@Override
public boolean onTouchEvent(MotionEvent event){
if (event.getAction() == MotionEvent.ACTION_DOWN){
setx = event.getX();
sety = event.getY();
Log.d(TAG, "isPressed triggered");
}
return true;
}
}
I get this error message
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): FATAL EXCEPTION: GLThread 9
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): java.lang.IllegalArgumentException: length - offset < n
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.Matrix.multiplyMV(Native Method)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.GLU.gluUnProject(GLU.java:237)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.app.ui.GLSurfaceRenderer.vector3(GLSurfaceRenderer.java:70)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.app.ui.GLSurfaceRenderer.onDrawFrame(GLSurfaceRenderer.java:103)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1332)
08-30 19:20:17.774: ERROR/AndroidRuntime(4681): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
With this code:
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.util.*;
public class GLSurfaceRenderer implements Renderer{
public static float setx, sety;
private static float posx, posy, posz = 100;
private double speed;
private static float rotation;
private static float statrotation;
public static boolean isPressed;
private static FlatColoredSquare square;
private static FlatColoredSquare statSquare;
public final static String TAG = "input";
public GLSurfaceRenderer () {
square = new FlatColoredSquare();
statSquare = new FlatColoredSquare();
rotation = (float) Math.floor(Math.random()*361);
speed = 0.1;
}
public void vector3 (GL11 gl){
int[] viewport = new int[4];
float[] modelview = new float[16];
float[] projection = new float[16];
float winx, winy, winz;
float[] newcoords = new float[3];
gl.glGetIntegerv(GL11.GL_VIEWPORT, viewport, 0);
((GL11) gl).glGetFloatv(GL11.GL_MODELVIEW_MATRIX, modelview, 0);
((GL11) gl).glGetFloatv(GL11.GL_PROJECTION_MATRIX, projection, 0);
winx = (float)setx;
winy = (float)viewport[3] - sety;
winz = 0;
GLU.gluUnProject(winx, winy, winz, modelview, 0, projection, 0, viewport, 0, newcoords, 0);
posx = (int)newcoords[1];
posy = (int)newcoords[2];
posz = (int)newcoords[3];
Log.d(TAG, "vector3 Used");
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glScalef(100, 100, 0);
gl.glPushMatrix();
gl.glRotatef(rotation, 0, 0, 1);
gl.glTranslatef((float) speed/10, 0, 0);
square.draw(gl);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef(posx, posy, posz);
gl.glRotatef(statrotation,0,0,1);
statSquare.draw(gl);
gl.glPopMatrix();
statrotation++;
speed++;
Log.d(TAG, "Frame Drawn");
vector3((GL11) gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, -width, width, -height, height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
}
Notice that I have attempted to call the vector3() method in my Draw method which appears to work because it reads far enough to pick out an error in the actual method. The error is thrown at this line
GLU.gluUnProject(winx, winy, winz, modelview, 0, projection, 0, viewport, 0, newcoords, 0);
Note that setx and sety should be equal to 0 at the point the error is thrown as the screen has not yet been touched.
Could the error be anything to do with my glSurfaceView?
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.*;
import android.view.MotionEvent;
public class Input extends GLSurfaceView {
public GLSurfaceRenderer glSurfaceRenderer;
public float setx, sety;
public final static String TAG = "input";
public Input(Context context) {
super(context);
glSurfaceRenderer = new GLSurfaceRenderer();
setRenderer(glSurfaceRenderer);
}
@Override
public boolean onTouchEvent(MotionEvent event){
if (event.getAction() == MotionEvent.ACTION_DOWN){
setx = event.getX();
sety = event.getY();
Log.d(TAG, "isPressed triggered");
}
return true;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我简单地查看了这个函数的源代码,它似乎期望您的 newcoords 向量的大小为 4 而不是 3。它们是齐次坐标,因此您还必须除以 w获取您的实际坐标。
请注意,您的代码中还存在另一个错误,在调用
gluUnProject
后,您对newcoords
的索引超出了范围。第一个元素是newcoords[0]
,而不是newcoords[1]
。我认为如果你使用这样的东西,它会工作得更好(虽然我没有测试这个):
I've briefly looked at the source code for this function, and it appears to expect your
newcoords
vector to have size 4 instead of 3. They are homogeneous coordinates, so you will also have to divide by w to get your actual coordinates.Note that there's another error in your code as well, you're indexing
newcoords
out of bounds after the call togluUnProject
. The first element isnewcoords[0]
, notnewcoords[1]
.I think if you use something like this, it would work better (I didn't test this though):