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 回调结束,让显示器知道需要更新帧缓冲区。这允许多边形管理器遍历每个多边形并将屏幕变白。在未来的迭代中,白色屏幕将被多边形绘制算法所取代。
如标题所述,我试图在 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 回调结束,让显示器知道需要更新帧缓冲区。这允许多边形管理器遍历每个多边形并将屏幕变白。在未来的迭代中,白色屏幕将被多边形绘制算法所取代。