我在这里看到了几个问题。
较小的一个是您在 for 循环中的缩进renderFunction
有点误导。该循环总是有 4 次迭代,每次打印一次随机变量。
第二个是你似乎误解了 的意思glutDisplayFunc(renderFunction);
。正如 这里所解释的,这仅注册renderFunction
为 glut 的默认“显示”回调,并且:
GLUT 根据窗口的重新显示状态确定何时触发显示回调。
glutMainLoop
将调用注册的回调,直到程序完成。请注意,glutMainLoop
永远不会返回。程序被未处理的信号或主窗口的关闭中断。这意味着,如果您最小化并恢复窗口,glut 将需要重新绘制其内容并再次调用显示回调 ( renderFunction
)。
由于您无法轻松控制,或者不应该尝试控制 glut 何时调用显示功能,我建议您确保显示功能只会绘制到屏幕上。您可以在main
函数中生成(并打印)随机值,并将随机变量设为全局变量,以便从renderFunction
. 或者,通过在第一次执行时修改标志的条件语句来保护采样的执行和打印的执行:
// at global scope (before renderFunction)
generated = false
declare random variables
...
// inside renderFunction
if (generated = false) {
generate RV
print RV
generated = true
}
display lines
在任何一种情况下,您都需要存储所有 16 个随机变量,因为您生成 4 个随机值 4 次(并且您将所有这些随机值用于绘图/打印)。我建议将它们存储在int r[4][4];
这是我的首选版本:
#include "GL/glut.h"
#include "GL/gl.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
#define XWidth 700 // Clipping window size 700*700
#define YHeight 700
int r[4][4];
void renderFunction() {
/*Clear Information from last draw
Sets the current clearing color for use in clearing
color buffers in RGBA mode.
*/
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
//Set line width
glLineWidth(1);
//(x,y) coordinates as in pixels
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, XWidth, 0, YHeight, -1, 1);
//Set line color
glColor3f(1.0, 0.0, 0.0);
//random num generated
for(int i=0;i<4;i++){
//Begin LINE coordinates
glBegin(GL_LINES);
glVertex2d(r[i][0], r[i][1]);
glVertex2d(r[i][2], r[i][3]);
//End LINE coordinate
glEnd();
}
//Forces previously issued OpenGL commands to begin execution
glFlush();
}
// Driver program to test above functions
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
//Set Output Window Size
glutInitWindowSize(XWidth,YHeight);
//Set the position of Output window corresponding to Screen
glutInitWindowPosition(100,100);
//Create the Window
glutCreateWindow("OpenGL - Classify line among three classes");
//Set handler functions for drawing
glutDisplayFunc(renderFunction);
//random num generated
for(int i=0;i<4;i++) {
r[i][0] = rand() % 1000;
r[i][1] = rand() % 1000;
r[i][2] = rand() % 1000;
r[i][3] = rand() % 1000;
cout<<r[i][0] << " " << r[i][1]<<" "<<r[i][2]<<" "<<r[i][3]<<" i is "<<i<<endl;
}
//Start the main loop
glutMainLoop();
return 0;
}
编辑
原始海报在评论部分提出了一个有趣的问题转折点。我在这里解释一下:
如果您需要大量(10000+)行并且内存是一个巨大的问题,我们是否仍然可以获得最初想要的行为:随机值只打印一次,并且每次重新绘制屏幕时行不会改变位置。
答案是:是的!保持您最初拥有的非常低的内存占用的一种方法是使用“if”保护技巧的组合,每次通过重新播种随机数生成器来打印和生成(相同的)随机值。
#include "GL/glut.h"
#include "GL/gl.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
#define XWidth 700 // Clipping window size 700*700
#define YHeight 700
bool printed;
int random_seed;
void renderFunction() {
/*Clear Information from last draw
Sets the current clearing color for use in clearing
color buffers in RGBA mode.
*/
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
//Set line width
glLineWidth(1);
//(x,y) coordinates as in pixels
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, XWidth, 0, YHeight, -1, 1);
//Set line color
glColor3f(1.0, 0.0, 0.0);
// =============================================
// set the seed of your random number generator
// ---------------------------------------------
srand(random_seed);
// =============================================
//random num generated
for(int i=0;i<4;i++) {
int r1 = rand() % 1000;
int r2 = rand() % 1000;
int r3 = rand() % 1000;
int r4 = rand() % 1000;
//Begin LINE coordinates
glBegin(GL_LINES);
glVertex2d(r1, r2);
glVertex2d(r3,r4);
//End LINE coordinate
glEnd();
// ***********************************************
// make sure the values are only printed the first
// time around
// ***********************************************
if (!printed) {
cout<<r1<<" "<<r2<<" "<<r3<<" "<<r4<<" i is "<<i<<endl;
}
}
printed = true;
//Forces previously issued OpenGL commands to begin execution
glFlush();
}
// Driver program to test above functions
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
//Set Output Window Size
glutInitWindowSize(XWidth,YHeight);
//Set the position of Output window corresponding to Screen
glutInitWindowPosition(100,100);
//Create the Window
glutCreateWindow("OpenGL - Classify line among three classes");
//Set handler functions for drawing
glutDisplayFunc(renderFunction);
// =======================================
// generate a random seed for the lines
// ---------------------------------------
srand(time(0));
random_seed = rand();
// =======================================
// ==========================================
// initialize the printing guard to "false",
// i.e. "did not print the random values yet"
// ------------------------------------------
printed = false;
// ==========================================
//Start the main loop
glutMainLoop();
return 0;
}
请注意,此方法与原始问题中的代码非常相似,添加的代码使用注释明确分隔。好处是它使用恒定数量的内存,无论您要绘制多少行。不利的一面是调用rand()
有点昂贵,因此您通常需要在高速(前一个版本)和低内存消耗(后一个版本)之间进行权衡。