2012-10-28 32 views
5

मैं एक गेम इंजन बनाने के लिए एसडीएल 2 और सी ++ 11 का उपयोग कर रहा हूं (जैसे कि एक निजी परियोजना, मज़ेदार और अभ्यास के लिए), और उन चीजों में से एक जो मैं करना चाहता हूं और ग्राफिक्स ड्राइवर ओपनजीएल के नवीनतम समर्थित संस्करण का उपयोग करता है, और संस्करण के आधार पर इंजन के ग्राफिक्स हिस्से को कैसे प्रस्तुत करता है, इस प्रकार भिन्न होता है। इस तरह मैं ओपनजीएल की नवीनतम सुविधाओं का उपयोग कर सकता हूं जहां वे प्रासंगिक और उपयोगी हैं, लेकिन पुराने हार्डवेयर का भी समर्थन करते हैं। वहाँ दो तरीकों मैं के बारे में सोच सकते हैं:एक ओपनजीएल 4.3 संदर्भ क्रैश बनाना जीएलएक्स

  1. ओपन के नवीनतम समर्थित संस्करण का पता लगा रहा है और उस का उपयोग कर, लेकिन मुझे लगता है कि ऐसा करने के लिए किसी भी तरह से नहीं सोच सकते हैं। हां, मैंने Google की कोशिश की है।

  2. परीक्षण और त्रुटि का उपयोग करना, जहां मैं नवीनतम संस्करण से शुरू होता हूं (4.3, लेकिन मेरा जीटीएक्स 460 केवल 4.2 तक का समर्थन करता है, भले ही मैंने ड्राइवर अपडेट किए हों), और यदि यह विफल हो जाता है (जिसे मैं एसडीएल की जांच करके पता लगाता हूं एक पूर्ण संदर्भ वापस करने के लिए), मैं संस्करण संख्या को कम करता हूं और पुनः प्रयास करता हूं।

जिस विधि का मैं उपयोग करता हूं (# 2) 4.3 संदर्भ के निर्माण पर तत्काल विफल रहता है। मुझे पता है कि मेरे ग्राफिक्स ड्राइवर अभी 4.2 का समर्थन करते हैं, लेकिन मैंने सोचा था कि जीएलएक्स को एक त्रुटि फेंकने, एक पूर्ण संदर्भ देने के लिए डिज़ाइन किया गया था, और आपके प्रोग्राम को जारी रखने दें, लेकिन इसके बजाय यह संदर्भ की असफल रचना को पीछे नहीं ला सकता । क्या मेरी धारणा है कि जीएलएक्स कैसे गलत व्यवहार करता है? संदर्भ बनाने के बिना नवीनतम समर्थित संस्करण का पता लगाने का कोई तरीका है?

क्योंकि मैं जानता हूँ कि कुछ लोगों को पूरा और कम से कम स्रोत है कि त्रुटि दर्शाता है देखना पसंद करते हैं यहाँ यह है:

#include <SDL2/SDL.h> 
#include <SDL2/SDL_opengl.h> 
int main() { 
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { 
     return -1; 
    } 
    SDL_Window* window = SDL_CreateWindow("SDL Window", 0, 0, 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 
    if(window == nullptr) { 
     return -1; 
    } 
    unsigned int major = 4; 
    unsigned int minor = 3; 
    SDL_GLContext context = nullptr; 
    while(context == nullptr) { 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major); 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor); 
     context = SDL_GL_CreateContext(window); 
     if(context == nullptr) { 
      if(minor == 0 && major > 1) { 
       --major; 
       minor = 9; 
      } 
      else if(minor > 0) { 
       --minor; 
      } 
      else { 
       SDL_DestroyWindow(window); 
       return -1; 
      } 
     } 
    } 
    SDL_Delay(5000); 
    SDL_GL_DeleteContext(context); 
    SDL_DestroyWindow(window); 
    return 0; 
} 

इसके अलावा, अगर मुझे लगता है कि कोड को बदलने के लिए एक 4.3 के बजाय एक 4.2 संदर्भ के साथ शुरू करने के लिए, यह ठीक काम करता है। तो त्रुटि 4.3 संदर्भ विशेष रूप से बनाने में है।

+0

सुनिश्चित नहीं है कि यह मदद करेगा, लेकिन यह सवाल बताता है कि संदर्भ संस्करण को SDL_Init को कॉल करने से पहले सेट करना होगा: http://stackoverflow.com/questions/8110053/creating-an-opengl-3-2- 3-x-context-in-sdl-1-3 –

