glutDisplayFunc显示垃圾 [英] glutDisplayFunc displays garbage

查看:89
本文介绍了glutDisplayFunc显示垃圾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试第一次将openGL合并到我的c ++代码中.首先,我编写了非常原始的代码,该代码定义了一个名为polygon的类,并应使用polygon.draw()方法显示多边形.现在,下面的所有内容都驻留在一个main.cpp文件中,尽管为了便于阅读,我将其分为以下部分:

I am trying to incorporate openGL into my c++ code for the first time. As a start up, I made this very primitive code, which defines a class called polygon and should display a polygon with a method polygon.draw(). Right now, everything below resides in a single main.cpp file, though for easy reading I am separating into section here:

问题是,以下代码编译并正常运行.仅当创建名为简单"的窗口时,才会显示垃圾(主要是从我的计算机背景屏幕中收集的:(.

The problem is, the below code compiles and runs alright. Only when the window named "simple" is created, displays garbage (mostly collected from my computer background screen :(.

首先,类多边形:

#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):

Then the c/c++ callback 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 ,它由顶点属性的列表/数组和面的列表组成,面的列表实质上是定义三角形的三元组的列表,在网格表面上.上课形式

First and foremost, the original code is completely overengineered. This may be part of the original confusion. Also there's not really much you can do, to fix the code, without throwing out most of it. For example representing each polygon (triangle) with a own object instance is about as inefficient as it can get. You normally do not want to do this. The usual approach at representing a model is a Mesh, which consists of a list/array of vertex attributes, and a list of faces, which is in essence a list of 3-tuples defining the triangles, making up the surface of the mesh. In class form

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

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

Then to draw a mesh you use 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方法.

You put references to these Mesh object instances into a list, or array, and iterate over that in the display function, calling the draw method, after setting the appropriate transformation.

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

这篇关于glutDisplayFunc显示垃圾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