简体   繁体   English

现代OpenGL 2D和3D绘图问题

[英]Modern OpenGL 2D & 3D drawing issue

I'm trying to grasp 2D & 3D with modern OpenGL & so the following is only a portion of code I'm using. 我正在尝试使用现代OpenGL来掌握2D和3D,因此以下只是我正在使用的部分代码。 I'm not sure what I'm doing wrong or missing, but I have narrowed it down to this; 我不确定自己在做什么或做错了什么,但是我将其范围缩小了。 I'd like to view overhead of just X & Y & ignore z (ie flat overview). 我只想查看X和Y的开销,而忽略z(即平面概览)。 But also view 3D, so for 3D z points need to be valid. 而且还可以查看3D,因此对于3D z点需要有效。

In the following example points should display vertical or horizontal lines, but they display on an angle ie diagonal or changing z value for a point affects overhead view display when it shouldn't. 在以下示例中,点应显示垂直或水平线,但是它们以一定角度显示,即对角线或点的z值更改会影响顶视图的显示,而不应显示。

Any help, feedback or critique would be much appreciated. 任何帮助,反馈或批评将不胜感激。 Thanks in advance :). 提前致谢 :)。

X/Y/Z points example & get sent to SetObjectData() function;


//horizontal
-70.0,20.0,50.0
25.0,20.00,0.0
70.0,20.00,-50.0

//vertical
20.0,80.0,100.0
20.0,20.0,100.0
20.0,-90.0,-100.0

m_oglWindow_OverHead.CreateGLContext(Rect, this);
m_oglWindow_OverHead.InitParm(60,0.0,0.0,0.0,1.0,1.0,1.0,0,0,-150.00);
m_oglWindow_OverHead.PrepareScene(1.0,1.0,1.0,1,2);


void OpenGLRenderer::InitParm(float fovy, float RotateX, float RotateY, float RotateZ, float ScaleX, float ScaleY, float ScaleZ, float TranslateX, float TranslateY, float TranslateZ)
{
    m_fovy = fovy;

    m_RotateX = RotateX;
    m_RotateY = RotateY;
    m_RotateZ = RotateZ;
    //following currently not in use elsewhere, to be implemented.
    //m_ScaleX = ScaleX;
    //m_ScaleY = ScaleY;
    //m_ScaleZ = ScaleZ;
    //m_TranslateX = TranslateX;
    //m_TranslateY = TranslateY;
    //m_TranslateZ = TranslateZ;
}


void OpenGLRenderer::PrepareScene(float r, float g, float b, float alpha, int iViewType)
{
    wglMakeCurrent(m_hdc, m_hrc);
    glClearColor(r, b, g, alpha); //background to clear with.

    if(iViewType == VIEW_2D)
    {
        InitShaderProgram();

        glDisable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        ExitOnGLError(_T("ERROR: Could not set OpenGL depth testing options"));

        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
        glFrontFace(GL_CCW);
        ExitOnGLError(_T("ERROR: Could not set OpenGL culling options"));

        if(m_RotateX !=0)
        {
            const float angle = m_RotateX;
            m_glmModelMatrix = glm::rotate(m_glmModelMatrix,angle, glm::vec3(1,0,0)); //x,y,z       
        }
        if(m_RotateY !=0)
        {
            const float angle = m_RotateY;
            m_glmModelMatrix = glm::rotate(m_glmModelMatrix,angle, glm::vec3(0,1,0)); //x,y,z       
        }
        if(m_RotateZ !=0)
        {
            const float angle = m_RotateZ;
            m_glmModelMatrix = glm::rotate(m_glmModelMatrix,angle, glm::vec3(0,0,1)); //x,y,z       
        }

        m_glmViewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -50.0f)); // Create view matrix which will translate back 50 units
        m_glmProjectionMatrix = glm::ortho<float>(-250.0f,250.0f,250.0f,-250.0f,-100.0f,250.0f); //world coordinates

    }
    wglMakeCurrent(NULL, NULL);
}


