SDL OpenGL in C++, Texture Shader missing the texture -
i trying create first opengl shader experiencing difficulties when trying add texture cube object.
is sharp eyed enough spot error? code might have lots of errors, , grateful if points them out, interested in why rotating cube gray , not colorful.
(i have skipped error handling keep source code size low, sorry that)
**edit found out missed uv settings, still gray cube though ...
#include <windows.h> #include <sdl.h> #include <gl/glew.h> #include <gl/glu.h> #include <gl/glut.h> #include <math.h> #include <string> using namespace std; void initall(); void setupbox(); void mainloop(); unsigned int generatetexture(); void handle_inputs(); void updatescreen(); void clean_up(); int scrwidth, scrheight, flags; bool bquit = false; float angle = 0.0f; gluint tex_box, tex_norm; std::string vertex_source, fragment_source; gluint shader_program, vertex_shader, fragment_shader; // vao , vbo handle gluint vao, vbo; const char *source; int length; struct svert { float x; float y; float z; }; class cpolygon { public: int v[4]; void fillverts(int v1, int v2, int v3, int v4) { v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; } } p[6]; svert pv[8]; int main(int argc, char *argv[]) { initall(); mainloop(); clean_up(); return 0; } void initall() { scrwidth = 800; scrheight = 600; vertex_source = "#version 330\n" "layout (location = 0) in vec3 position;\n" "layout (location = 1) in vec2 texcoord;\n" "void main() {\n" " gl_position = gl_modelviewprojectionmatrix * gl_vertex;\n" " gl_texcoord[0] = gl_multitexcoord0;\n" "}\n"; fragment_source = "#version 330\n" "uniform sampler2d tex;\n" "void main() {\n" " fragcolor = texture2d(tex, gl_texcoord[0].st);\n" "}\n"; sdl_initsubsystem(sdl_init_video); sdl_gl_setattribute( sdl_gl_alpha_size, 8 ); sdl_gl_setattribute( sdl_gl_red_size, 8 ); sdl_gl_setattribute( sdl_gl_green_size, 8 ); sdl_gl_setattribute( sdl_gl_blue_size, 8 ); sdl_gl_setattribute( sdl_gl_depth_size, 16 ); sdl_gl_setattribute( sdl_gl_doublebuffer, 1 ); flags = sdl_opengl | sdl_anyformat ; sdl_setvideomode(scrwidth, scrheight, 16, flags); glmatrixmode( gl_projection ); glloadidentity( ); gluperspective( 45.0f, (glfloat)scrwidth/(glfloat)scrheight, 1.0f, 500.0f ); glmatrixmode( gl_modelview ); glloadidentity( ); glenable (gl_depth_test); glenable (gl_lighting); glenable (gl_light0); glenable(gl_blend); glblendfunc(gl_src_color, gl_one_minus_src_alpha); sdl_wm_setcaption( "texture shader", null ); glewinit(); // vertex shader vertex_shader = glcreateshader(gl_vertex_shader); source = vertex_source.c_str(); length = vertex_source.size(); glshadersource(vertex_shader, 1, &source, &length); glcompileshader(vertex_shader); // fragment shader fragment_shader = glcreateshader(gl_fragment_shader); source = fragment_source.c_str(); length = fragment_source.size(); glshadersource(fragment_shader, 1, &source, &length); glcompileshader(fragment_shader); // create program shader_program = glcreateprogram(); glattachshader(shader_program, vertex_shader); glattachshader(shader_program, fragment_shader); gllinkprogram(shader_program); glgenvertexarrays(1, &vao); glbindvertexarray(vao); glgenbuffers(1, &vbo); glbindbuffer(gl_array_buffer, vbo); setupbox(); glfloat vd[6*5*6]; for(int pi=0; pi<6; pi++) { vd[pi*30+ 0] = pv[ p[pi].v[0] ].x; vd[pi*30+ 1] = pv[ p[pi].v[0] ].y; vd[pi*30+ 2] = pv[ p[pi].v[0] ].z; vd[pi*30+ 3] = 0.0; vd[pi*30+ 4] = 1.0; vd[pi*30+ 5] = pv[ p[pi].v[1] ].x; vd[pi*30+ 6] = pv[ p[pi].v[1] ].y; vd[pi*30+ 7] = pv[ p[pi].v[1] ].z; vd[pi*30+ 8] = 0.0; vd[pi*30+ 9] = 0.0; vd[pi*30+10] = pv[ p[pi].v[2] ].x; vd[pi*30+11] = pv[ p[pi].v[2] ].y; vd[pi*30+12] = pv[ p[pi].v[2] ].z; vd[pi*30+13] = 1.0; vd[pi*30+14] = 0.0; vd[pi*30+15] = pv[ p[pi].v[0] ].x; vd[pi*30+16] = pv[ p[pi].v[0] ].y; vd[pi*30+17] = pv[ p[pi].v[0] ].z; vd[pi*30+18] = 0.0; vd[pi*30+19] = 1.0; vd[pi*30+20] = pv[ p[pi].v[2] ].x; vd[pi*30+21] = pv[ p[pi].v[2] ].y; vd[pi*30+22] = pv[ p[pi].v[2] ].z; vd[pi*30+23] = 1.0; vd[pi*30+24] = 0.0; vd[pi*30+25] = pv[ p[pi].v[3] ].x; vd[pi*30+26] = pv[ p[pi].v[3] ].y; vd[pi*30+27] = pv[ p[pi].v[3] ].z; vd[pi*30+28] = 1.0; vd[pi*30+29] = 1.0; } glbufferdata(gl_array_buffer, sizeof(glfloat)*6*5*6, vd, gl_static_draw); glenablevertexattribarray(0); glvertexattribpointer(0, 3, gl_float, gl_false, 5*sizeof(glfloat), (char*)0 + 0*sizeof(glfloat)); glenablevertexattribarray(1); glvertexattribpointer(1, 2, gl_float, gl_false, 5*sizeof(glfloat), (char*)0 + 3*sizeof(glfloat)); tex_box = generatetexture(); tex_norm = generatetexture(); } void setupbox() { (int z=0;z<2;z++) (int y=0;y<2;y++) (int x=0;x<2;x++) { pv[x+y*2+z*4].x = -1.0+x; pv[x+y*2+z*4].y = -1.0+y; pv[x+y*2+z*4].z = -1.0+z; } p[0].fillverts (0, 1, 3, 2); // above p[1].fillverts (4, 5, 1, 0); // behind p[2].fillverts (6, 7, 3, 2); // in front p[3].fillverts (5, 7, 3, 1); // right p[4].fillverts (0, 2, 6, 4); // left p[5].fillverts (7, 6, 4, 5); // below } unsigned int generatetexture() { byte data[128*128*3]; unsigned int id; (int x=0;x<128;x++) (int y=0;y<128;y++) { data[y*128*3+x*3+0] = x; // red data[y*128*3+x*3+1] = y; // green data[y*128*3+x*3+2] = 128-(abs(64-x)+abs(64-y)); // blue } glgentextures(1, &id); glbindtexture(gl_texture_2d, id); gltexenvf( gl_texture_env, gl_texture_env_mode, gl_modulate ); gltexparameteri( gl_texture_2d, gl_texture_mag_filter, gl_nearest); gltexparameteri( gl_texture_2d, gl_texture_min_filter, gl_nearest); gltexparameterf( gl_texture_2d, gl_texture_wrap_s, gl_repeat ); gltexparameterf( gl_texture_2d, gl_texture_wrap_t, gl_repeat ); glteximage2d(gl_texture_2d, 0, gl_rgb, 128, 128, 0, gl_rgb, gl_unsigned_byte, data); glgeneratemipmap(gl_texture_2d); return id; } void mainloop() { while(bquit == false) { handle_inputs(); updatescreen(); angle += 1.5f; sleep(50); } } void handle_inputs() { sdl_pumpevents(); uint8 * keystate = sdl_getkeystate(null); if(keystate[sdlk_escape]) bquit = true; } void updatescreen() { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); glloadidentity(); glulookat (2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); gluseprogram(shader_program); glbindvertexarray(vao); glrotatef(angle, 1.0, 0.0, 0.0); //rotate on x axis glrotatef(angle, 0.0, 1.0, 0.0); //rotate on y axis glrotatef(angle, 0.0, 0.0, 1.0); //rotate on z axis glactivetexture(gl_texture0); int loc = glgetuniformlocation(shader_program, "tex"); gluniform1i(loc, 0); glbindtexture(gl_texture_2d, tex_box); gldrawarrays(gl_triangles, 0, 6*6); //glutsolidteapot(2.0); gluseprogram(0); sdl_gl_swapbuffers(); } void clean_up() { gldeletevertexarrays(1, &vao); gldeletebuffers(1, &vbo); gldetachshader(shader_program, vertex_shader); gldetachshader(shader_program, fragment_shader); gldeleteshader(vertex_shader); gldeleteshader(fragment_shader); gldeleteprogram(shader_program); sdl_quitsubsystem(sdl_init_video); gldeletetextures(1, &tex_box); gldeletetextures(1, &tex_norm); sdl_quit(); }
**edit 2 here fixed version result following advices in derhass accepted answer. upvote answer instead of if it.
#include <windows.h> #include <sdl.h> #include <gl/glew.h> #include <gl/glu.h> #include <gl/glut.h> #include <stdio.h> #include <math.h> #include <string> using namespace std; #define log_size 10000 void initall(); void setupbox(); void mainloop(); unsigned int generatetexture(); void handle_inputs(); void updatescreen(); void clean_up(); void dbpf(int, const char *, ...); int scrwidth, scrheight, flags; bool bquit = false; float angle = 0.0f; va_list m; int db_threashold = 0; glint status; glchar elog[log_size]; glint rlength = 0; gluint tex_box, tex_norm; std::string vertex_source, fragment_source; gluint shader_program, vertex_shader, fragment_shader; gluint vao, vbo; const char *source; int length; struct svert { float x; float y; float z; }; class cpolygon { public: int v[4]; void fillverts(int v1, int v2, int v3, int v4) { v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; } } p[6]; svert pv[8]; int main(int argc, char *argv[]) { initall(); mainloop(); clean_up(); return 0; } void initall() { scrwidth = 800; scrheight = 600; vertex_source = "#version 330\n" "in vec3 position;\n" "in vec2 texcoord;\n" "out vec3 ocolor;" "out vec2 otexcoord;" "void main() {\n" " otexcoord = texcoord;\n" " gl_position = gl_modelviewprojectionmatrix*vec4(position, 1.0);\n" "}\n"; fragment_source = "#version 330\n" "in vec2 otexcoord;" "out vec4 ocolor;" "uniform sampler2d tex;\n" "void main() {\n" " ocolor = texture2d(tex, otexcoord);\n" "}\n"; sdl_initsubsystem(sdl_init_video); sdl_gl_setattribute( sdl_gl_alpha_size, 8 ); sdl_gl_setattribute( sdl_gl_red_size, 8 ); sdl_gl_setattribute( sdl_gl_green_size, 8 ); sdl_gl_setattribute( sdl_gl_blue_size, 8 ); sdl_gl_setattribute( sdl_gl_depth_size, 16 ); sdl_gl_setattribute( sdl_gl_doublebuffer, 1 ); flags = sdl_opengl | sdl_anyformat ; sdl_setvideomode(scrwidth, scrheight, 16, flags); glmatrixmode( gl_projection ); glloadidentity( ); gluperspective( 45.0f, (glfloat)scrwidth/(glfloat)scrheight, 1.0f, 500.0f ); glmatrixmode( gl_modelview ); glloadidentity( ); glenable (gl_depth_test); glenable (gl_lighting); glenable (gl_light0); sdl_wm_setcaption( "texture shader", null ); glewinit(); // create , compiler vertex shader vertex_shader = glcreateshader(gl_vertex_shader); source = vertex_source.c_str(); length = vertex_source.size(); glshadersource(vertex_shader, 1, &source, &length); glcompileshader(vertex_shader); glgetshaderiv(vertex_shader, gl_compile_status, &status); glgetshaderinfolog(vertex_shader, log_size, &rlength, elog); dbpf(10, "compile vertex log: \n %s \n", elog); // create , compiler fragment shader fragment_shader = glcreateshader(gl_fragment_shader); source = fragment_source.c_str(); length = fragment_source.size(); glshadersource(fragment_shader, 1, &source, &length); glcompileshader(fragment_shader); glgetshaderiv(fragment_shader, gl_compile_status, &status); glgetshaderinfolog(fragment_shader, log_size, &rlength, elog); dbpf(10, "compile fragment log: \n %s \n", elog); // create program shader_program = glcreateprogram(); // attach shaders glattachshader(shader_program, vertex_shader); glattachshader(shader_program, fragment_shader); // link program , check errors gllinkprogram(shader_program); glgetprogramiv(shader_program, gl_link_status, &status); glgetprograminfolog(shader_program, log_size, &rlength, elog); dbpf(10, "link log: \n %s \n", elog); // generate , bind vao glgenvertexarrays(1, &vao); glbindvertexarray(vao); // generate , bind buffer object glgenbuffers(1, &vbo); glbindbuffer(gl_array_buffer, vbo); setupbox(); glfloat vd[6*5*6]; for(int pi=0; pi<6; pi++) { vd[pi*30+ 0] = pv[ p[pi].v[0] ].x; vd[pi*30+ 1] = pv[ p[pi].v[0] ].y; vd[pi*30+ 2] = pv[ p[pi].v[0] ].z; vd[pi*30+ 3] = 0.0; vd[pi*30+ 4] = 1.0; vd[pi*30+ 5] = pv[ p[pi].v[1] ].x; vd[pi*30+ 6] = pv[ p[pi].v[1] ].y; vd[pi*30+ 7] = pv[ p[pi].v[1] ].z; vd[pi*30+ 8] = 0.0; vd[pi*30+ 9] = 0.0; vd[pi*30+10] = pv[ p[pi].v[2] ].x; vd[pi*30+11] = pv[ p[pi].v[2] ].y; vd[pi*30+12] = pv[ p[pi].v[2] ].z; vd[pi*30+13] = 1.0; vd[pi*30+14] = 0.0; vd[pi*30+15] = pv[ p[pi].v[0] ].x; vd[pi*30+16] = pv[ p[pi].v[0] ].y; vd[pi*30+17] = pv[ p[pi].v[0] ].z; vd[pi*30+18] = 0.0; vd[pi*30+19] = 1.0; vd[pi*30+20] = pv[ p[pi].v[2] ].x; vd[pi*30+21] = pv[ p[pi].v[2] ].y; vd[pi*30+22] = pv[ p[pi].v[2] ].z; vd[pi*30+23] = 1.0; vd[pi*30+24] = 0.0; vd[pi*30+25] = pv[ p[pi].v[3] ].x; vd[pi*30+26] = pv[ p[pi].v[3] ].y; vd[pi*30+27] = pv[ p[pi].v[3] ].z; vd[pi*30+28] = 1.0; vd[pi*30+29] = 1.0; } // fill data glbufferdata(gl_array_buffer, sizeof(glfloat)*6*5*6, vd, gl_static_draw); // set generic attrib pointers glenablevertexattribarray(0); glvertexattribpointer(0, 3, gl_float, gl_false, 5*sizeof(glfloat), (char*)0 + 0*sizeof(glfloat)); glenablevertexattribarray(1); glvertexattribpointer(1, 2, gl_float, gl_false, 5*sizeof(glfloat), (char*)0 + 3*sizeof(glfloat)); tex_box = generatetexture(); tex_norm = generatetexture(); } void setupbox() { (int z=0;z<2;z++) (int y=0;y<2;y++) (int x=0;x<2;x++) { pv[x+y*2+z*4].x = -1.0+x; pv[x+y*2+z*4].y = -1.0+y; pv[x+y*2+z*4].z = -1.0+z; } p[0].fillverts (0, 1, 3, 2); // above p[1].fillverts (4, 5, 1, 0); // behind p[2].fillverts (6, 7, 3, 2); // in front p[3].fillverts (5, 7, 3, 1); // right p[4].fillverts (0, 2, 6, 4); // left p[5].fillverts (7, 6, 4, 5); // below } unsigned int generatetexture() { byte data[128*128*3]; unsigned int id; (int x=0;x<128;x++) (int y=0;y<128;y++) { data[y*128*3+x*3+0] = x; // red data[y*128*3+x*3+1] = y; // green data[y*128*3+x*3+2] = 128-(abs(64-x)+abs(64-y)); // blue } glgentextures(1, &id); glbindtexture(gl_texture_2d, id); gltexenvf( gl_texture_env, gl_texture_env_mode, gl_modulate ); gltexparameteri( gl_texture_2d, gl_texture_mag_filter, gl_nearest); gltexparameteri( gl_texture_2d, gl_texture_min_filter, gl_nearest); gltexparameterf( gl_texture_2d, gl_texture_wrap_s, gl_repeat ); gltexparameterf( gl_texture_2d, gl_texture_wrap_t, gl_repeat ); glteximage2d(gl_texture_2d, 0, gl_rgb, 128, 128, 0, gl_rgb, gl_unsigned_byte, data); glgeneratemipmap(gl_texture_2d); return id; } void mainloop() { while(bquit == false) { handle_inputs(); updatescreen(); angle += 1.5f; sleep(50); } } void handle_inputs() { sdl_pumpevents(); uint8 * keystate = sdl_getkeystate(null); if(keystate[sdlk_escape]) bquit = true; } void updatescreen() { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); glloadidentity(); glulookat (2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // use shader program gluseprogram(shader_program); // bind vao glbindvertexarray(vao); // rotation glrotatef(angle, 1.0, 0.0, 0.0); //rotate on x axis glrotatef(angle, 0.0, 1.0, 0.0); //rotate on y axis glrotatef(angle, 0.0, 0.0, 1.0); //rotate on z axis // bind texture glactivetexture(gl_texture0); int loc = glgetuniformlocation(shader_program, "tex"); gluniform1i(loc, 0); glbindtexture(gl_texture_2d, tex_box); // draw gldrawarrays(gl_triangles, 0, 6*6); gluseprogram(0); sdl_gl_swapbuffers(); } void clean_up() { gldeletevertexarrays(1, &vao); gldeletebuffers(1, &vbo); gldetachshader(shader_program, vertex_shader); gldetachshader(shader_program, fragment_shader); gldeleteshader(vertex_shader); gldeleteshader(fragment_shader); gldeleteprogram(shader_program); sdl_quitsubsystem(sdl_init_video); gldeletetextures(1, &tex_box); gldeletetextures(1, &tex_norm); sdl_quit(); } void dbpf(int t, const char * msg, ...) { va_start(m, msg); if (t >= db_threashold) vfprintf(stderr, msg, m); va_end(m); }
your fragment shader shouldn't compile. writing undeclated variable 'fragcolor'. should first add code check compile , link status, , query compile , link log, errors , warnings glsl compiler/linker detected. use like:
glint status; glubyte log[log_size]; // compile shader here ... glgetshaderiv(shader, gl_compile_status, &status); if (status != gl_true) { // compile error ... } glgetshaderinfolog(shader, log_size, 0, log); // print log ... // link program here // ... glgetprogramiv(program, gl_link_status, &status); if (status != gl_true) { // error ... } glgetprograminfolog(program, log_size, 0, log); // print log
maybe want print info log in error case, there might warnings/hints in there in successful case, recommend printing alywas, @ least in debug/development builts.
i recommend stop mixing old, deprecated builtins gl_texcoord[0]
, gl_multitexcoord0
, on mordern user defined attributes, inputs , outputs. currently, not using texcoord
attribute did declare.
Comments
Post a Comment