从本质上来说,我在创建路径跟踪器时遇到了一个小问题。
在我的项目中,我有一个对象,该对象通过while循环中完成的更新功能不断有机地移动。我使用即时模式并将玩家表示为一个正方形,我想这样做,以便每次更新时都将对象绘制在其当前位置,但也要让它绘制其先前的位置,以便向路径蚀刻点对象在移动。我很确定我们可以通过正常绘制位置来实现此目的,但是在while循环中在此实例之后不清除所有内容,但是我不知道如何执行此操作。
编辑:对于需要这些代码的人,一定要了解该代码尤其不符合该问题,并且我做了大量的概括(例如将粒子称为对象),因此该问题的基本要点是可以理解的:
#include "PerlinNoise.hpp"
#include "Particle.hpp"
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cmath>
#include <vector>
using namespace siv;
float map(float oValue, float oMin, float oMax, float nMin, float nMax)
{
float oRange = (oMax - oMin);
float nRange = (nMax - nMin);
return(((oValue - oMin) * nRange)/oRange) + nMin;
}
void drawRectangle(float x, float y, float xr, float yr, float R, float G, float B)
{
glBegin(GL_QUADS);
glColor3f(R,G,B);
glVertex2f(x,y);
glVertex2f(x+xr,y);
glVertex2f(x+xr,y+yr);
glVertex2f(x,y+yr);
glEnd();
}
void drawLine(float x, float y, float xr, float yr, float rotation)
{
float radius = sqrt(xr*xr + yr*yr);
float a0 = asin(yr/radius);
float tangle = a0+rotation;
//std::cout<<tangle*180/M_PI<<std::endl;
glBegin(GL_LINES);
glColor3f(.1,.1,.1);
glVertex2f(x,y);
glVertex2f(x + sin(tangle)*radius,y + cos(tangle)*radius);
glEnd();
}
int main()
{
float inc = 0.1;
int scl = 20;
int cols,rows;
Particle particles[100000];
//V2D flowfield[cols*rows];
GLFWwindow* window;
if (!glfwInit())
return 1;
int width = 800;
int height = 800;
window = glfwCreateWindow(width, height, "Window", NULL, NULL);
cols = floor(width/scl);
rows = floor(height/scl);
V2D flowfield[cols*rows];
float zoff = 0;
if (!window) {
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
if(glewInit()!=GLEW_OK)
std::cout<<"Error"<<std::endl;
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glfwGetFramebufferSize(window, &width, &height);
glOrtho(0, width*(width/height), height, 0, -2, 2);
PerlinNoise png = PerlinNoise(1);
while(!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(0.11, 0.14, 0.17, 1);
float yoff = 0;
for(int y = 0; y < rows; y++)
{
float xoff = 0;
for(int x = 0; x < cols; x++)
{
double noise = map(png.noise((double)xoff, (double)yoff, (double)zoff),-1,1,0,1);
double angle = noise * 8 *M_PI;
//std::cout<<angle/(2*M_PI)<<std::endl;
int index = x + y * cols;
V2D v = V2D(cos(angle), sin(angle));
v.normalize();
v = V2D(v.x*5,v.y*5);
flowfield[index] = v;
//drawLine(x*scl, y*scl, scl, 0, atan2(v.x, v.y));
//drawRectangle(x*scl,y*scl,scl,scl,noise,noise,noise);
xoff += inc;
}
yoff += inc;
zoff += 0.0001;
}
for(int i = 0; i < 100000; i++)
{
particles[i].follow(flowfield);
particles[i].update();
particles[i].show();
}
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}
答案 0 :(得分:3)
直接在窗口上绘制时(无论是否具有双缓冲,都没有影响),您不得假设其内容在绘制之间是持久的。哎呀,严格来说,内容可能会在抽签中途甚至完成之前就损坏;当然,在实践中这不太可能发生,并且考虑到现代合成图形系统,实际上已将其消除。
您的应用程序尖叫到绘制到中间帧缓冲区对象。无论发生什么情况,FBO均保证保留其内容;您也可以随时在FBO的后备缓冲区中添加更多图形。
OpenGL官方Wiki在https://www.khronos.org/opengl/wiki/Framebuffer_Object上描述了FBO
很久以前,我编写了一个简单的代码示例(使用许多过时的旧版OpenGL);绘图是遗留的,但是FBO的部分已经像10年前一样完成了:https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/minimalfbo/minimalfbo.c(我使用渲染到纹理来实现;渲染到renderbuffer和缓冲区blit到主帧缓冲区也对您有用)。