void OpenGLRenderer::SetObjectData(const gl_vvCords vVerticesA, gl_vvCords vVerticesB)
{
    wglMakeCurrent(m_hdc, m_hrc);

    unsigned int TotalNumObjects = m_NumberVAOs = vVerticesA.size();
    m_vGLSizeCount.clear();
    m_vVaoID.clear();
    m_vVaoID.resize(m_NumberVAOs+2);
    m_vVboID.clear();
    m_vVboID.resize(m_NumberVAOs+2);

    glGenVertexArrays(TotalNumObjects, &m_vVaoID[0]);
    int m_GLIntSize  = 4;

    for(unsigned int iObjectNum=0;iObjectNum<TotalNumObjects;iObjectNum++)
    {
        m_GLSizeCount = vVerticesA.at(iObjectNum).size();
        m_vGLSizeCount.push_back(m_GLSizeCount);


        //VAO setup
        glBindVertexArray(m_vVaoID[iObjectNum]);
        glGenBuffers(1, &m_vVboID[iObjectNum]);
        glBindBuffer(GL_ARRAY_BUFFER, m_vVboID[iObjectNum]);

        glBufferData(GL_ARRAY_BUFFER, sizeof(vVerticesA.at(iObjectNum)), &vVerticesA.at(iObjectNum).at(0), GL_STATIC_DRAW);

        glVertexAttribPointer((GLuint)0, m_GLIntSize, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);

            GLfloat r=0.0,b=0.0,g=0.0,a=1.0;
            std::vector<GLfloat> vColor;
            for(int i=0;i<m_GLSizeCount;i++)
            {
                vColor.push_back(r);
                vColor.push_back(b);
                vColor.push_back(g);
                vColor.push_back(a);
            }

            glGenBuffers(1, &m_vVboID[iObjectNum+1]);
            glBindBuffer(GL_ARRAY_BUFFER, m_vVboID[iObjectNum+1]);
            glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vColor.size(), &vColor[0], GL_STATIC_DRAW);
            glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
            glEnableVertexAttribArray(1);
    }
    wglMakeCurrent(NULL, NULL);
}



void OpenGLRenderer::DrawScene()
{
    wglMakeCurrent(m_hdc, m_hrc);

    switch(m_iViewType)
    {
        case VIEW_2D:
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                glUseProgram(ShaderIDs[0]);
                    for(int i=0;i<m_NumberVAOs;i++)
                    {
                        if(m_vGLSizeCount.size() > 0 )
                        {
                            if(m_iShowObjectType1.at(i) == 1 && ((m_iShowObjectType2.at(i) == 1 || m_iShowObjectType2.at(i) == 2  )))
                            {
                                glUniformMatrix4fv(m_ProjectionMatrixUniformLocation, 1, GL_FALSE, &m_glmProjectionMatrix[0][0]); // Send our projection matrix to the shader
                                glUniformMatrix4fv(m_ViewMatrixUniformLocation, 1, GL_FALSE, &m_glmViewMatrix[0][0]); // Send our view matrix to the shader
                                glUniformMatrix4fv(m_ModelMatrixUniformLocation, 1, GL_FALSE, &m_glmModelMatrix[0][0]); // Send our model matrix to the shader
                                glBindVertexArray(m_vVaoID.at(i));
                                glDrawArrays(GL_LINE_STRIP, 0, m_GLSizeCount);
                                ExitOnGLError(_T("ERROR: Could not draw item"));
                            }
                        }
                    }
                glUseProgram(0);
            }
            break;

        default:
            break;
    }

    //--------------------------------
    SwapBuffers(m_hdc);
    wglMakeCurrent(NULL, NULL);
}



const GLchar* VertexShader = 
{
    "#version 330\n"\
    "layout(location=0) in vec4 in_Position;\n"\
    "layout(location=1) in vec4 in_Color;\n"\
    "out vec4 ex_Color;\n"\
    "uniform mat4 vsModelMatrix;\n"\
    "uniform mat4 vsViewMatrix;\n"\
    "uniform mat4 vsProjectionMatrix;\n"\
    "void main(void)\n"\
    "{\n"\
        "gl_Position = (vsProjectionMatrix * vsViewMatrix * vsModelMatrix) * in_Position;\n"\
        "ex_Color = in_Color;\n"\
    "}\n"
};