+0

वॉन, वास्तव में? यह अजीब बात है, एसडीएल दस्तावेज़ों का मतलब है कि इसे एसडीएल इनिट को कॉल करने और संदर्भ बनाने से पहले सेट करना होगा। इसके अलावा, अगर मैं 4.2 से शुरू करने के लिए कोड बदलता हूं, तो यह ठीक काम करता है। शायद उल्लेख किया जाना चाहिए था कि ... – OniLink

+0

क्या आपने @VaughnCato द्वारा प्रदान किए गए सुझाव की कोशिश की है? क्या आपने 'SDL_GL_SetAttribute' से वापसी मानों की जांच की है, दस्तावेज़ों का सुझाव है कि उन्हें सफलता के लिए 0 होना चाहिए। कोड में यह क्रैश हो रहा है? डीबगर आपको क्या बताता है? –

उत्तर

1

यह संभवतः एसडीएल के X11_GL_CreateContext() में एक बग इंगित कर सकता है (वेब ​​पर यह कहता है कि एसडीएल 2 अभी भी प्रयोगात्मक है)। समर्थित OpenGL संस्करण को ढूंढने की आपकी रणनीति मान्य है, लेकिन एसडीएल के लिए आपको आगे-संगत संदर्भ देने के लिए, पहले इसे अस्थायी संदर्भ बनाने की आवश्यकता है, glCreateContextAttribsARB प्राप्त करने के लिए glxGetProcAddress() पर कॉल करें (यह बिना किए किए ऐसा नहीं कर सकता एक सक्रिय ओपनजीएल संदर्भ), और फिर यह आपके द्वारा अनुरोधित ओपनजीएल संस्करण को प्रारंभ करने का प्रयास करता है। अब अगर यह विफल रहता है, तो यह अस्थायी संदर्भ का निपटारा करता है और पूर्ण लौटाता है।

मेरा अनुमान है कि यह दूसरी बार अस्थायी संदर्भ बनाने में विफल रहता है, मैं डीबग जानकारी के साथ एसडीएल बनाने का सुझाव देता हूं और यह पता लगाने की कोशिश करता हूं कि X11_GL_CreateContext() में यह वास्तव में कहां विफल रहता है (या कम से कम कुछ printf को प्रेरित करना) ।

दूसरी ओर, यदि आप अपने डिफ़ॉल्ट मानों में SDL_GL_CONTEXT_MAJOR_VERSION और SDL_GL_CONTEXT_MINOR_VERSION छोड़ते हैं तो आपको पहले से ही अधिकतम ओपनजीएल संस्करण मिलता है। आपको केवल एक फॉरवर्ड-संगत संदर्भ नहीं मिलता है, जिसका अर्थ यह है कि इससे कुछ व्यवहार किए जाएंगे जिन्हें भविष्य के संस्करणों में "गलती" माना जाता है।

इसके अलावा, सामान्य रूप से, अधिकतम संस्करण के साथ आगे-संगत संदर्भ बनाने का अच्छा विचार नहीं है। जैसे ओपनजीएल 3.2 में, फॉरवर्ड-संगत प्रोफ़ाइल वर्टेक्स सरणी ऑब्जेक्ट्स के उपयोग को लागू करती है, जो पुराना कोड बनाता है जो वीएओ टूटा हुआ नहीं है। इसलिए यदि ओपनजीएल 3.1 (या कोई अन्य संस्करण) के लिए लिखा गया एप्लिकेशन नवीनतम अग्रेषित-संगत प्रोफ़ाइल को संभव बनाने की कोशिश करता है, तो वास्तव में यह भविष्य में काम करना बंद कर सकता है। यह एक अच्छा विचार नहीं है।

एक विकल्प एक आगे-संगत प्रोफ़ाइल के उपयोग पर निर्णय लेना है, जो अधिकतर सहायक है क्योंकि यह बहिष्कृत सुविधाओं के बारे में त्रुटियों की रिपोर्ट करता है। यदि आप वास्तव में अधिक संस्करणों का उपयोग करना चाहते हैं, तो ऐसा करने के लिए आपको अधिक कोड पथ (= अपने गेम इंजन के अधिक संस्करण) की आवश्यकता है।ओपनजीएल संस्करण का पता लगाने के लिए, मैं एक डमी एसडीएल विंडो बनाने, एक साधारण ओपनजीएल प्रोफाइल शुरू करने, संस्करण प्राप्त करने और सब कुछ बंद करने का सुझाव देना चाहता हूं, फिर उस संस्करण के साथ फिर से शुरू करना, जिसके लिए आप निर्णय लेते हैं। यह काम करना चाहिए।

