2011-09-15 13 views
5

मैं विंडोज कॉर्ड को विश्व कॉर्ड में बदलने के लिए gluUnProject का उपयोग करने की कोशिश कर रहा हूं। मैं एमुलेटर या पुराने एंड्रॉइड सिस्टम (ओपनजीएल ईएस v1.0 के साथ) में काम करने का नमूना पाने की कोशिश नहीं कर रहा हूं और यह जीएल फ़ंक्शन उपलब्धता के बारे में कोई सवाल नहीं है। मैं ओपनजीएल ईएस 1.1 के साथ असली डिवाइस पर काम करने की कोशिश कर रहा हूं और glGet फ़ंक्शंस गैर-शून्य परिणाम लौटाता हूं।gluUnProject एंड्रॉइड ओपनजीएल ES 1.1 उपयोग

नमूना है:

public Vector3 translateScreenCoordsToWorld(Vector2 screenCoords) { 
gl.glLoadIdentity(); 

final Matrix4x4 modelViewMatrix = new Matrix4x4(); 
final Matrix4x4 projectMatrix = new Matrix4x4(); 

int[] viewVectorParams = new int[4]; 
gl.glGetIntegerv(GL11.GL_VIEWPORT,viewVectorParams,0); 
gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX,modelViewMatrix.buffer,0); 
gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX,projectMatrix.buffer,0); 

float[] output = new float[4]; 
GLU.gluUnProject(
    screenCoords.x, screenCoords.y, 0, 
    modelViewMatrix.buffer, 0, 
    projectMatrix.buffer, 0, 
    viewVectorParams, 0, 
    output, 0);    

return new Vector3(output[0],output[1],output[2]); 

} 

Matrix4x4 सिर्फ नाव [] बफर के लिए एक आवरण है,

इस फ़ंक्शन के साथ मैं सभी स्क्रीन भरने के लिए एक विमान बनाने की कोशिश कर रहा हूं या वर्तमान प्रक्षेपण मैट्रिक्स के लिए अधिकतम विश्व कोर का पता लगाने की कोशिश कर रहा हूं, लेकिन यह बिल्कुल काम नहीं कर रहा है क्योंकि मुझे सच में यकीन नहीं है कि मैं इन कार्यों का सही ढंग से उपयोग कर रहा हूं।

उदाहरण के लिए, जब मैं कोशिश कर रहा हूँ रन translateScreenCoordsToWorld (नई Vector2 (480,800)) यह बहुत छोटा निर्देशांक रिटर्न को महत्व देता Vector3 (0.27f, 0.42f, -1.0f)।

कोई भी एक निर्धारित कैमरे के साथ GL_PROJECTION मोड के लिए अच्छा नमूना उपयोग gluUnProject प्रदान कर सकता है।

अद्यतन अच्छे लिंक के लिए धन्यवाद। लेकिन यह अभी भी मेरे लिए काम नहीं कर रहा ':( अब मेरी समारोह लगता है:

public Vector3 translateScreenCoordsToWorld(Vector2 screenCoords) { 

float winX = screenCoords.x, winY = screenCoords.y, winZ = 0; 
winY = (float)currentViewVectorParams[3] - winY; 

float[] output = new float[4]; 
GLU.gluUnProject(
    winX, winY, winZ, 
    currentModelViewMatrix.buffer, 0, 
    currentProjectMatrix.buffer, 0, 
    currentViewVectorParams, 0, 
    output, 0 
);    

Vector3 nearPlane = new Vector3(output[0],output[1],output[2]); 
winZ = 1.0f;   
GLU.gluUnProject(
    winX, winY, winZ, 
    currentModelViewMatrix.buffer, 0, 
    currentProjectMatrix.buffer, 0, 
    currentViewVectorParams, 0, 
    output, 0 
);    
Vector3 farPlane = new Vector3(output[0],output[1],output[2]); 

farPlane.sub(nearPlane); 
farPlane.div(nearPlane.length()); 

float dot1, dot2; 

Vector3 pointInPlane = new Vector3(), pointPlaneNormal = new Vector3(0,0,-1); 
pointInPlane.sub(nearPlane); 

dot1 = (pointPlaneNormal.x * pointInPlane.x) + (pointPlaneNormal.y * pointInPlane.y) + (pointPlaneNormal.z * pointInPlane.z); 
dot2 = (pointPlaneNormal.x * farPlane.x) + (pointPlaneNormal.y * farPlane.y) +(pointPlaneNormal.z * farPlane.z); 

float t = dot1/dot2; 
farPlane.mul(t); 

return farPlane.add(nearPlane); 
} 

