glutDisplayFunc显示垃圾

glutDisplayFunc displays garbage

本文关键字:显示 glutDisplayFunc      更新时间:2023-10-16

我第一次尝试将openGL合并到我的c++代码中。作为一个开始,我制作了这个非常原始的代码,它定义了一个名为polygon的类,应该用polygong.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++回调接口(蹦床/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();
 }

首先,原始代码完全被过度设计了。这可能是最初混乱的一部分。此外,在不抛出大部分代码的情况下修复代码也没有什么可做的。例如,用自己的对象实例表示每个多边形(三角形)几乎是低效的。你通常不想这样做。表示模型的常用方法是网格,它由顶点属性的列表/数组和面列表组成,面列表本质上是定义三角形的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();
};

然后使用顶点阵列绘制网格

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

drawPolygon函数开始时,您需要执行glClear(GL_COLOR_BUFFER_BIT);