दूसरा विकल्प केवल विकास के लिए आगे-संगत प्रोफ़ाइल का उपयोग करना और वितरण के लिए एक सरल विरासत प्रोफ़ाइल का उपयोग करना है। यह सबसे संगत है और इसमें कम से कम प्रयास शामिल है (आप रिलीज संस्करण में अधिकांश ओपनजीएल त्रुटियों को अनदेखा करना चाहते हैं - त्रुटि रिपोर्टिंग ड्राइवर द्वारा भी अक्षम की जा सकती है)।

+0

एसडीएल में एक बग की वजह से यह बहुत अच्छा हो सकता है। मैं यह देखने के लिए परीक्षण कर रहा हूं कि मैं कुछ भी ट्रैक कर सकता हूं, लेकिन मुझे पूरा यकीन है कि यह एक ड्राइवर त्रुटि है (मैंने एसएफएमएल का भी परीक्षण किया है, जिसमें वास्तव में अधिकतम समर्थित जीएल संस्करण के परीक्षण के लिए समान कार्यक्षमता है, यह भी असफल रहा)। मैंने SDL_GL_CONTEXT _ * _ संस्करण सेट करने की कोशिश नहीं की, और उसने मुझे 2.1 संदर्भ दिया, जिससे यह काम नहीं करेगा। मैं प्रतिपादन कोड के कई संस्करण लिखना चाहता हूं - यह सब मेरे लिए सीखने के लिए एक परियोजना है। – OniLink

+0

अपडेट: मैं एसडीएल में प्रिंटफ्स का एक गुच्छा डालता हूं जहां यह क्रैश हो जाता है। यह इस लाइन पर विशेष रूप से दुर्घटनाओं: 'संदर्भ = glXCreateContextAttribs (प्रदर्शन, [0] framebuffer_config, share_context, यह सच है, गुण);' तो, हाँ, यह एक चालक मुद्दा कैसा दिखाई देता है, क्योंकि यह यह अतीत बनाया अस्थायी संदर्भ और सबकुछ। – OniLink

+0

@ ओनीलिंक हो सकता है। अगर मुझे गलत नहीं लगता है, तो ओपनजीएल 4.3 ड्राइवर अभी भी बीटा हैं (कम से कम एनवीडिया हैं)। लेकिन फिर भी मुझे लगता है कि डमी खिड़की और पूर्ण शटडाउन के साथ init चाल चल सकता है। दुर्भाग्यवश, –

2

यह थोड़ी देर हो चुकी है, लेकिन मैं हाल ही में इस समस्या के साथ संघर्ष किया (फिर भी दुर्घटनाओं जब एक ओपन संदर्भ SDL2 में समर्थित नहीं thats बनाने का प्रयास कर)

मैं बस बनाया एक डमी संदर्भ और फिर उस के लिए उस संदर्भ का उपयोग जीएल संस्करण प्राप्त करने के लिए। फिर उस संदर्भ को नष्ट करें (जब तक यह वही है जो मैं चाहता था) और दूसरा बनाओ।

//Create Dummy Context 
context = SDL_GL_CreateContext(window); 

//Get OpenGL Version 
const GLubyte* sGLVersion = glGetString(GL_VERSION); 

version = (sGLVersion[0]-'0')*10; 
version += (sGLVersion[2]-'0'); 

//Now Check that it can support the version that you want to make and stop if you can't 
//or in your case set it to that version 

//If you need to make another context destroy the old one 
SDL_GL_DeleteContext(context); 

//and make a new one 
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majorVersion); 
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minorVersion); 

context = SDL_GL_CreateContext(window); 

यह संस्करण संख्याओं के माध्यम से ब्रूट-फोर्सिंग से भी तेज है जब तक कि आप काम करने वाले किसी व्यक्ति पर भूमि न हो जाएं। (आपका समाधान 1 जिसे आप googling द्वारा नहीं ढूंढ पाएंगे :))

'स्वाइन' को डिफ़ॉल्ट संस्करण के बारे में गलत संस्करण के बारे में गलत माना गया था (कम से कम संस्करण में मेरे पास यह 2.1 है जहां मेरे पास 4.3 है उपलब्ध)