d - OpenGL Square not Rendering Correctly -
correct rendering:

incorrect rendering:

the correct rendering me using 6 vertices per square. incorrect rendering when try re-use vertices , down 4 vertices per square.
here code (i call addsquare 6 times in example):
module src.ultramesh; import grape; import std.conv; import std.stdio; import grape.shader; import std.math; import std.stdio; import std.traits; import std.conv; import std.algorithm; import std.array; import std.range; class ultramesh { appender!(float[]) vertices; appender!(int[]) indices; appender!(ubyte[]) color; bool wireframe; ubyte colorr, colorb, colorg, colora; gluint indicebuffer; gluint vertexbuffer; gluint colorbuffer; gluint vaoid; int indicebuffersize = 0; int vertexbuffersize = 0; int colorbuffersize = 0; bool updatebuffers = true; glint camerauniformlocation; this() { if (program null) { initializeshader(); } wireframe = false; colorr = to!ubyte(255); colorb = to!ubyte(0); colorg = to!ubyte(0); colora = to!ubyte(255); vertices = appender!(float[]); //points indices = appender!(int[]); //edges color = appender!(ubyte[]); glgenvertexarrays(1, &vaoid); // create our vertex array object glbindvertexarray(vaoid); // bind our vertex array object can use //create buffer indices glgenbuffers(1, &indicebuffer); glbindbuffer(gl_element_array_buffer, indicebuffer); glbufferdata(gl_element_array_buffer, int.sizeof*3, null, gl_dynamic_draw); glbindbuffer(gl_element_array_buffer, 0); //create buffer vertices glgenbuffers(1, &vertexbuffer); //bind buffer can work on glbindbuffer(gl_array_buffer, vertexbuffer); glbufferdata(gl_array_buffer, float.sizeof*9, null, gl_dynamic_draw); //bind attribute can stuff glbindattriblocation(program, 0, cast(char*)"position"); //get attribute location? glint _location = glgetattriblocation(program, cast(char*)"position"); //enable drawing glenablevertexattribarray(_location); //describe data of attribute? glvertexattribpointer(_location, 3, gl_float, gl_false, 0, null); //unbind buffer glbindbuffer(gl_array_buffer, 0); //create buffer colors glgenbuffers(1, &colorbuffer); //bind buffer can work on glbindbuffer(gl_array_buffer, colorbuffer); glbufferdata(gl_array_buffer, byte.sizeof*12, null, gl_dynamic_draw); //bind attribute can stuff glbindattriblocation(program, 1, cast(char*)"color"); //get attribute location? _location = glgetattriblocation(program, cast(char*)"color"); //enable drawing glenablevertexattribarray(_location); //describe data of attribute? glvertexattribpointer(_location, 4, gl_unsigned_byte, gl_false, 0, null); //unbind buffer glbindbuffer(gl_array_buffer, 0); camerauniformlocation = glgetuniformlocation(program, cast(char*)"pvmmatrix"); glenablevertexattribarray(0); // disable our vertex array object glbindvertexarray(0); // disable our vertex buffer object } ~this() { gldeletebuffers(1, &indicebuffer); gldeletebuffers(1, &vertexbuffer); gldeletebuffers(1, &colorbuffer); } void updateallbuffers() { updateindicebufferpartial(0, to!int(indices.data.length)); updatevertexbufferpartial(0, to!int(vertices.data.length)); updatecolorbufferpartial(0, to!int(color.data.length)); } void updatecolorbuffer() { updatecolorbufferpartial(0, to!int(color.data.length)); }void updatevertexbuffer() { updatevertexbufferpartial(0, to!int(vertices.data.length)); }void updateindicebuffer() { updateindicebufferpartial(0, to!int(indices.data.length)); } void reserveindicebuffer(int length) { indicebuffersize = length; glbindbuffer(gl_element_array_buffer, indicebuffer); glbufferdata(gl_element_array_buffer, int.sizeof*length, null, gl_dynamic_draw); glbindbuffer(gl_element_array_buffer, 0); } void updateindicebufferpartial(int start, int length) { if (indicebuffersize <= start+length) { indicebuffersize = to!int(indicebuffersize * 2 + 3); if (indicebuffersize < start+length) {indicebuffersize=start+length+3;} glbindbuffer(gl_element_array_buffer, indicebuffer); glbufferdata(gl_element_array_buffer, int.sizeof*indicebuffersize, null, gl_dynamic_draw); glbuffersubdata(gl_element_array_buffer, 0, indices.data.length*int.sizeof, indices.data.ptr); glbindbuffer(gl_element_array_buffer, 0); } else { glbindbuffer(gl_element_array_buffer, indicebuffer); glbuffersubdata(gl_element_array_buffer, start*int.sizeof, length*int.sizeof, indices.data[start..start+length].ptr); glbindbuffer(gl_element_array_buffer, 0); } } void reservevertexbuffer(int length) { vertexbuffersize = length; glbindbuffer(gl_array_buffer, vertexbuffer); glbufferdata(gl_array_buffer, float.sizeof*length, null, gl_dynamic_draw); glbindbuffer(gl_array_buffer, 0); } void updatevertexbufferpartial(int start, int length) { if (vertexbuffersize <= start+length) { vertexbuffersize = to!int(vertexbuffersize * 2 + 9); if (vertexbuffersize < start+length) {vertexbuffersize=start+length+9;} glbindbuffer(gl_array_buffer, vertexbuffer); glbufferdata(gl_array_buffer, float.sizeof*vertexbuffersize, null, gl_dynamic_draw); glbuffersubdata(gl_array_buffer, 0, vertices.data.length*float.sizeof, vertices.data.ptr); glbindbuffer(gl_array_buffer, 0); } else { glbindbuffer(gl_array_buffer, vertexbuffer); glbuffersubdata(gl_array_buffer, start*float.sizeof, length*float.sizeof, vertices.data[start..start+length].ptr); glbindbuffer(gl_array_buffer, 0); } } void reservecolorbuffer(int length) { colorbuffersize = length; glbindbuffer(gl_array_buffer, colorbuffer); glbufferdata(gl_array_buffer, byte.sizeof*length, null, gl_dynamic_draw); glbindbuffer(gl_array_buffer, 0); } void updatecolorbufferpartial(int start, int length) { if (colorbuffersize <= start+length) { colorbuffersize = to!int(colorbuffersize * 2 + 12); if (colorbuffersize < start+length) {colorbuffersize=start+length+12;} glbindbuffer(gl_array_buffer, colorbuffer); glbufferdata(gl_array_buffer, byte.sizeof*colorbuffersize, null, gl_dynamic_draw); glbuffersubdata(gl_array_buffer, 0, color.data.length*byte.sizeof, color.data.ptr); glbindbuffer(gl_array_buffer, 0); } else { glbindbuffer(gl_array_buffer, colorbuffer); glbuffersubdata(gl_array_buffer, start*byte.sizeof, length*byte.sizeof, color.data[start..start+length].ptr); glbindbuffer(gl_array_buffer, 0); } } vertexgroup addtriangle(double trianglex, double triangley, double trianglez, double width) { if (vertices.capacity() == 0) { vertices.reserve(vertices.data.length*2 + 9); } if (indices.capacity() == 0) { indices.reserve(indices.data.length*2 + 3); } if (color.capacity() == 0) { color.reserve(color.data.length*2 + 12); } int firstvertex = to!int(vertices.data.length); int firstindice = to!int(indices.data.length); int firstcolor = to!int( color.data.length); vertices.put( [trianglex-width/2.0, triangley-width/2.0, trianglez, trianglex+width/2.0, triangley-width/2.0, trianglez, trianglex, triangley+width/2.0, trianglez ] ); //add lines connect vertices int n = to!int(indices.data.length); indices.put( [n, n+1, n+2] ); //for each vertex need color r, g, b, color.put( [colorr, colorg, colorb, colora, colorr, colorg, colorb, colora, colorr, colorg, colorb, colora] ); int lastvertex = to!int(vertices.data.length); int lastindice = to!int(indices.data.length); int lastcolor = to!int(color.data.length); if (updatebuffers) { updateindicebufferpartial(firstindice, lastindice-firstindice); updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); updatecolorbufferpartial(firstcolor, lastcolor-firstcolor); } return vertexgroup(firstvertex, lastvertex, firstcolor, lastcolor, firstindice, lastindice, this); } vertexgroup addsquare(double squarex, double squarey, double squarez, double size) { if (vertices.capacity() == 0) { vertices.reserve(vertices.data.length*2 + 12); } if (indices.capacity() == 0) { indices.reserve(indices.data.length*2 + 6); } if (color.capacity() == 0) { color.reserve(color.data.length*2 + 16); } int firstvertex = to!int(vertices.data.length); int firstindice = to!int(indices.data.length); int firstcolor = to!int( color.data.length); vertices.put( [ squarex-size/2.0, squarey-size/2.0, squarez, squarex-size/2.0, squarey+size/2.0, squarez, squarex+size/2.0, squarey-size/2.0, squarez, squarex+size/2.0, squarey+size/2.0, squarez] ); //add lines connect vertices int n = to!int(indices.data.length); indices.put( [n, n+1, n+2, n+3, n+2, n+1] ); //for each vertex need color r, g, b, color.put( [colorr, colorg, colorb, colora, colorr, colorg, colorb, colora, colorr, colorg, colorb, colora, colorr, colorg, colorb, colora] ); int lastvertex = to!int(vertices.data.length); int lastindice = to!int(indices.data.length); int lastcolor = to!int(color.data.length); if (updatebuffers) { updateindicebufferpartial(firstindice, lastindice-firstindice); updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); updatecolorbufferpartial(firstcolor, lastcolor-firstcolor); } return vertexgroup(firstvertex, lastvertex, firstcolor, lastcolor, firstindice, lastindice, this); } void render(camera camera) { program.use(); //set camera location uniform gluniformmatrix4fv(camerauniformlocation, 1, gl_false, camera.pvmat4.mat.ptr); // wireframe checking if (wireframe) glpolygonmode(gl_front_and_back, gl_line); scope(exit) glpolygonmode(gl_front_and_back, gl_fill); //draw indices //glbindbuffer(gl_element_array_buffer, indicebuffer); glbindvertexarray(vaoid); // bind our vertex array object //glbindbuffer(gl_element_array_buffer, indicebuffer); gldrawarrays(drawmode.triangles, 0, to!int(indices.data.length)); //glbindbuffer(gl_element_array_buffer, 0); //glbindvertexarray(0); // unbind our vertex array object //gldrawelements(drawmode.triangles, to!int(indices.data.length), gl_unsigned_int, cast(void*)(0) ); //glbindbuffer(gl_element_array_buffer, 0); } } static shader vs; static shader fs; static shaderprogram program = null; static void initializeshader() { vs = new shader(shadertype.vertex, vertexshadersource); fs = new shader(shadertype.fragment, fragmentshadersource); program = new shaderprogram(vs, fs); } static immutable vertexshadersource = q{ #version 150 in vec3 position; in vec4 color; uniform mat4 pvmmatrix; out vec4 vcolor; void main() { vcolor = color; gl_position = pvmmatrix * vec4(position, 1.0); } }; static immutable fragmentshadersource = q{ #version 150 in vec4 vcolor; out vec4 fragcolor; void main() { fragcolor = vcolor; } }; struct vertexgroup { int firstvertex, lastvertex; int firstcolor, lastcolor; int firstindice, lastindice; ultramesh ultramesh; float centerx = 0; float centery = 0; float centerz = 0; static vertexgroup opcall(int fv, int lv, int fc, int lc, int fi, int li, ultramesh um) { vertexgroup vg = vertexgroup.init; vg.firstvertex = fv; vg.lastvertex = lv; vg.firstcolor = fc; vg.lastcolor = lc; vg.firstindice = fi; vg.lastindice = li; vg.ultramesh = um; vg.calculatecenter(); return vg; } void calculatecenter() { int vcount = (lastvertex - firstvertex)/3; (int = firstvertex; < lastvertex; i+= 3) { //writeln("x: ", ultramesh.vertices.data[i], ", y: ", ultramesh.vertices.data[i+1]); centerx += ultramesh.vertices.data[i]/vcount; centery += ultramesh.vertices.data[i+1]/vcount; centerz += ultramesh.vertices.data[i+2]/vcount; } } void rotatex(float angle) { float s = sin(angle); float c = cos(angle); (int = firstvertex; < lastvertex; i+=3) { float z = ultramesh.vertices.data[i+2] - centerz; float y = ultramesh.vertices.data[i+1] - centery; ultramesh.vertices.data[i+2] = z * c - y * s + centerz; ultramesh.vertices.data[i+1] = y * c + z * s + centery; } if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void rotatey(float angle) { float s = sin(angle); float c = cos(angle); (int = firstvertex; < lastvertex; i+=3) { float x = ultramesh.vertices.data[i] - centerx; float z = ultramesh.vertices.data[i+2] - centerz; ultramesh.vertices.data[i] = x * c - z * s + centerx; ultramesh.vertices.data[i+2] = z * c + x * s + centerz; } if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void rotatez(float angle) { float s = sin(angle); float c = cos(angle); (int = firstvertex; < lastvertex; i+=3) { float x = ultramesh.vertices.data[i] - centerx; float y = ultramesh.vertices.data[i+1] - centery; ultramesh.vertices.data[i] = x * c - y * s + centerx; ultramesh.vertices.data[i+1] = y * c + x * s + centery; } if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void translatex(float value) { (int = firstvertex; < lastvertex; i+= 3) { ultramesh.vertices.data[i] += value; } centerx += value; if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void translatey(float value) { (int = firstvertex; < lastvertex; i+= 3) { ultramesh.vertices.data[i+1] += value; } centery += value; if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void translatez(float value) { (int = firstvertex; < lastvertex; i+= 3) { ultramesh.vertices.data[i+2] += value; } centerz += value; if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void setposition(float xpos, float ypos, float zpos) { float movex = xpos-centerx; float movey = ypos-centery; float movez = zpos-centerz; centerx = xpos; centery = ypos; centerz = zpos; (int = firstvertex; < lastvertex; i+= 3) { ultramesh.vertices.data[i] += movex; ultramesh.vertices.data[i+1] += movey; ultramesh.vertices.data[i+2] += movez; } if (ultramesh.updatebuffers) ultramesh.updatevertexbufferpartial(firstvertex, lastvertex-firstvertex); } void setcolor(float r, float g, float b, float a) { ubyte rbyte = to!ubyte(to!int(r*255)); ubyte gbyte = to!ubyte(to!int(g*255)); ubyte bbyte = to!ubyte(to!int(b*255)); ubyte abyte = to!ubyte(to!int(a*255)); (int = firstcolor; < lastcolor; += 4) { ultramesh.color.data[i] = rbyte; ultramesh.color.data[i+1] = gbyte; ultramesh.color.data[i+2] = bbyte; ultramesh.color.data[i+3] = abyte; } if (ultramesh.updatebuffers) ultramesh.updatecolorbufferpartial(firstcolor, lastcolor-firstcolor); } } pastebin better formatting:
http://pastebin.com/1b9b2ksu i believe i'm setting indices correctly, idea why happens?
n should equal vertices/3 instead of indices.
Comments
Post a Comment