const GLchar* FragmentShader = 
{
    "#version 330\n"\
    "in vec4 ex_Color;\n"\
    "out vec4 out_Color;\n"\
    "void main(void)\n"\
    "{\n"\
    "   out_Color = ex_Color;\n"\
    "}\n"\
};


void OpenGLRenderer::InitShaderProgram()
{
    ShaderIDs[0] = glCreateProgram();
    ExitOnGLError(_T("ERROR: Could not create the shader program"));

        ShaderIDs[1] = glCreateShader(GL_VERTEX_SHADER);
        ShaderIDs[2] = glCreateShader(GL_FRAGMENT_SHADER);

        glShaderSource(ShaderIDs[1], 1, &VertexShader, NULL);
        glCompileShader(ShaderIDs[1]);
        glShaderSource(ShaderIDs[2], 1, &FragmentShader, NULL);
        glCompileShader(ShaderIDs[2]);

        glAttachShader(ShaderIDs[0], ShaderIDs[1]);
        glAttachShader(ShaderIDs[0], ShaderIDs[2]);

    glLinkProgram(ShaderIDs[0]);
    ExitOnGLError(_T("ERROR: Could not link the shader program"));

    m_ModelMatrixUniformLocation = glGetUniformLocation(ShaderIDs[0], "vsModelMatrix");
    m_ViewMatrixUniformLocation = glGetUniformLocation(ShaderIDs[0], "vsViewMatrix");
    m_ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIDs[0], "vsProjectionMatrix");
    ExitOnGLError(_T("ERROR: Could not get shader uniform locations"));
};


void OpenGLRenderer::OnSize(UINT nType, int cx, int cy)
{
    if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED)
        return;

    if(m_hdc != NULL)
    {
        wglMakeCurrent(m_hdc, m_hrc);

        switch(m_iViewType)
        {
            case VIEW_2D:
            {
                CurrentWidth = GetViewPortWidth();//cx;
                CurrentHeight = GetViewPortHeight();//cy;
                glViewport(0, 0, CurrentWidth, CurrentHeight);

                glUseProgram(ShaderIDs[0]);
                glUniformMatrix4fv(m_ProjectionMatrixUniformLocation, 1, GL_FALSE, &m_glmProjectionMatrix[0][0]); // Send our projection matrix to the shader
                glUniformMatrix4fv(m_ViewMatrixUniformLocation, 1, GL_FALSE, &m_glmViewMatrix[0][0]); // Send our view matrix to the shader
                glUniformMatrix4fv(m_ModelMatrixUniformLocation, 1, GL_FALSE, &m_glmModelMatrix[0][0]); // Send our model matrix to the shader
                glUseProgram(0);
            }
                break;
        }

        //necessary for resizing windows
        GetWindowRect(m_rect);
        MoveWindow(m_oldWindow.left,m_oldWindow.top,GetViewPortWidth(),GetViewPortHeight(),TRUE);
        GetWindowRect(m_rect);

        wglMakeCurrent(NULL, NULL);
    }
}

There's a problem with the arguments to your glVertexAttribPointer() calls. glVertexAttribPointer()调用的参数有问题。 These are the critical lines from your code: 这些是代码中的关键行:

int m_GLIntSize  = 4;
...
glVertexAttribPointer((GLuint)0, m_GLIntSize, GL_FLOAT, GL_FALSE, 0, 0);

The second argument to glVertexAttribPointer() is the number of components for the attribute. glVertexAttribPointer()的第二个参数是属性的组件数。 So this call specifies that 4 float components should be used for attribute 0. 因此,此调用指定应将4个float组件用于属性0。

But the sample data in your question shows only 3 coordinates per vertex. 但是问题中的样本数据每个顶点仅显示3个坐标。 Since the attribute has only 3 components, the call should be: 由于该属性只有3个组成部分,因此调用应为:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM