GPGPU labor VI Rekurzv algoritmusok labirintus Kezdeti teendk
GPGPU labor VI. Rekurzív algoritmusok labirintus
Kezdeti teendők • Tantárgy honlapja, rekurzív algoritmusok • A labor kiindulási alapjának letöltése (lab 6_base. zip), kitömörítés a D: GPGPU könyvtárba • D: GPGPUlabslab 6_glsllab 6_glsl. sl n indítása • Project tulajdonságai – Configuration Properties – Debugging – Working Directory = $(Project. Dir). . bin
Próba
Adat buffer • Globális Framebuffer* data. Buffer; Shader* generate. Shader; int labyrinth. Size = 64; bool recalc. Labyrinth = true; float noise. Seed = (float) rand() / (float) RAND_MAX; float noise. Start = 0. 5; float noise. Scale = 0. 5; • Init data. Buffer = new Framebuffer(labyrinth. Size, 2, true, false); generate. Shader = new Shader("passthrough. vert", "generate. frag"); glut. Reshape. Window(labyrinth. Size * window. Scale, labyrinth. Size * window. Scale);
• Display gl. Clear. Color(0. 17 f, 0. 4 f, 0. 6 f, 1. 0 f); gl. Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(recalc. Labyrinth){ int level = data. Buffer->get. Levels() - 1; data. Buffer->set. Render. Target(level); GLenum ca = GL_COLOR_ATTACHMENT 0; gl. Draw. Buffers(1, &ca); gl. Clear. Color(1, 0, 1, 0); gl. Clear(GL_COLOR_BUFFER_BIT); ca = GL_COLOR_ATTACHMENT 1; gl. Draw. Buffers(1, &ca); gl. Clear. Color(0. 5, 0. 5); gl. Clear(GL_COLOR_BUFFER_BIT); float scale = noise. Start; for(level = level - 1; level >= 0; level--){ data. Buffer->set. Render. Target(level); generate. Shader->enable(); generate. Shader->bind. Uniform. Int("level", level); generate. Shader->bind. Uniform. Float("noise. Scale", scale); generate. Shader->bind. Uniform. Float("noise. Seed", noise. Seed * 16. 0); generate. Shader->bind. Uniform. Texture("input. Tex 1", data. Buffer->get. Color. Buffer(0), 0); generate. Shader->bind. Uniform. Texture("input. Tex 2", data. Buffer->get. Color. Buffer(1), 1); generate. Shader->bind. Uniform. Texture("noise. Tex", noise. Texture->get. Texture. Handle(), 2); fullscreen. Quad->render(generate. Shader); generate. Shader->disable(); scale *= noise. Scale; } } data. Buffer->disable. Render. Target(); recalc. Labyrinth = false;
• Display folyt: gl. Viewport(0, 0, window. Width, window. Height); simple. Shader->enable(); simple. Shader->bind. Uniform. Texture("input. Tex", data. Buffer->get. Color. Buffer(1), 0); fullscreen. Quad->render(simple. Shader); simple. Shader->disable(); glut. Swap. Buffers();
• Keyboard case 'q': noise. Scale *= 1. 01; recalc. Labyrinth = true; std: : cout<<"noise. Scale: "<<noise. Scale<<" noise. Scale. Start: "<<noise. Start<<std: : endl; break; case 'a': noise. Scale *= 0. 99; recalc. Labyrinth = true; std: : cout<<"noise. Scale: "<<noise. Scale<<" noise. Scale. Start: "<<noise. Start<<std: : endl; break; case 'w': noise. Start *= 1. 01; recalc. Labyrinth = true; std: : cout<<"noise. Scale: "<<noise. Scale<<" noise. Scale. Start: "<<noise. Start<<std: : endl; break; case 's': noise. Start *= 0. 99; recalc. Labyrinth = true; std: : cout<<"noise. Scale: "<<noise. Scale<<" noise. Scale. Start: "<<noise. Start<<std: : endl; break;
generate. frag #version 130 out vec 4 outcolor[2]; in vec 2 f. Tex. Coord; uniform sampler 2 D input. Tex 1; uniform sampler 2 D input. Tex 2; uniform sampler 2 D noise. Tex; uniform int level; uniform float noise. Scale; uniform float noise. Seed; void main() { ivec 2 coord = ivec 2(gl_Frag. Coord. xy); vec 4 R = texture. Lod(input. Tex 2, f. Tex. Coord, level + 1); vec 4 rand = texel. Fetch(noise. Tex, ivec 2(mod(coord + ivec 2(noise. Seed, 0), ivec 2(16))), 0); } outcolor[1] = R + noise. Scale * (rand - 0. 5);
Próba
Generate. frag outcolor[1] = R + noise. Scale * (rand - 0. 5); ivec 2 coord. Base = coord / 2; ivec 2 coord. Rel = ivec 2(mod(vec 2(coord), vec 2(2))); int index = coord. Rel. x + coord. Rel. y * 2; vec 4 V; vec 4 P = texel. Fetch(input. Tex 1, coord. Base, level + 1); V = P; //szülő cella öröklése outcolor[0] = V;
• Display: simple. Shader->bind. Uniform. Texture("input. Tex", data. Buffer->get. Color. Buffer(1), 0); helyett simple. Shader->bind. Uniform. Texture("input. Tex", data. Buffer->get. Color. Buffer(0), 0);
Próba Nem elég informatív!!
Labirintus vizualizációja • Globális Shader* visualize. Shader; Framebuffer* visualize. Tex; • Init: visualize. Tex = new Framebuffer( data. Buffer->get. Width() * 2 + 1, data. Buffer->get. Height() * 2 + 1, 1, false); visualize. Shader = new Shader("passthrough. vert", "visualize. frag");
• Display visualize. Tex->set. Render. Target(); visualize. Shader->enable(); visualize. Shader->bind. Uniform. Texture("input. Tex", data. Buffer>get. Color. Buffer(0), 0); fullscreen. Quad->render(visualize. Shader); visualize. Shader->disable(); visualize. Tex->disable. Render. Target(); gl. Viewport(0, 0, window. Width, window. Height); simple. Shader->enable(); simple. Shader->bind. Uniform. Texture("input. Tex", visualize. Tex ->get. Color. Buffer(0), 0); fullscreen. Quad->render(simple. Shader); simple. Shader->disable(); glut. Swap. Buffers();
visualize. frag #version 130 out vec 4 outcolor; in vec 2 f. Tex. Coord; uniform sampler 2 D input. Tex; void main() { outcolor = vec 4(0); ivec 2 coord = ivec 2(gl_Frag. Coord. xy); if(coord. x == 0){ if(texel. Fetch(input. Tex, coord / 2, 0). z == 1 && mod(coord. y, 2) == 1) outcolor = vec 4(1); } else if(coord. y == 0){ if(texel. Fetch(input. Tex, coord / 2, 0). w == 1 && mod(coord. x, 2) == 1) outcolor = vec 4(1); } else{ coord = coord - ivec 2(1); ivec 2 coord. Base = coord / 2; ivec 2 coord. Rel = ivec 2(mod(vec 2(coord), vec 2(2))); vec 4 Vp = texel. Fetch(input. Tex, coord. Base, 0); } } if(coord. Rel. x == 0 && coord. Rel. y == 0) outcolor = vec 4(1); else if(coord. Rel. x == 1 && coord. Rel. y == 0 && Vp. x == 1) outcolor = vec 4(1); else if(coord. Rel. x == 0 && coord. Rel. y == 1 && Vp. y == 1) outcolor = vec 4(1);
Próba
Csak az átjárók felét tartsuk meg! generate. frag vec 4 M[4] = vec 4[4](vec 4(1, 1, 0, 0), vec 4 D[4] = vec 4[4](vec 4(1, 1, 0, 1), vec 4(0, 1, 1, 0), vec 4(1, 0, 0, 1), vec 4(0, 0, 1, 1)); vec 4(0, 1, 1, 0), vec 4(1, 1, 1, 1), vec 4(1, 0, 1, 1)); vec 4 inv(vec 4 v){return vec 4(1. 0) - v; } vec 4 uni(vec 4 v 1, vec 4 v 2){ return min(vec 4(1. 0), v 1 + v 2); }
generate. frag V=P helyett V = P * D[index];
Próba
Belső falakat tüntessük el! generate. frag V = P * D[index]; V = uni(V, M[index]);
Próba
Cella felosztás generate. frag vec 4 W 1; // fuggoleges v. vizszintes vec 4 W 2; // bal/lenn - jobb/fenn if(R. x < 0. 25){ // right W 1 = vec 4(1, 0, 1, 0); W 2 = vec 4(M[index]. x == 1); } else if(R. x < 0. 5) { // top W 1 = vec 4(0, 1, 0, 1); W 2 = vec 4(M[index]. y == 1); } else if(R. x < 0. 75){ // left W 1 = vec 4(1, 0, 1, 0); W 2 = vec 4(M[index]. z == 1); } else{ // bottom W 1 = vec 4(0, 1, 0, 1); W 2 = vec 4(M[index]. w == 1); } V = V * uni(W 1, W 2), inv(M[index]));
Próba Labirintus kész!
Legrövidebb út keresés • Globális Shader* search. Shader; Framebuffer* shortest. Path; GLuint streamout. Bufffer[2]; GLuint output. Query; bool start. Point. Changed = true; bool endpoint. Changed = true; float start. X = 0; float start. Y = labyrinth. Size -1; float end. X = labyrinth. Size - 1; float end. Y = labyrinth. Size - 1;
• Init shortest. Path = new Framebuffer(labyrinth. Size, 1, false, true); gl. Gen. Buffers(2, streamout. Bufffer); gl. Bind. Buffer(GL_ARRAY_BUFFER_ARB, streamout. Bufffer[0]); gl. Buffer. Data(GL_ARRAY_BUFFER_ARB, labyrinth. Size*4*sizeof(float)*2, 0, GL_DYNAMIC_DRAW); gl. Bind. Buffer(GL_ARRAY_BUFFER_ARB, streamout. Bufffer[1]); gl. Buffer. Data(GL_ARRAY_BUFFER_ARB, labyrinth. Size*4*sizeof(float)*2, 0, GL_DYNAMIC_DRAW); search. Shader = new Shader("search. vert", "search. frag", "search. geom"); gl. Gen. Queries(1, &output. Query);
void recursion( float start. X, float start. Y, float start. Z, float start. W) { gl. Bind. Buffer. Base(GL_TRANSFORM_FEEDBACK_BUFFER, 0, streamout. Bufffer[0]); gl. Begin. Transform. Feedback(GL_POINTS); gl. Begin. Query(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, output. Query); gl. Point. Size(1); gl. Begin(GL_POINTS); gl. Vertex 4 f(start. X, start. Y, start. Z, start. W); gl. End(); gl. End. Query(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); gl. End. Transform. Feedback(); GLint out. Point. Count = 0; GLint succ = 0; while(!succ) gl. Get. Query. Objectiv(output. Query, GL_QUERY_RESULT_AVAILABLE, &succ); gl. Get. Query. Objectiv(output. Query, GL_QUERY_RESULT, &out. Point. Count); //std: : cout << "points written: " << out. Point. Count << std: : endl; succ = 0;
gl. Enable. Client. State(GL_VERTEX_ARRAY); int bb = 0; while(out. Point. Count > 0) { gl. Bind. Buffer. Base(GL_TRANSFORM_FEEDBACK_BUFFER, 0, streamout. Bufffer[(bb+1)%2]); gl. Begin. Transform. Feedback(GL_POINTS); gl. Begin. Query(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, output. Query); gl. Bind. Buffer. ARB(GL_ARRAY_BUFFER_ARB, streamout. Bufffer[bb]); gl. Vertex. Pointer(4, GL_FLOAT, 0, NULL); gl. Draw. Arrays(GL_POINTS, 0, out. Point. Count); gl. End. Transform. Feedback(); gl. End. Query(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); while(!succ) gl. Get. Query. Objectiv(output. Query, GL_QUERY_RESULT_AVAILABLE, &succ); gl. Get. Query. Objectiv(output. Query, GL_QUERY_RESULT, &out. Point. Count); succ = 0; bb = (bb + 1) % 2; } } gl. Disable. Client. State(GL_VERTEX_ARRAY);
• Display if(recalc. Labyrinth) {. . start. Point. Changed = true; } if(start. Point. Changed) { endpoint. Changed = true; shortest. Path->set. Render. Target(); gl. Clear. Color(0, 0, 0, 0); gl. Clear(GL_COLOR_BUFFER_BIT); search. Shader->enable(); search. Shader->bind. Uniform. Texture("input. Tex 1", data. Buffer->get. Color. Buffer(0), 0); search. Shader->bind. Uniform. Texture("input. Tex 2", shortest. Path->get. Color. Buffer(0), 1); recursion(start. X, start. Y, 0, 5); search. Shader->disable(); shortest. Path->disable. Render. Target(); start. Point. Changed = false; }. . . simple. Shader->bind. Uniform. Texture("input. Tex", shortest. Path->get. Color. Buffer(0), 0);
Mouse if(GLUT_LEFT_BUTTON == button && GLUT_UP == state) { start. X = x/window. Scale; start. Y = y/window. Scale; start. Point. Changed = true; } else if(GLUT_RIGHT_BUTTON == button && GLUT_UP == state) { end. X = x/window. Scale; end. Y = y/window. Scale; endpoint. Changed = true; }
simple. frag void main() { outcolor = texture(input. Tex, f. Tex. Coord); outcolor = outcolor. bbbb / 400; }
search. vert #version 130 in vec 4 position; //out vec 4 celldata; void main(void) { gl_Position = gl_Vertex; }
search. geom #version 130 #extension GL_EXT_geometry_shader 4 : enable uniform sampler 2 D input. Tex 1; //neighbour information uniform sampler 2 D input. Tex 2; //celldata texture (shortest path + path dir) out vec 4 celldata; void main(void){ vec 2 window. Size = texture. Size(input. Tex 2, 0); vec 4 vertexdata = gl_Position. In[0]; //read neighbour information vec 4 neigh. Inf = texel. Fetch(input. Tex 1, ivec 2(vertexdata. xy), 0); vec 4 stored. Celldata = texel. Fetch(input. Tex 2, ivec 2(vertexdata. xy), 0); if(stored. Celldata. z > vertexdata. z || stored. Celldata. w == 0){ celldata = vertexdata; vec 2 w. Coord = vertexdata. xy / window. Size * 2. 0 - 1. 0; gl_Position = vec 4(w. Coord, 0, 1); Emit. Vertex(); }. . .
search. geom //emit neighbours if connected //right if(neigh. Inf. r == 1) { celldata = vertexdata; celldata. x += 1; celldata. z += 1; celldata. w = 3; stored. Celldata = texel. Fetch(input. Tex 2, ivec 2(celldata. xy), 0); if((stored. Celldata. z > celldata. z || stored. Celldata. w == 0) && celldata. x < window. Size. x) { vec 2 w. Coord = celldata. xy / window. Size * 2. 0 - 1. 0; gl_Position = vec 4(w. Coord, 0, 1); Emit. Vertex(); } }. . . Többi irányra is End. Primitive(); }
search. frag #version 130 out vec 4 outcolor; in vec 4 celldata; void main() { outcolor = celldata; }
Próba
Bejárás • Globális Shader* walk. Path. Shader; • Init walk. Path. Shader = new Shader("search. vert", "red. frag", "walkpath. geom");
Bejárás if(endpoint. Changed) { labyrinth. Tex->set. Render. Target(); visualize. Shader->enable(); visualize. Shader->bind. Uniform. Texture("input. Tex", buffer>get. Color. Buffer(0), 0); fullscreen. Quad->render(visualize. Shader); visualize. Shader->disable(); walk. Path. Shader->enable(); walk. Path. Shader->bind. Uniform. Texture("input. Tex 1", shortest. Path>get. Color. Buffer(0), 0);
Display visualize. Tex->set. Render. Target(); visualize. Shader->enable(); visualize. Shader->bind. Uniform. Texture("input. Tex", data. Buffer->get. Color. Buffer(0), 0); fullscreen. Quad->render(visualize. Shader); visualize. Shader->disable(); visualize. Tex->disable. Render. Target(); Helyett. .
if(endpoint. Changed) { visualize. Tex->set. Render. Target(); visualize. Shader->enable(); visualize. Shader->bind. Uniform. Texture("input. Tex", data. Buffer->get. Color. Buffer(0), 0); fullscreen. Quad->render(visualize. Shader); visualize. Shader->disable(); walk. Path. Shader->enable(); walk. Path. Shader->bind. Uniform. Texture("input. Tex 1", shortest. Path->get. Color. Buffer(0), 0); recursion(end. X, end. Y, 0, 5); walk. Path. Shader->disable(); . . .
gl. Begin(GL_POINTS); gl. Color 3 f(0, 0, 1); gl. Vertex 3 f((float)(start. X * 2 + 1) / (float)(2 * labyrinth. Size) * 2. 0 f 1. 0 f, (float)(start. Y * 2 + 1) / (float)(2 * labyrinth. Size) * 2. 0 f - 1. 0 f, 0); gl. Color 3 f(0, 1, 0); gl. Vertex 3 f((float)(end. X * 2 + 1) / (float)(2 * labyrinth. Size) * 2. 0 f 1. 0 f, (float)(end. Y * 2 + 1) / (float)(2 * labyrinth. Size) * 2. 0 f - 1. 0 f, 0); gl. End(); visualize. Tex->disable. Render. Target(); } endpoint. Changed = false;
Display gl. Viewport(0, 0, window. Width, window. Height); simple. Shader->enable(); simple. Shader->bind. Uniform. Texture("input. Tex", visualize. Tex->get. Color. Buffer(0), 0); fullscreen. Quad->render(simple. Shader); simple. Shader->disable();
simple. frag void main() { outcolor = texture(input. Tex, f. Tex. Coord); outcolor = outcolor. bbbb / 400; }
walkpath. geom #version 130 #extension GL_EXT_geometry_shader 4 : enable uniform sampler 2 D input. Tex 1; //cell information out vec 4 celldata; void main(void) { vec 2 window. Size = texture. Size(input. Tex 1, 0); vec 4 vertexdata = gl_Position. In[0]; vec 4 stored. Celldata = texel. Fetch(input. Tex 1, ivec 2(vertexdata. xy), 0); if(stored. Celldata. z == 0) return; . . .
if(stored. Celldata. w == 1) // right { celldata = vertexdata; celldata. x += 1; vec 2 w. Coord = (celldata. xy * 2 + 1) / (window. Size * 2 + 1) * 2. 0 - 1. 0; gl_Position = vec 4(w. Coord, 0, 1); Emit. Vertex(); }. . . többi irányra is End. Primitive(); }
red. frag #version 130 out vec 4 outcolor; in vec 4 celldata; void main() { outcolor = vec 4(1, 0, 0, 1); }
Próba
Vége
- Slides: 47