#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
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++){
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();
cout<<r1<<" "<<r2<<" "<<r3<<" "<<r4<<" i is "<<i<<endl;}
//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);
//Start the main loop
glutMainLoop();
return 0;
}
当我执行上面的程序时,它工作正常。但问题是,当我打印随机生成的变量值 r1
r2
r3
r4
时,它们正在打印 8 次或有时 12 次。这意味着 glutDisplayFunc(renderFunction);
多次调用 renderFunction
,这不是必需的。
如何控制这种行为。我希望只调用一次 renderFunction
。
更新:我想创建 4 条线,正好形成 4 条线,但是当我打印坐标时,它们显示出我上面提到的意外行为。
最佳答案
我在这里看到了几个问题。
较小的一个是您在 renderFunction
中对 for 循环的缩进有点误导。该循环总是恰好有 4 次迭代,每次都打印一次随机变量。
第二个是您似乎误解了 glutDisplayFunc(renderFunction);
的含义。正如解释的那样 here ,这只会将 renderFunction
注册为过剩的默认“显示”回调,并且:
GLUT determines when the display callback should be triggered based on the window's redisplay state.
glutMainLoop
将调用已注册的回调,直到程序完成。请注意,glutMainLoop
永远不会返回。程序被未处理的信号或主窗口关闭中断。这意味着如果您最小化并恢复窗口,glut 将要重新绘制其内容并再次调用显示回调 (renderFunction
)。
由于在 glut 调用 display 函数时您无法轻易控制,或者不应尝试控制,因此我建议您确保 display 函数只会绘制到屏幕上。您可以在 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;
}
编辑 原始发帖人在评论部分提出了一个有趣的问题转折。我将在这里解释一下:
If you require a large (10000+) number of lines and memory is a huge concern, can we still get the originally desired behavior:random values printed only once and lines not changing position every time the screen gets repainted.
答案是:是的!保持您最初拥有的非常低的内存占用的一种方法是使用“if”保护技巧的组合,每次通过 re-seeding the random number generator 打印和生成(相同的)随机值。 .
#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()
有点昂贵,因此您通常需要在高速(前一个版本)和低内存消耗(后一个版本)之间进行权衡。
关于c++ - opengl/glut 中的 renderDisplayFunc 不止一次调用 myfunc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18485690/