[英]How to permanently draw things in OpenGL's Immediate mode?
我在創建路徑跟蹤器時遇到了一個小問題。
在我的項目中,我有一個對象,它通過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();
}
當直接繪制到窗口時(無論是否雙重緩沖都沒有區別),您不得對其內容在繪圖之間持久進行任何假設。 哎呀,嚴格來說,在事情結束之前,內容可能會在畫中期受損; 當然,在實踐中這不太可能發生,並且鑒於現代合成圖形系統,它幾乎被淘汰了。
您的應用程序尖叫為繪制到中間幀緩沖對象。 無論發生什么事情,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 (我使用render實現它紋理;渲染到渲染緩沖區和緩沖區blit到主幀緩沖區也適合你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.