2015-06-23 6 views
8

पर glviewport नहीं लगाया गया है I QVpenGLWidget :: glizeGL में glViewport वर्चुअल फ़ंक्शन को ओवरराइट किया गया है, जिसे कॉल किया गया था और व्यूपोर्ट केवल विजेट स्पेस का हिस्सा उपयोग करता था। लेकिन इसका कोई प्रभाव नहीं पड़ा, सामग्री अभी भी विजेट के पूर्ण आकार में आती है। क्या मुझे कुछ याद आया?glViewport Qt5.4 QOpenGLWidget :: resizeGL

class MyWidget : public QOpenGLWidget, protected QOpenGLFunctions 
{ 
    Q_OBJECT 

public: 
    explicit MyWidget(QWidget* parent = NULL); 

protected: 
    virtual void initializeGL(); 
    virtual void paintGL(); 
    virtual void resizeGL(int w, int h); 

private: 
    QOpenGLShaderProgram program; 
}; 

और mywidget.cpp:

MyWidget::MyWidget(QWidget* parent) : QOpenGLWidget(parent) 
{ 
} 

static const GLfloat squareVertices[] = { 
    -1.0f, -1.0f, 
    1.0f, -1.0f, 
    -1.0f, 1.0f 
}; 

void MyWidget::initializeGL() 
{ 
    initializeOpenGLFunctions(); 
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 

    program.addShaderFromSourceCode(QOpenGLShader::Vertex, 
     "attribute highp vec4 vec;\n" 
     "void main(void)\n" 
     "{\n" 
     " gl_Position = vec;\n" 
     "}"); 
    program.addShaderFromSourceCode(QOpenGLShader::Fragment, 
     "void main(void)\n" 
     "{\n" 
     " gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);\n" 
     "}"); 
    program.link(); 
    program.bind(); 

    program.enableAttributeArray(0); 
    program.setAttributeArray(0, squareVertices, 2); 
} 

void MyWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    //glViewport(0, 0, width()/2, height()/2); 
    // if I put glViewport here, everything work as intended, 
    // but we shouldn't need to set viewport everytime render a frame 

    program.bind(); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); 
} 

void MyWidget::resizeGL(int w, int h) 
{ 
    glViewport(0, 0, w/2, h/2); 
    // this line didn't have any effect, opengl still draw using full widget space 
} 
+0

मुझे नहीं लगता कि आप इस तरह से ऐसा कर सकते हैं। glViewport केवल सामान्यीकृत डिवाइस स्थान से स्क्रीन स्पेस तक एफ़िन रूपांतरण को संभालता है। यदि आप जीएल विंडो के एक हिस्से में प्रस्तुत करना चाहते हैं, तो आपको वास्तविक प्रतिपादन के बनावट के साथ एक ट्रैक्टर बनाना होगा। यह काफी जटिल और वास्तव में कुशल नहीं होगा, इसलिए यदि आप अभी समझाया गया है, तो यह आपकी मदद करेगा, आप केवल खिड़की के हिस्से में क्यों प्रस्तुत करना चाहते हैं। शायद आप जो करना चाहते हैं उसके लिए एक बेहतर समाधान है! वास्तव में glViewport क्या करता है इसके वर्णन के लिए https://www.khronos.org/opengles/sdk/docs/man/xhtml/glViewport.xml भी देखें। –

उत्तर

0

glViewport होना चाहिए Calle

यहाँ मेरी कोड,

mywidget.h है डी ड्राइंग कोड में, यानी paintGL हैंडलर, कहीं और नहीं। विंडो रीशेप हैंडलर में glViewport कॉल होने के कारण एक खराब एंटी-पैटर्न है जो ओपनजीएल ट्यूटोरियल्स में बहुत दूर फैल गया है; यह वहां से संबंधित नहीं है।

+0

की गणना में इन मैट्रिक्स लेने के लिए और glViewport paintGL हैंडलर में हर फ्रेम रीसेट मेरे लिए एक बड़ा बेकार लगता है, के बाद से glViewport केवल परिवर्तित होने पर विंडो आकार परिवर्तन (resizeGL हैंडलर) – user3724853

+0

@ user3724853: कई कार्यक्रमों में एक फ्रेम को प्रतिपादित करने में व्यूपोर्ट कई बार बदलता है। उदाहरण के लिए हर बार एक बनावट को एक छवि में प्रस्तुत किया जाता है, या दृश्य कई पैन में विभाजित होता है, आदि व्यूपोर्ट को सेट करना वास्तव में इतना सस्ता है, कि अन्य ग्राफिक्स एपीआई में, वल्कन की तरह, व्यूपोर्ट को सेट करने का एक अभिन्न हिस्सा माना जाता है एक फ्रेम प्रतिपादन। GlViewport को कॉल करना न तो अपर्याप्त और न ही अक्षम है और वास्तव में इसके बारे में जाने का एकमात्र तरीका है। प्रक्षेपण मैट्रिक्स बीटीडब्ल्यू सेट करने के साथ ही यही होता है। * इसे मेरे साथ कहें: * * "मैं प्रत्येक फ्रेम की शुरुआत में glViewport को कॉल करूंगा।" * – datenwolf

0

कोशिश के बाद,

void MyWidget::resizeGL(int w, int h) 
{ 
    glViewport(0, 0, w, h); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    GLdouble dWt; 
    GLdouble dHt; 

    if(w > h) { 
     dHt = 1; 
     dWt = ((double)w)/h; 
    } else { 
     dHt = ((double)h)/w; 
     dWt = 1; 
    } 

    if(bPerspective) { 
     glFrustum(-dWt, dWt, -dHt, dHt, 5, 100); 
    } else { 
     glOrtho(-dWt, dWt, -dHt, dHt, 5.0, 100.0); 
    } 

    gluLookAt(5.0, 2.0, -10.0, 
       0.0, 0.0, 0.0, 
       0.0, 1.0, 0.0); 

    glMatrixMode(GL_MODELVIEW); 
} 
+0

मैं शेडर का उपयोग कर रहा हूं, इसलिए मैट्रिक्स मोड का कोई अर्थ नहीं है (मैं इसका उपयोग नहीं कर रहा हूं)। glViewport सेटिंग जहां तक ​​मुझे पता है शेडर के बाहर है, लेकिन ऐसा लगता है कि क्यूटी के कार्यान्वयन ने इसे आकार बदलने के दौरान नहीं लिया? – user3724853

+0

जब मैंने अपना 2 डी ओपनजीएल फ्रेमवर्क लॉन्च किया था तो मैं ऑन पेंट से पहले glViewPort को लागू कर रहा था, इसलिए यदि आपके पास स्रोत कोड है तो पेंट से पहले क्या होता है। किसी भी मामले में glViewPort आंतरिक परिवर्तन matrices को प्रभावित करने के लिए सिर्फ एक सुविधा विधि है। तो glViewport से पहले दृष्टिकोण से ऊपर प्रयास करने और विशेष रूप से glMatrixMode के साथ खेलने के लिए कुछ योग्यता है। अंत में अगर आप अपने शेडर लिख रहे हैं हो सकता है आप consieration –

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