【问题标题】:glutDisplayFunc displays garbageglutDisplayFunc 显示垃圾
【发布时间】:2012-07-28 07:55:42
【问题描述】:

我第一次尝试将 openGL 合并到我的 c++ 代码中。作为一个开始,我编写了这个非常原始的代码,它定义了一个名为多边形的类,并且应该使用方法 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();
 }

【问题讨论】:

  • 请注意GL_POLYGON 只处理凸多边形。其他一切都需要您自己进行三角测量。
  • 另外,默认的绕线顺序是逆时针,而不是顺时针。
  • 您的代码是其中之一“嗯,是的,当然……但是……为什么?” glutDisplayFunc 并不意味着在每个几何基础上使用。您只注册一次显示回调函数,然后在该回调中迭代现有几何图形,将绘图调用分派给它。
  • 另外,您正在将顶点推入 std::vector。为什么不将此向量作为顶点数组传递,而不是调用立即模式函数。
  • @datenwolf:那只是因为我正在尝试第一手的 openGL。顶点数组似乎是一个更好的解决方案。

标签: c++ opengl


【解决方案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();
}

【讨论】:

    【解决方案2】:

    drawPolygon 函数的开头,您需要执行 glClear(GL_COLOR_BUFFER_BIT);

    【讨论】:

    • 您好philipvr,非常感谢您的建议。我不知何故(愚蠢地)那条线会清除屏幕:p...顺便说一句,现在它不像以前那样显示垃圾,而是保持黑色(即不显示多边形。)。 :(
    • 我明白了....这是我在其他地方的错误,即在位置结构中,我只有整数值,因此没有正确获取顶点:(...谢谢很多...现在,解决了!
    猜你喜欢
    • 2013-07-10
    • 2016-07-08
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多