c++ - OpenGL Index Buffering To Make A Square -
i'm new opengl , have been following youtube tutorial jeffrey chastine. personal exercise, wanted make simple square using index buffers. sadly attempt, see 1 triangle drawn (when expect two). i'm not sure i'm missing. here code, tried explaining logic/reasoning in comments. feel free correct me wherever i'm wrong:
#include <gl/glew.h> #include <gl/freeglut.h> #include <iostream> #define buffer_offset(i) ((char *)null + (i)) gluint shaderprogramid; gluint vao = 0; gluint vbo; gluint positionid, colorid; gluint indexbufferid; #pragma region shader_functions static char* readfile(const char* filename) { //open file file* fp = fopen(filename, "r"); //move file pointer end of file , determining length fseek(fp, 0, seek_end); long file_length = ftell(fp); fseek(fp, 0, seek_set); char* contents = new char[file_length + 1]; //zero out memory for(int = 0; < file_length+1; i++) { contents[i] = 0; } //here's actual read fread(contents, 1, file_length, fp); contents[file_length + 1] = '\0'; fclose(fp); return contents; } bool compiledstatus(glint shaderid){ glint compiled = 0; glgetshaderiv(shaderid, gl_compile_status, &compiled); if (compiled) { return true; } else { glint loglength; glgetshaderiv(shaderid, gl_info_log_length, &loglength); char* msgbuffer = new char[loglength]; glgetshaderinfolog(shaderid, loglength, null, msgbuffer); printf ("%s\n", msgbuffer); delete (msgbuffer); return false; } } //takes in source code string gluint makevertexshader(const char* shadersource) { //call gl make vertex shader , id gluint vertexshaderid = glcreateshader(gl_vertex_shader); //bind provided source code shader id glshadersource(vertexshaderid, 1, (const glchar**)&shadersource, null); //compile vertex shader glcompileshader(vertexshaderid); bool compiledcorrect = compiledstatus(vertexshaderid); if(compiledcorrect) { return vertexshaderid; } return -1; return vertexshaderid; } gluint makefragmentshader(const char* shadersource) { //call gl make fragment shader , id gluint fragmentshaderid = glcreateshader(gl_fragment_shader); //bind provided source code shader id glshadersource(fragmentshaderid, 1, (const glchar**)&shadersource, null); //compile fragment shader glcompileshader(fragmentshaderid); bool compiledcorrect = compiledstatus(fragmentshaderid); if(compiledcorrect) { return fragmentshaderid; } return -1; return fragmentshaderid; } #pragma endregion shader_functions void changeviewport(int w, int h) { glviewport(0, 0, w, h); } //this function using each time window needs redrawn void render() { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); gldrawelements(gl_triangles, 4, gl_unsigned_int, null); glutswapbuffers(); } gluint makeshaderprogram(gluint vertextshaderid, gluint fragmentshaderid) { gluint shaderid = glcreateprogram(); //attach vertex shader shader program glattachshader(shaderid, vertextshaderid); //attatch fragment shader shader program glattachshader(shaderid, fragmentshaderid); //link shaders gllinkprogram(shaderid); return shaderid; } int main (int argc, char** argv) { //standards glutinit(&argc, argv); glutinitdisplaymode(glut_rgba); glutinitwindowsize(800, 600); glutcreatewindow("test"); glutreshapefunc(changeviewport); glutdisplayfunc(render); glewinit(); //verticies glfloat vertices_0[] = {-0.5f, -0.5f, 0.0f, //0 -> bottom left -0.5f, 0.5f, 0.0f, //1 -> top left 0.5f, -0.5f, 0.0f, //2 -> bottom right 0.05f, 0.5f, 0.0f};//3 -> top right //colors glfloat colors_0[] = {1.0f, 0.0, 0.0f, 1.0f,//0 0.0f, 1.0f, 0.0f, 1.0f,//1 0.0f, 0.0f, 1.0f, 1.0f,//2 1.0f, 0.0f, 1.0f, 1.0f};//3 //indicies -> triangle 1 -> 0 1 2, traingle 2 -> 1 3 2 gluint indicies_0[] = {0, 1, 2, 1, 3, 2}; //read vertex shader char* vertexshadersourcecode = readfile("vertexshader.vsh"); //read fragment shader char* fragmentshadersourcecode = readfile("fragmentshader.fsh"); //make vertex shader gluint vertexshaderid = makevertexshader(vertexshadersourcecode); //make fragment shader gluint fragmentshaderid = makefragmentshader(fragmentshadersourcecode); //make shader program shaderprogramid = makeshaderprogram(vertexshaderid, fragmentshaderid); printf("vertex shader id %d\n", vertexshaderid); printf("fragment shader id %d\n", fragmentshaderid); printf("shader program id %d\n", shaderprogramid); printf("s_vposition's id %d\n", positionid); //create vertex array object glgenvertexarrays(1, &vao); //bind vertex array object glbindvertexarray(vao); //create vertex buffer object glgenbuffers(1, &vbo); //bind vertex buffer object glbindbuffer(gl_array_buffer, vbo); //create buffer ->7 values 4 vertices glbufferdata(gl_array_buffer, 7*4*sizeof(glfloat), null, gl_static_draw); //starting @ beggining of buffer, place position data (3 values 4 verticies) glbuffersubdata(gl_array_buffer, 0, 3*4*sizeof(glfloat), vertices_0); //starting after placement of position data, place color data (4 values 4 verticies) glbuffersubdata(gl_array_buffer, 3*4*sizeof(glfloat), 4*4*sizeof(glfloat), colors_0); //generate index buffer glgenbuffers(1, &indexbufferid); //bind buffer glbindbuffer(gl_element_array_buffer, indexbufferid); //place index buffer data 6 indicies glbufferdata(gl_element_array_buffer, 6*sizeof(gluint), indicies_0, gl_static_draw); //get position attribute shader positionid = glgetattriblocation(shaderprogramid, "s_vposition"); //get color attribute shader colorid = glgetattriblocation(shaderprogramid, "s_vcolor"); //tell variables can find info in buffer glvertexattribpointer(positionid, 3, gl_float, gl_false, 0, 0); glvertexattribpointer(colorid, 4, gl_float, gl_false, 0, buffer_offset(sizeof(vertices_0))); //tell program use shader program gluseprogram(shaderprogramid); //turn on position variable in shader glenablevertexattribarray(positionid); //turn on color variable in shader glenablevertexattribarray(colorid); glutmainloop(); return 0; }
as mentioned in comments, there error in vertices definition (0.05f should 0.5f).
but, reason seeing 1 triangle instead of 2 line:
gldrawelements(gl_triangles, 4, gl_unsigned_int, null);
the second parameter described in opengl documentation as
count - specifies number of elements rendered.
which index count (each element referenced entry in index array), , should number of entries in index array, not number of unique indexes. change 4 6.
note if used gl_triangle_strip
or gl_triangle_fan
instead of gl_triangles
need 4 indexes {0, 1, 2, 3} , pass 4 doing, because each triangle after first 1 shares 2 of indexes previous triangle, total index count of (triangle count + 2). when using gl_triangles
, each triangle specified separately 3 indexes each (triangle count * 3).
Comments
Post a Comment