0

初めて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++ コールバック インターフェイス (トランポリン/サンク):

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

2 に答える 2

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

次に、頂点配列を使用してメッシュを描画します

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

これらのメッシュ オブジェクト インスタンスへの参照をリストまたは配列に入れ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();
}
于 2012-07-27T23:55:42.277 に答える
1

関数の開始時に、次のdrawPolygonことを行う必要があります。glClear(GL_COLOR_BUFFER_BIT);

于 2012-07-27T21:45:06.650 に答える