C++ 通过引用第二个 object 传递 3D 数组,无法操作

C++ pass 3D array by reference to second object, can't manipulate

如标题所述,我试图在 object 的 object 中操作 3D 数组。两个 object 具有完全相同的函数声明,但只有 parent object 能够操作数组(将帧缓冲区变为白色)。我试图操作的 3D 数组包含在 main 的范围内。 parent object 操作 3D 数组没有问题,但是当传递给 parent object 的 child 时,没有任何变化。

我将帧缓冲区(3D 数组)从主缓冲区传递到多边形管理器,在这里我可以通过将所有值设置为 1.0 来使帧缓冲区变白。但是,即使单击几次后我的系统中有许多多边形和点,我也无法将帧缓冲区进一步传递给多边形管理器中包含的多边形 object。我在多边形管理器中注释掉 "white-out" for 循环并尝试在多边形中再次使用它。没有任何反应。

Main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <math.h>

#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "polygon_manager.h"

#define ImageW 400
#define ImageH 400

float framebuffer[ImageH][ImageW][3];

PolygonManager polygon_manager;

// Draws the scene
void drawit( void ) {
    glDrawPixels( ImageW, ImageH, GL_RGB, GL_FLOAT, framebuffer );
    glFlush();
}

// Clears framebuffer to black
void clearFramebuffer() {
    int i, j;

    for ( i = 0; i < ImageH; i++ ) {
        for ( j = 0; j < ImageW; j++ ) {
            framebuffer[i][j][0] = 0.0;
            framebuffer[i][j][1] = 0.0;
            framebuffer[i][j][2] = 0.0;
        }
    }
}

void display( void ) {
    /** THIS IS WHERE I AM MODIFYING THE BUFFER */
    polygon_manager.add_points( framebuffer );

    drawit();
}

void onMouse( int button, int state, int x, int y ) {
    if ( state == GLUT_DOWN ) {
        if ( button == GLUT_LEFT_BUTTON ) {
            polygon_manager.add_point( x, y );
        }

        if ( button == GLUT_RIGHT_BUTTON ) {
            polygon_manager.add_final_point( x, y );
        }
        cout << polygon_manager;
    }
}

void init( void ) {
    clearFramebuffer();
}

int main( int argc, char** argv ) {
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
    glutInitWindowSize( ImageW, ImageH );
    glutInitWindowPosition( 100, 100 );
    glutCreateWindow( "Robert Timm - Homework 3" );
    init();
    glutMouseFunc( onMouse );
    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}

polygon_manager.h

#ifndef POLYGON_MANAGER_H_
#define POLYGON_MANAGER_H_

#include <string>
#include <vector>
#include <iostream>

#include "point.h"
#include "color.h"
#include "polygon.h"

const int MAX_POLYGONS = 10;

using namespace std;

class PolygonManager {

public:

    PolygonManager() {
        create_new_poly = true;
    }

    void add_point( int x, int y ) {
        if ( create_new_poly ) {
            if ( polygons.size() >= MAX_POLYGONS ) {
                cerr << "Max number of polygons added (" << MAX_POLYGONS << ")"
                        << endl;
                return;
            }
            create_new_poly = false;
            Polygon p;
            polygons.push_back( p );
        }
        polygons.back().add_point( x, y );
    }

    void add_final_point( int x, int y ) {
        if ( polygons.back().size() < 2 ) {
            cerr << "Polygon requires at least three points "
                    << "to be considered a polygon!" << endl;
            return;
        }
        if ( create_new_poly ) {
            cerr << "Right-click already pressed. Left click "
                    << "to add a new polygon." << endl;
            return;
        }
        create_new_poly = true;
        polygons.back().add_point( x, y );
    }

    void add_points( float (&framebuffer)[400][400][3] ) {
        for ( int i = 0; i < polygons.size(); ++i ) {
            polygons[i].add_points( framebuffer );
        }
        /** EDITING BUFFER HERE CHANGES SCREEN FROM BLACK TO WHITE
             AS INTENDED */
        for ( int i = 0; i < 400; ++i ) {
            for ( int j = 0; j < 400; ++j ) {
                framebuffer[j][i][0] = 1.0;
                framebuffer[j][i][1] = 1.0;
                framebuffer[j][i][2] = 1.0;
            }
        }

    }

    friend ostream& operator<<( ostream& os, const PolygonManager& pm ) {
        os << "Polygons:" << endl;
        for ( auto &polygon : pm.polygons ) {
            os << "=> " << polygon << endl;
        }
        return os;
    }

private:

    bool create_new_poly;
    vector<Polygon> polygons;

};

#endif

polygon.h

#ifndef POLYGON_H_
#define POLYGON_H_

#include <vector>
#include <string>
#include <iostream>

#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "color.h"
#include "point.h"

const int MAX_POINTS = 10;

using namespace std;

class Polygon {

public:
    Polygon() {

    }

    int size() {
        return points.size();
    }

    void add_point( int x, int y ) {
        if ( points.size() >= (MAX_POINTS - 1) ) {
            cerr << "This polygon already has nine points, add a final "
                    << "tenth point by right-clicking the screen." << endl;
            return;
        }
        Point p( x, y );
        points.push_back( p );
    }

    void add_final_point( int x, int y ) {
        Point p( x, y );
        points.push_back( p );
    }

    void add_points( float (&framebuffer)[400][400][3] ) {
        for ( auto &point : points ) {
            int y = 400 - 1 - point.get_y();
            int x = point.get_x();
        }
        /** EDITING BUFFER HERE DOES NOTHING, SCREEN
         *  SHOULD TURN WHITE
         */
        for ( int i = 0; i < 400; ++i ) {
            for ( int j = 0; j < 400; ++j ) {
                framebuffer[j][i][0] = 1.0;
                framebuffer[j][i][1] = 1.0;
                framebuffer[j][i][2] = 1.0;
            }
        }
    }

    friend ostream& operator<<( ostream& os, const Polygon& poly ) {
        for ( int i = 0; i < poly.points.size(); ++i ) {
            if ( i < poly.points.size() - 1 ) {
                os << poly.points[i] << ", ";
            } else {
                os << poly.points[i];
            }
        }
        return os;
    }

private:
    Color color;
    vector<Point> points;

};

#endif

多边形管理器正在编辑帧缓冲区,但只编辑了一次。我对Main.cpp "display"中注册的回调有误解。本来我以为display会被调用很多次,而实际上它只在应用程序打开时被调用一次。我补充说,

glutPostRedisplay();

我的 onMouse 回调结束,让显示器知道需要更新帧缓冲区。这允许多边形管理器遍历每个多边形并将屏幕变白。在未来的迭代中,白色屏幕将被多边形绘制算法所取代。