1 module armos.graphics.bufferentity; 2 3 import armos.graphics; 4 import armos.graphics.mesh; 5 import armos.graphics.material; 6 import armos.graphics.buffer; 7 import armos.graphics.buffermesh; 8 import armos.graphics.shader; 9 10 /++ 11 +/ 12 class BufferEntity { 13 import armos.utils.scoped; 14 public{ 15 /// 16 this(Mesh mesh, Material material, in BufferUsageFrequency freq, in BufferUsageNature nature){ 17 this(new BufferMesh(mesh, freq, nature), material); 18 } 19 20 /// 21 this(BufferBundle bufferBundle, Material material){ 22 _material = material; 23 _bufferBundle = bufferBundle; 24 updateShaderAttribs(); 25 } 26 27 /// 28 this(){} 29 30 /// 31 BufferEntity updateShaderAttribs(){ 32 auto scopedVao = _bufferBundle.vao.scoped; 33 import std.algorithm; 34 _bufferBundle.attrs.keys.filter!(key => _bufferBundle.attrs[key].type!=BufferType.ElementArray && _bufferBundle.attrs[key].type!=BufferType.DrawIndirect) 35 .each!((key){ 36 if(_bufferBundle.attrs[key].size > 0){ 37 _bufferBundle.attrs[key].begin; 38 _material.shader.attr(key); 39 _bufferBundle.attrs[key].end; 40 } 41 }); 42 return this; 43 } 44 45 BufferEntity updateBuffers(){ 46 import std.algorithm; 47 _bufferBundle.attrs.keys.each!((key){ 48 _bufferBundle.attr(key).updateGlBuffer; 49 }); 50 return this; 51 } 52 53 /// 54 void begin(){ 55 _material.begin; 56 _bufferBundle.vao.begin; 57 } 58 59 /// 60 void end(){ 61 _bufferBundle.vao.end; 62 _material.end; 63 } 64 65 /// 66 BufferBundle bufferBundle(){ 67 return _bufferBundle; 68 } 69 70 /// 71 BufferEntity bufferBundle(BufferBundle bb){ 72 _bufferBundle = bb; 73 if(_material && _material.shader) updateShaderAttribs(); 74 return this; 75 } 76 77 /// 78 BufferEntity mesh(Mesh mesh, in BufferUsageFrequency freq, in BufferUsageNature nature){ 79 _bufferBundle = new BufferMesh(mesh, freq, nature); 80 if(_material && _material.shader) updateShaderAttribs(); 81 return this; 82 } 83 84 /// 85 Material material(){ 86 return _material; 87 } 88 89 /// 90 BufferEntity material(armos.graphics.Material m){ 91 _material = m; 92 return this; 93 } 94 95 /// 96 BufferEntity shader(Shader shader){ 97 if(_material)_material = new DefaultMaterial; 98 _material.shader = shader; 99 if(_bufferBundle) updateShaderAttribs(); 100 return this; 101 } 102 103 void draw(){ 104 updateBuffers; 105 updateShaderAttribs; 106 drawWithoutUpdate; 107 } 108 109 /// 110 void drawWithoutUpdate(){ 111 const scopedVao = scoped(_bufferBundle.vao); 112 const scopedMaterial = scoped(_material); 113 const iboScope = scoped(_bufferBundle.attrs["index"]); 114 115 import armos.graphics.renderer; 116 _material.shader.uniform("modelViewMatrix", viewMatrix * modelMatrix); 117 _material.shader.uniform("projectionMatrix", projectionMatrix); 118 _material.shader.uniform("modelViewProjectionMatrix", modelViewProjectionMatrix); 119 _material.shader.uniform("textureMatrix", textureMatrix); 120 _material.shader.enableAttribs(); 121 int elements; 122 import derelict.opengl3.gl; 123 glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &elements); 124 import std.conv; 125 immutable int size = (elements/GLuint.sizeof).to!int; 126 glDrawElements(_primitiveMode.getGLPrimitiveMode, size, GL_UNSIGNED_INT, null); 127 _material.shader.disableAttribs(); 128 } 129 130 void draw(in armos.graphics.PolyRenderMode renderMode){ 131 import derelict.opengl3.gl; 132 glPolygonMode(GL_FRONT_AND_BACK, getGLPolyRenderMode(renderMode)); 133 draw; 134 glPolygonMode(GL_FRONT_AND_BACK, getGLPolyRenderMode(currentStyle.polyRenderMode)); 135 } 136 137 /++ 138 entityをワイヤフレームで描画します. 139 +/ 140 void drawWireFrame(){ 141 draw(armos.graphics.PolyRenderMode.WireFrame); 142 }; 143 144 /++ 145 entityの頂点を点で描画します. 146 +/ 147 void drawVertices(){ 148 draw(armos.graphics.PolyRenderMode.Points); 149 }; 150 151 /++ 152 meshの面を塗りつぶして描画します. 153 +/ 154 void drawFill(){ 155 draw(armos.graphics.PolyRenderMode.Fill); 156 }; 157 158 /// 159 BufferEntity primitiveMode(in armos.graphics.PrimitiveMode mode){ 160 _primitiveMode = mode; 161 return this; 162 } 163 164 /// 165 armos.graphics.PrimitiveMode primitiveMode()const{ 166 return _primitiveMode; 167 } 168 }//public 169 170 private{ 171 armos.graphics.BufferBundle _bufferBundle; 172 armos.graphics.Material _material; 173 armos.graphics.PrimitiveMode _primitiveMode = armos.graphics.PrimitiveMode.Triangles; 174 }//private 175 }//class BufferEntity