为什么即使相同的视口,投影矩阵和模型视图矩阵有不同的外观?

时间:2018-03-21 10:36:09

标签: opengl

这是我的场景 - 我正在使用固定功能管道

我在Draw函数中绘制了一个圆圈。在使用GLDrawCircle绘制圆圈之前的此功能中,我设置了viewportprojection矩阵和modelview矩阵。 modelview矩阵是一个单位矩阵。当我退出Draw功能时,我重置了viewport&弹出projectionmodelview矩阵。

另外,对于内部渲染引擎中的一些错误,我必须清除modelview矩阵堆栈(在绘制其他人员时有溢出)。所以在draw函数中,我清除堆栈,除了在堆栈中保留一个矩阵。

现在,在调用此绘图功能之前,有时我需要进行挑选。为此我正在做 -

  1. 启用标记
  2. 设置选择缓冲区
  3. GL_SELECT设置为渲染模式
  4. 调用Draw功能进行选择
  5. GL_RENDER设置为渲染模式&禁用标志
  6. 调用Draw绘图功能
  7. 问题 -

    如果我进行拣选,则圆圈显示不同。看起来相机已经倒退,圆圈看起来很小。

    但是我调试并检查了 - modelview矩阵始终是一个单位矩阵(在拾取和绘制时),viewport总是相同的,projection矩阵总是同样如此。我使用了以下方法来获取矩阵和视口 -

    glGetFloatv(GL_MODELVIEW_MATRIX, ptr)
    glGetFloatv(GL_PROJECTION_MATRIX, ptr)
    glGetIntegerv(GL_VIEWPORT, ptr)
    

    有谁能请你知道这里会发生什么?据我了解,如果viewportprojection矩阵和modelview矩阵相同,则对象应始终显示为相同。

    以下是完整代码 - 引擎调用不带参数的Draw函数。

    typedef struct tagGLInitDrawCircle
    {
    public:
        CVKCompass* m_pClass;
        LONG        m_id;
        BOOL        m_bRes;
        tagGLInitDrawCircle(MyClass* cclas, LONG id) : m_id(id), m_pClass(cclas)
        {
            if(m_pClass)
                m_bRes = m_pClass->DrawCircleInit(id);
            else
                m_bRes = FALSE;
        }
        ~tagGLInitDrawCircle()
        {
            if(m_pClass && m_bRes)
                m_pClass->DrawCircleTerm(m_id);
        }
    
    }   GLInitDrawCircle;
    
    
    static double g_cosh[100];
    static double g_sinh[100];
    static GuBoolean g_bCosSinInit = FALSE;
    
    static void GLDrawCircle(float r, float width, GuBoolean bFill)
    {
        if(bFill == FALSE)
        {
            glLineWidth(width/2);
            glBegin(GL_LINE_STRIP);
            for(int i=0 ; i<100 ; i++)
            {
                glVertex2f(r*g_cosh[i], r*g_sinh[i]);
            }
            glVertex2f(r*g_cosh[0], r*g_sinh[0]);
            glEnd();
            glLineWidth(width);
        }
        else
        {
            glBegin(GL_POLYGON);
            for(int i=0 ; i<100 ; i++)
            {
                glVertex2f(r*g_cosh[i], r*g_sinh[i]);
            }
            glEnd();
        }
    }
    
    
    
    
    
    
    
    void MyClass::Draw()
    {
    
        GLuint selectBuf[128];
    
        if (m_bSelectMode == TRUE)
        {
            memset(selectBuf, 0, 128 * sizeof(GLuint));
    
            glSelectBuffer(128, selectBuf);
            glRenderMode(GL_SELECT);
    
            glInitNames();
            glPushName(0);
    
            glMatrixMode(GL_PROJECTION);
            this->Draw(0);
            m_bSelectMode = FALSE;
            hits = glRenderMode(GL_RENDER);
        }
    
        this->Draw(1);
    }
    
    void MyClass::Draw(int type)
    {
        GLint depth;
        glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
        for (int i = 0; i < depth - 1; i++)
            glPopMatrix();
    
        GLUquadricObj* quadObj = (GLUquadricObj*)m_quadObj;
        GLUquadricObj* quadSphere = (GLUquadricObj*)m_quadSphere;
    
    
        if(g_bCosSinInit == FALSE)
        {
            g_bCosSinInit = TRUE;
            float pi_step = PI/50.f;
            for(int i=0 ; i<100 ; i++)
            {
                g_cosh[i] = cos(pi_step*i);
                g_sinh[i] = sin(pi_step*i);
            }
        }
        if(quadObj == NULL)
        {
    
            quadObj = gluNewQuadric();
    
    
            m_quadObj = (void*)quadObj;
        }
        if(quadSphere == NULL)
        {
            // Need to create a new quadratic object for the sphere
            quadSphere = gluNewQuadric();
            m_quadSphere = (void*)quadSphere;
        }
    
        GLInitDrawCircle initCircle(this, id, bResult);
    
    
        if(quadObj != NULL)
        {
            glMatrixMode(GL_MODELVIEW);
            glPushMatrix();
            glLoadIdentity();
    
    
            DrawCircle();
    
            glMatrixMode(GL_MODELVIEW);
            glPopMatrix();
    
        }
    }
    
    void MyClass::DrawCircle(void)
    {    
        glColor4ub(1, 1, 1, 1);
    
        if (m_bSelectMode )
        {
            glLoadName(10);
            GLDrawCircle(30, 1, FALSE);
        }
        else
        {
            GLDrawCircle(30, 1, FALSE);
        }
    
    
    }
    
    
    BOOL MyClass::DrawCircleInit(LONG id)
    {
    
        int width = 1351; 
        int height = 612;
    
        float scene_width = width / 10.0;
        float scene_height = height / 10.0;
    
        glGetIntegerv(GL_VIEWPORT, &m_viewport[0]);
    
        glViewport(5, 5, (GLsizei)scene_width, (GLsizei)scene_width);
    
    
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
    
    
        float ortho[6];
    
        ortho[0] = -scene_width;
        ortho[1] = scene_width  + offset_triad;
        ortho[2] = -scene_width - offset_height;
        ortho[3] = scene_width + offset_height;
        ortho[4] = -scene_width * 10;
        ortho[5] = scene_width * 10;
        glOrtho(ortho[0], ortho[1], ortho[2], ortho[3],
                ortho[4], ortho[5]);
    
    
        return TRUE;
    }
    
    
    BOOL MyClass::DrawCircleTerm(LONG id)
    {
    
        glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]);
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
    
        return TRUE;
    }
    

1 个答案:

答案 0 :(得分:0)

这个

let fm = FileManager.default
let path = Bundle.main.resourcePath!+("/photos")

let items = try! fm.contentsOfDirectory(atPath: path)

for item in items {
            if item.hasPrefix("nssl") {
                pictures.append(item)
            }
        }

将导致

   glMatrixMode(GL_PROJECTION);
   this->Draw(0);

因此,当您进行拣选时,您不会清除&#34; (严重:修复你的渲染器)你的模型视图矩阵堆栈,但是投影矩阵堆栈(很可能甚至是它的下溢)。