光线采摘混乱
Posted
技术标签:
【中文标题】光线采摘混乱【英文标题】:Ray picking mess 【发布时间】:2013-01-10 22:37:29 【问题描述】:我正在使用光线拾取来查找角色的边界。这不是最佳的,但这是我能做的最好的,而且必须做的;我需要(接近)像素完美的碰撞,而且我有很多很多的对象。
但是,我没有让光线拾取正常工作。它发生了碰撞,但不是在正确的地方。我尝试调整射线的大小,但没有任何效果。
对不起,代码乱七八糟,我只是把它放在一起。
private void renderCollision(Vector3f dir)
//
// Render the models
//
glPushMatrix();
glPushAttrib(GL_ALL_ATTRIB_BITS);
float size = 10.0f;
Picker.startPicking2D(10, 10, 20, 20, -1.0f, size);
//Picker.startPicking2D(10, 10, 20, 20, 0.1f, 20.0f);
glClear (GL_COLOR_BUFFER_BIT);
glDisable(GL_BLEND);
glDisable(GL_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(true);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(100.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
glLoadIdentity ();
//box.drawMoving(camera);
player.move(dir);
glTranslatef(-player.position.x, -player.position.y + size / 2.0f, -player.position.z);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
box.drawAll();
glDisable(GL_DEPTH_TEST);
boolean hit = Picker.getHit();
if (hit)
player.move(new Vector3f(-dir.x, -dir.y, -dir.z));
Picker.stopPicking();
glPopAttrib();
glPopMatrix();
public class Picker
private static IntBuffer selBuffer;
private static int hits;
private static int xSelected;
private static int ySelected;
/**
* Makes the game available for picking (when in 3D mode)
*
* @param xMouse The x coordinate of the mouse on the screen
* @param yMouse The y coordinate of the mouse on the screen
*/
public static void startPicking3D(int xMouse, int yMouse, int screenWidth, int screenHeight, float near, float far)
startPickingGeneric(xMouse, yMouse);
GLU.gluPerspective(SCREEN_FOV, SCREEN_RAT,
near, far);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
/**
* Makes the game available for picking (when in 2D mode)
*
* @param xMouse The x coordinate of the mouse on the screen
* @param yMouse The y coordinate of the mouse on the screen
*/
public static void startPicking2D(int xMouse, int yMouse, int screenWidth, int screenHeight, float near, float far)
startPickingGeneric(xMouse, yMouse);
GL11.glOrtho(0, screenWidth, 0, screenHeight, near, far);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
/**
* Makes the game available for picking (generic)
*
* @param xMouse The x coordinate of the mouse on the screen
* @param yMouse The y coordinate of the mouse on the screen
*/
private static void startPickingGeneric(int xMouse, int yMouse)
// The selection buffer
selBuffer = ByteBuffer.allocateDirect(1024).order(ByteOrder.nativeOrder()).
asIntBuffer();
IntBuffer vpBuffer = ByteBuffer.allocateDirect(64).
order(ByteOrder.nativeOrder()).asIntBuffer();
// Size of the viewport. [0] Is <x>, [1] Is <y>, [2] Is <width>, [3] Is <height>
int[] viewport = new int[4];
// Get the viewport info
GL11.glGetInteger(GL11.GL_VIEWPORT, vpBuffer);
vpBuffer.get(viewport);
// Set the buffer that OpenGL uses for selection to our buffer
GL11.glSelectBuffer(selBuffer);
// Change to selection mode
GL11.glRenderMode(GL11.GL_SELECT);
// Initialize the name stack (used for identifying which object was selected)
GL11.glInitNames();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
// Create 5x5 pixel picking region near cursor location
GLU.gluPickMatrix((float) xMouse, (float) yMouse,
5.0f, 5.0f, IntBuffer.wrap(viewport));
/**
* Stops the picking mode
*/
public static void stopPicking()
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
hits = 0;
hits = GL11.glRenderMode(GL11.GL_RENDER);
/**
* Gets the tile the mouse points to
*
* @return TileCoords object with the coordinates of the selected tile
*/
public static boolean getHit()
int[] buffer = new int[256];
xSelected = -1000;
ySelected = -1000;
selBuffer.get(buffer);
if (hits > 0)
// If there were more than 0 hits
xSelected = buffer[3]; // Make our selection the first object
ySelected = buffer[4];
int depth = buffer[1]; // Store how far away it is
for (int i = 1; i < hits; i++)
// Loop through all the detected hits
// If this object is closer to us than the one we have selected
if (buffer[i * 4 + 1] < (int) depth)
xSelected = buffer[i * 4 + 3]; // Select the closest object
ySelected = buffer[i * 4 + 4];
depth = buffer[i * 4 + 1]; // Store how far away it is
return true;
return false;
【问题讨论】:
“pickelperfect 碰撞”? @gepfault:是的,像泡菜一样绿:') 不要使用固定功能管道! @Felix K.:我刚读到这个,这显然是有争议的,但较新的显卡确实可以使用着色器更快。如果我非常需要性能提升,我会记住这一点。谢谢! @RobotRock 还有其他一些原因,不仅是关于性能,而且你更灵活,这是主要原因,ffp 已被弃用。 【参考方案1】:我应该绕 x 轴而不是 y 轴旋转然后平移。
【讨论】:
以上是关于光线采摘混乱的主要内容,如果未能解决你的问题,请参考以下文章