और यहां मेरा कैमरा विन्यस्त:

public void updateCamera() { 
Camera camera = scene.getCamera(); 
GLU.gluLookAt(gl, 
    camera.position.x, camera.position.y, camera.position.z, 
    camera.target.x, camera.target.y, camera.target.z, 
    camera.upAxis.x, camera.upAxis.y, camera.upAxis.z 
); 

    gl.glGetIntegerv(GL11.GL_VIEWPORT,currentViewVectorParams,0);  
    gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, currentModelViewMatrix.buffer,0); 
    gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX,currentProjectMatrix.buffer,0); 
} 

कैमरा निम्नलिखित coords के साथ विन्यस्त:

camera.position = { 0, 0, 65 };  
camera.target = { 0, 0, 0 } 
camera.upAxis = { 0, 1, 0 } 

उत्तर

3

ठीक है, आमतौर पर gluUnProject का उपयोग करते समय आप स्क्रीन पर पिक्सेल के विश्व अंतरिक्ष समन्वय को प्राप्त करने का प्रयास कर रहे हैं। आपको int को रखने के लिए जानकारी के तीन टुकड़े, (matrices के अलावा) की आवश्यकता है o glUnProject, एक स्क्रीन एक्स समन्वय, एक स्क्रीन वाई समन्वय, और उस पिक्सेल से संबंधित गहराई बफर मूल्य। प्रक्रिया सामान्य रूप से इस प्रकार जाती है:

  1. एक फ्रेम बनाएं, इसलिए सभी गहराई बफर जानकारी तैयार है।
  2. व्यूपोर्ट/मैट्रिस/स्क्रीन कॉर्ड
  3. स्क्रीन वाई समन्वय को घुमाएं।
  4. किसी दिए गए पिक्सेल पर गहराई मान पढ़ें। यह प्रभावी रूप से एक सामान्यीकृत जेड समन्वय है।
  5. glunProject में x, y और z इनपुट करें।

यह एक पिक्सेल के दिए गए खंड के विश्व अंतरिक्ष समन्वय को समाप्त करता है। एक और अधिक विस्तृत गाइड here पाया जा सकता है। वैसे भी, मैं आपके कोड में दो संभावित गलतियों को देख सकता हूं। पहला यह है कि आम तौर पर आपको वाई स्क्रीन समन्वय को उलटा करना पड़ता है, (लिंक विवरण पर ट्यूटोरियल क्यों), दूसरा यह है कि आप हमेशा zu मान के रूप में gluUnProject के रूप में 0 में गुजर रहे हैं। इस अन-प्रोजेक्ट को वर्टेक्स करना जैसे कि यह निकटतम विमान पर था। क्या ये वही है जो तुम चाहते हो?

वैसे भी, अगर मैं आपके प्रश्न को गलत तरीके से पढ़ता हूं तो मुझे क्षमा करें।

+0

धन्यवाद! यह अच्छा नेहे लेख है। लेकिन ओपनजीएल ईएस (एंड्रॉइड) में कोई GL_DEPTH_COMPONENT समर्थन नहीं है।मैं glReadPixels (Winx, Winy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, कॉल कर सकते हैं नहीं &winZ); :( कोई वैकल्पिक हल समाधान है? – abdolence

+3

आप सही, मैं शायद याद किया जाना चाहिए था कर रहे हैं। दो काम arounds, कर रहे हैं सबसे पहले निकट और दूर के विमान के बीच एक किरण बनाना और मैन्युअल चौराहे परीक्षण चलाएं, (जो काफी मुश्किल हो सकता है), [यहां] (http://softwareprodigy.blogspot.com/2009/08/gluunproject-for- iphone-opengl-es.html), दूसरा फ्रेम बफर ऑब्जेक्ट बनाना है, और उस से गहराई बफर मानों को पढ़ना है। वैकल्पिक रूप से आप gluUnProject को छोड़ सकते हैं और पिकिंग को लागू करने का प्रयास कर सकते हैं। [यहां देखें] (http: // stackoverflow। कॉम/प्रश्न/7364693/कैसे-से-get-object-in-webgl-3d-space-from-a-mouse-click-coordinate) –

+0

फिर से रुचि लिंक। धन्यवाद! मैंने मैन्युअल छेड़छाड़ को लागू करने का प्रयास किया, लेकिन यह अभी भी नहीं है काम कर रहा है :(कृपया अद्यतन को देखें ई – abdolence

संबंधित मुद्दे