glutDisplayFunc显示垃圾

时间:2012-07-27 21:35:54

标签: c++ opengl

我第一次尝试将openGL合并到我的c ++代码中。作为一个初学者,我创建了这个非常原始的代码,它定义了一个名为polygon的类,并且应该使用方法polygon.draw()显示一个多边形。现在,下面的所有内容都驻留在一个main.cpp文件中,虽然为了便于阅读,我在这里分成了一段:

问题是,下面的代码编译并运行正常。只有在创建名为“simple”的窗口时,才会显示垃圾(主要是从我的计算机背景屏幕收集:(。

首先,类多边形:

#include <GL/glut.h>
#include "utility.hpp"
#include <vector>

void init(void);

class nikPolygon{
public:
    std::vector<nikPosition> m_vertices;
    nikColor m_color;
    double m_alpha;

    // constructors
    // without alpha (default is 1.0)
    nikPolygon(std::vector<nikPosition> vList, nikColor c):
    m_vertices(vList), m_color(c), m_alpha(1.0){

    }

    nikPolygon(std::vector<nikPosition> vList, nikColor c, double a):
    m_vertices(vList), m_color(c), m_alpha(a){

    }

    // default constructor
    nikPolygon(){

    }


    // member functions
    // add vertex
    void addVertex(nikPosition v)              { m_vertices.push_back(v); }
    // remove vertex
    void removeVertex(nikPosition v);
    // adjust vertex
    void modifyVertex(unsigned int vIndex, nikPosition newPosition);
    // fill color
    void setColor(nikColor col)               { m_color = col; }
    // set alpha
    void setAlpha(double a)                   { m_alpha = a; }
    // display
    void drawPolygon(void){

        // color the objet
        glColor4f(m_color.red, 
                  m_color.green, 
                  m_color.blue, 
                  m_alpha);

        // construct polygon
        glBegin(GL_POLYGON);    
        for (std::vector<nikPosition>::iterator it = m_vertices.begin();
             it != m_vertices.end(); it++)
            glVertex2f(it->x, it->y);
        glEnd();

        // send to screen
        glFlush();

    }

    void draw(void);
};

然后是c / c ++回调接口(trampoline / thunk):

 // for c++/c callback
 nikPolygon* currentPolygon;

 extern "C"
 void drawCallback(void){
     currentPolygon->drawPolygon();
 }

 void nikPolygon::draw(){
     currentPolygon = this;
     glutDisplayFunc(drawCallback);
 }

然后其余部分:

 // initialize openGL etc
 void init(void){

     // set clear color to black
     glClearColor(0.0, 0.0, 0.0, 0.0);

     // set fill color to white
     glColor3f(1.0, 1.0, 1.0);

     // enable transperancy
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

     // setup standard orthogonal view with clipping
     // box as cube of side 2 centered at origin
     // this is the default view
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

 }


 int main(int argc, char** argv){

     nikPolygon poly;

     poly.addVertex(nikPosition(-0.5, -0.5));
     poly.addVertex(nikPosition(-0.5, 0.5));
     poly.addVertex(nikPosition(0.5, 0.5));
     poly.addVertex(nikPosition(0.5, -0.5));

     poly.setColor(nikColor(0.3, 0.5, 0.1));
     poly.setAlpha(0.4);


     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
     glutInitWindowSize(500, 500);
     glutInitWindowPosition(0, 0);

     glutCreateWindow("simple");
     init();
     poly.draw();
     glutMainLoop();
 }

2 个答案:

答案 0 :(得分:1)

drawPolygon功能开始时,您需要执行glClear(GL_COLOR_BUFFER_BIT);

答案 1 :(得分:1)

首先,原始代码完全过度设计。这可能是原始混淆的一部分。此外,你可以做很多事情来修复代码,而不会丢掉大部分代码。例如,用自己的对象实例表示每个多边形(三角形)的效率低得多。你通常不想这样做。表示模型的常用方法是 Mesh ,它由顶点属性的列表/数组和面列表组成,它实质上是定义三角形的3元组列表,在网格的表面上。在课堂表格中

class Mesh
{
    std::vector<float> vert_position;
    std::vector<float> vert_normal;
    std::vector<float> vert_texUV;

    std::vector<unsigned int> faces_indices;

public:
    void draw();
};

然后绘制网格,使用Vertex Arrays

void Mesh::draw()
{
    // This is the API as used up to including OpenGL-2.1

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXCOORD_ARRAY);

    // sizes of attributes depend on actual application
    glVertexPointer(3, GL_FLOAT, 0, &vert_position[0]);
    glNormalPointer(GL_FLOAT, 0, &vert_normal[0]);
    glTexCoordPointer(2, GL_FLOAT, 0, &vert_texUV[0]);

    glDrawElements(GL_TRIANGLES, faces_indices.size(), GL_UNSIGNED_INT, &faces_indices[0]);
}

将这些Mesh对象实例的引用放入列表或数组中,并在设置适当的转换后调用draw方法在显示函数中迭代它。

std::list<Mesh> list_meshes;

void display()
{
    clear_framebuffer();

    set_viewport_and_projection();

    for(std::list<Mesh>::iterator mesh_iter = list_meshes.begin();
        mesh_iter != list_meshes.end();
        mesh_iter++) {
        mesh_iter->draw()
    }

    swap_buffers();
}