c++ - glutDisplayFunc 显示垃圾

标签 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++回调接口(interface)(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();
 }

最佳答案

首先,原始代码完全是过度设计的。这可能是原始混淆的一部分。此外,在不丢弃大部分代码的情况下,您也无能为力。例如,用自己的对象实例表示每个多边形(三角形)的效率几乎是最低的。您通常不想这样做。表示模型的常用方法是Mesh,它由顶点属性列表/数组和面列表组成,面列表本质上是定义三角形的三元组列表,使得向上网格的表面。上课形式

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

关于c++ - glutDisplayFunc 显示垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11695977/

相关文章:

带有 cURL 的 Android NDK 包含错误

c++ - Allegro vs OpenGL 速度/效率明智

c++ - OpenGL 照明位置固定在不需要的位置

c++ - 在 Mac OSX 中以编程方式阻止屏幕保护程序

opengl - 写入浮点 FBO 时的低精度和钳位

java - 我是否总是必须为 libGDX 中的可渲染对象指定索引数组?

c++ - 为什么要两次使用静态库才能使编译工作?

c++ - Piglatin 输出仍无法正常工作

c++ - 从函数中抛出内部对象异常是否合法

c++ - FLTK 关闭窗口