سؤال

أحتاج إلى إظهار نفس الكائن في OpenGL في عرضين مختلفين، على سبيل المثال، واحد باستخدام الإسقاط Ortographic والآخر باستخدام منظور. من أجل القيام بذلك، أحتاج إلى رسم مرة أخرى الكائن بعد كل مكالمة إلى GLVIEPPORT ()؟

هل كانت مفيدة؟

المحلول

nehe. لديه برنامج تعليمي جيد حول كيفية القيام بذلك، وموقعه هو موارد جيدة بشكل عام لأسئلة OpenGL.

نصائح أخرى

 // normal mode
  if(!divided_view_port)
    glViewport(0, 0, w, h);
else
{
    // right bottom
    glViewport(w/2, h/2, w, h);
    glLoadIdentity ();
    gluLookAt(5.0f, 5.0f, 5.0f,
              0.0f, 0.0f, 0.0f,
              0.0f, 1.0f, 0.0f);

    display();

    // left bottom
    glViewport(0, h/2, w/2, h);
    glLoadIdentity();
    gluLookAt (5.0f, 0.0f, 0.0f,
              0.0f, 0.0f, 0.0f,
              0.0f, 1.0f, 0.0f);

    display();

    // top right
    glViewport(w/2, 0, w, h/2);
    glLoadIdentity();
    gluLookAt(0.0f, 0.0f, 5.0f,
              0.0f, 0.0f, 0.0f,
              0.0f, 1.0f, 0.0f);

    display();

    // top left
    glViewport(0, 0, w/2, h/2);
    glLoadIdentity();
    gluLookAt(0.0f, 5.0f, 0.0f,
              0.0f, 0.0f, 0.0f,
              0.0f, 1.0f, 0.0f);

    display();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

if (w <= h)
    glOrtho(-2.0, 2.0, 
            -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, 
    -10.0, 100.0); 
else
    glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, 
    -2.0, 2.0, 
    -10.0, 100.0);

glMatrixMode(GL_MODELVIEW);

نعم،

ويجب عليك أيضا تغيير إعدادات المقصية للحصول على فصل نظيف بين وجهتين إذا كانت في نفس النافذة.

الحد الأدنى من ذلك

مشابه ل هذه الإجابة, ، ولكن أكثر مباشرة وجوازية. انتاج:

رمز:

#include <stdlib.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

static int width;
static int height;

static void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 0.0f, 0.0f);

    glViewport(0, 0, width/2, height/2);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glutWireTeapot(1);

    glViewport(width/2, 0, width/2, height/2);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glutWireTeapot(1);

    glViewport(0, height/2, width/2, height/2);
    glLoadIdentity();
    gluLookAt(0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
    glutWireTeapot(1);

    glViewport(width/2, height/2, width/2, height/2);
    glLoadIdentity();
    gluLookAt(0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
    glutWireTeapot(1);

    glFlush();
}

static void reshape(int w, int h) {
    width = w;
    height = h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return EXIT_SUCCESS;
}

جمع مع:

gcc -lGL -lGLU -lglut main.c

تم اختباره على OpenGL 4.5.0 NVIDIA 352.63، أوبونتو 15.10.

ToDo: أعتقد أنه في OpenGL الحديث، يجب عليك فقط تقديم القوام، ثم ضع تلك القوام Orchogonaly على الشاشة، راجع ذلك كنقطة انطلاق: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-stexture/

في GL 4، يمكنك تقديم الكثير من Viewports في تمريل واحد. يرى arb_viewport_array. والمفاهيم ذات الصلة.

فكر في OpenGL باعتباره شيئا أكثر من الأوامر التي تحضيرك لإخراجها إلى النافذة التي تعمل معها حاليا.

هناك أمران مع OpenGL الذي حتى البرامج التعليمية في Nehee لا تخبرك بأهمية:

WGLCREATECONTEX - التي تأخذ سياق جهاز نافذة DC، يمكن الحصول عليها من أي نافذة - سواء كان عنصر تحكم مستخدم أو نموذج Windows أو نافذة GL أو نافذة تطبيق أخرى (مثل المفكرة). يؤدي هذا إلى إنشاء سياق تشغيل OpenGL - يشير إلى كسياق موارد - الذي تستخدمه لاحقا مع ...

WGLMAKECECurrent - الذي يأخذ معلمين، سياق الجهاز الذي تتعامل معه (المعلمة مرت في سياق جهاز Windows في WGLCreatecontext) - وسياق الموارد الذي يعود.

الاستفادة من هذين الأمرين فقط - إليك نصيحتي:

يوفر البرنامج التعليمي Nehe حلا يرفع النافذة الموجودة فقط وشرائح الشاشة للرسم. إليك البرنامج التعليمي: http://nehe.gamedev.net/tutorial/multiple_viewports/20002/

الاستفادة من GLVIEPPORT ستحتاج إلى إعادة رسمها على كل تحديث.

هذه طريقة واحدة.

ولكن هناك طريقة أخرى غير تقليدية بيانيا والمعالج:

إنشاء نافذة لكل عرض من خلال الاستفادة من عنصر تحكم المستخدم.

كل نافذة لديها hwnd الخاصة بها.

احصل على العاصمة، ومعالجة WGLCREATECONTEXT، ثم، على جهاز كمبيوتر مؤقت (الألغام 30 إطارات ثانية واحدة)، إذا كشفت عن تغيير الحالة، فحدد WGLMAKECurrent لهذا العرض وإعادة رسمها. خلاف ذلك، فقط تخطي القسم بالكامل.

هذا يحفظ طاقة معالجة قيمة، ويقلل أيضا من التعليمات البرمجية من الاضطرار إلى إدارة حسابات النافذة و Viewport يدويا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top