मैं खेल Antichamber की तरह कुछ को लागू करने की कोशिश कर रहा है पिछले सप्ताह के (अधिक precisly इस चाल नीचे दिखाया गया है) जो मैं उम्मीद कर रहा हूं उसका वीडियो (भले ही यह अवास्तविक इंजन 4 के साथ किया गया हो; मैं इसका उपयोग नहीं कर रहा हूं): https://www.youtube.com/watch?v=Of3JcoWrMZsओपन कैसे लागू करने के लिए "पोर्टल प्रतिपादन"
मैंने ऐसा करने का सबसे अच्छा तरीका देखा और मुझे स्टैंसिल के बारे में पता चला बफर। this लेख और this कोड ("drawPortals()" फ़ंक्शन) के बीच में मैंने ऑनलाइन पाया कि मैं इसे लगभग कार्यान्वित करने में कामयाब रहा।
यह एक पोर्टल के साथ एक और कमरे में अच्छी तरह से काम करता है (एक क्रॉस करने योग्य पोर्टल नहीं, जिसका अर्थ है कि आप इसके माध्यम से नहीं चल सकते हैं और दूसरे कमरे में टेलीपोर्ट किया जा सकता है)। मेरे उदाहरण में मैं एक साधारण वर्ग वाले कमरे में एक क्षेत्र के साथ एक पोर्टल खींच रहा हूं; पोर्टल के पीछे एक और क्षेत्र है, कि मैं चाहे गहराई बफर सही ढंग से काम कर रहा था और पोर्टल के पीछे यह ड्राइंग जाँच करने के लिए प्रयोग किया है: जब मैं एक और पोर्टल जोड़ने
समस्याओंउठता है कि इस के पास है उस मामले में मैं अन्य पोर्टल सही ढंग से प्रदर्शित करने के लिए प्रबंधन (प्रकाश बंद है, लेकिन सही पर क्षेत्र है कि यह एक और क्षेत्र है दिखाने के लिए एक अलग रंग का है):
लेकिन अगर मैं बारी कैमरा इतना है कि पहले पोर्टल दूसरा एक से अधिक तैयार हो गया है, तो पहले एक की गहराई गलत हो जाता है, और दूसरा पोर्टल इस तरह पहले से अधिक तैयार हो जाता है,:
जबकि यह ऐसा कुछ होना चाहिए:
तो, यह समस्या है। मैं शायद गहराई बफर के साथ कुछ गलत कर रहा हूं, लेकिन मुझे क्या नहीं मिल रहा है।
प्रतिपादन भाग के लिए मेरे कोड काफी यह है:
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
// First portal
glPushMatrix();
// Disable writing to the color and depht buffer; disable depth testing
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
// Make sure that the stencil always fails
glStencilFunc(GL_NEVER, 1, 0xFF);
// On fail, put 1 on the buffer
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
// Enable writing to the stencil buffer
glStencilMask(0xFF);
// Clean the buffer
glClear(GL_STENCIL_BUFFER_BIT);
// Finally draw the portal's frame, so that it will have only 1s in the stencil buffer; the frame is basically the square you can see in the pictures
portalFrameObj1.Draw();
/* Now I compute the position of the camera so that it will be positioned at the portal's room; the computation is correct, so I'm skipping it */
// I'm going to render the portal's room from the new perspective, so I'm going to need the depth and color buffers again
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
// Disable writing to the stencil buffer and enable drawing only where the stencil values are 1s (so only on the portal frame previously rendered)
glStencilMask(0x00);
glStencilFunc(GL_EQUAL, 1, 0xFF);
// Draw the room from this perspective
portalRoomObj1.Draw();
glPopMatrix();
// Now the second portal; the procedure is the same, so I'm skipping the comments
glPushMatrix();
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glStencilFunc(GL_NEVER, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
glStencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT);
portalFrameObj2.Draw();
/* New camera perspective computation */
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
glStencilMask(0x00);
glStencilFunc(GL_EQUAL, 1, 0xFF);
portalRoomObj2.Draw();
glPopMatrix();
// Finally, I have to draw the portals' frames once again but this time on the depth buffer, so that they won't get drawn over; first off, disable the stencil buffer
glDisable(GL_STENCIL_TEST);
// Disable the color buffer
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glClear(GL_DEPTH_BUFFER_BIT);
// Draw portals' frames
portalFrameObj1.Draw();
portalFrameObj2.Draw();
// Enable the color buffer again
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
/* Here I draw the rest of the scene */
अद्यतन
मैं पता लगाने के लिए कि समस्या क्या है में कामयाब रहे, लेकिन मैं अभी भी इसे हल करने में सक्षम नहीं हूँ। यह वास्तव में गहराई बफर से संबंधित नहीं है, लेकिन स्टैंसिल के लिए।
असल में, जिस तरह से मैं पहला पोर्टल खींच रहा हूं वह यह है: 1) स्टैंसिल बफर में 1 एस के साथ पोर्टल फ्रेम की बिट्स भरें; पोर्टल के बाहर केवल 0s 2) पोर्टल रूम बनाएं जहां स्टैंसिल के पास 1 है (ताकि यह फ्रेम के पोर्टल
पर खींचा जाए और मैं इसे दूसरे पोर्टल के लिए दोहरा दूं।तब मैं
:
पहले पोर्टल के लिए, मैं पर चरण 1 कुछ इस तरह तो (बेवकूफ चित्र क्षमा, मैं आलसी हूँ) मिलती है:
फिर 2 चरण के बाद दूसरे पोर्टल के साथ शुरू:
लेकिन अब, चरण 1 और 2 के बीच, मैं स्टेंसिल बता केवल आकर्षित करने के लिए जहां बिट्स 1s कर रहे हैं; चूंकि बफर अब साफ़ हो गया है, इसलिए मैंने पहले पोर्टल के 1 एस का ट्रैक खो दिया है, इसलिए यदि दूसरे पोर्टल के फ्रेम का हिस्सा पिछले फ्रेम के पीछे है, तो दूसरे फ्रेम के 1 एस को अभी भी दूसरे पोर्टल के कमरे के साथ खींचा जाएगा, भले ही गहराई बफर एक तरह से इस छवि में पसंद:
अगर मैं इसे सही समझाने में कामयाब मैं नहीं जानता ...