1 module draw; 2 3 import std.math; 4 5 import des.math.linear; 6 import des.util.stdext.algorithm; 7 import des.util.helpers; 8 9 import des.space; 10 11 import des.gl; 12 13 class Sphere : GLSimpleObject, SpaceNode 14 { 15 mixin SpaceNodeHelper; 16 17 protected: 18 19 GLBuffer pos, ind; 20 21 void prepareBuffers() 22 { 23 auto loc = shader.getAttribLocations( "pos" ); 24 pos = createArrayBuffer; 25 ind = createIndexBuffer; 26 setAttribPointer( pos, loc[0], 3, GLType.FLOAT ); 27 28 vec3[] buf; 29 30 vec3 sp( vec2 a, float R ) { return spheric(a) * R; } 31 vec3 cl( vec2 a, float R ) { return cylinder(a) * vec3(R,R,1); } 32 33 buf ~= amap!(a=>a+vec3(0,0,0))( amap!(a=>sp(a,R))( planeCoord( uivec2( resU, resV/2 ), vec2(0,PI*2), vec2(PI,PI/2) ) ) ); 34 buf ~= amap!(a=>a-vec3(0,0,0))( amap!(a=>sp(a,R*0.9))( planeCoord( uivec2( resU, resV/2 ), vec2(0,PI*2), vec2(PI/2,PI) ) ) ); 35 36 pos.setData( buf ); 37 38 ind.setData( triangleStripPlaneIndex( uivec2( resU+1, resV+2 ), uint.max ) ); 39 } 40 41 uint resU, resV; 42 float R; 43 44 public: 45 46 this( float r, uint u, uint v ) 47 { 48 R = r; 49 resU = u; 50 resV = v; 51 import std.file; 52 super( newEMM!CommonGLShaderProgram( 53 parseGLShaderSource( 54 readText( 55 appPath( "..", "data", "shaders", "object.glsl" ) 56 )))); 57 prepareBuffers(); 58 } 59 60 void draw( Camera cam ) 61 { 62 shader.setUniform!col4( "col", col4(1,0,0,1) ); 63 glEnable( GL_PRIMITIVE_RESTART ); 64 glPrimitiveRestartIndex(uint.max); 65 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 66 shader.setUniform!mat4( "prj", cam.projection.matrix * cam.resolve(this) ); 67 drawElements( DrawMode.TRIANGLE_STRIP ); 68 glDisable( GL_PRIMITIVE_RESTART ); 69 } 70 } 71 72 vec2[] planeCoord( uivec2 res, vec2 x_size=vec2(0,1), vec2 y_size=vec2(0,1) ) 73 { 74 vec2[] ret; 75 76 float sx = (x_size[1] - x_size[0]) / res.u; 77 float sy = (y_size[1] - y_size[0]) / res.v; 78 79 foreach( y; 0 .. res.y+1 ) 80 foreach( x; 0 .. res.x+1 ) 81 ret ~= vec2( x_size[0] + sx * x, y_size[0] + sy * y ); 82 83 return ret; 84 } 85 86 vec3 spheric( in vec2 c ) pure 87 { return vec3( cos(c.x) * sin(c.y), sin(c.x) * sin(c.y), cos(c.y) ); } 88 89 vec3 cylinder( in vec2 c ) pure 90 { return vec3( cos(c.x), sin(c.x), c.y ); } 91 92 uint[] triangleStripPlaneIndex( uivec2 res, uint term ) 93 { 94 uint[] ret; 95 foreach( y; 0 .. res.y-1 ) 96 { 97 ret ~= [ y*res.x, (y+1)*res.x ]; 98 foreach( x; 1 .. res.x ) 99 ret ~= [ y*res.x+x, (y+1)*res.x+x ]; 100 ret ~= term; 101 } 102 return ret; 103 }