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

时间:2014-08-04 10:53:16

标签: c++ opengl mfc

我试图掌握2D& amp; 3D现代OpenGL&所以以下只是我使用的代码的一部分。我不确定我做错了什么或错过了什么,但我已经把它缩小到了这个范围;我想查看X& amp;的开销。 Y&忽略z(即平面概述)。但也可以查看3D,因此对于3D z点需要有效。

在下面的示例中,点应显示垂直或水平线,但它们显示在一个角度上,即一个点的对角线或更改z值会影响顶部视图显示,而不应该这样。

非常感谢任何帮助,反馈或批评。 在此先感谢:)。

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);
    }
}

1 个答案:

答案 0 :(得分:1)

glVertexAttribPointer()来电的参数存在问题。这些是代码中的关键行:

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

glVertexAttribPointer()的第二个参数是属性的组件数。因此,此调用指定应将4个float组件用于属性0。

但是问题中的示例数据每个顶点只显示3个坐标。由于该属性只有3个组件,因此调用应为:

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