c++ - glGenTextures works but returns the same texture name every single time -
i have class called texture
. class responsible managing texture. in programs startup opengl context initialised (which makes question different involving unexpected glgentextures behaviour). texture
gets texture name glgentextures()
, loads , binds image data memory texture name int function texglinit()
. works, , texture displayed expected.
however, want texture able change texture displays when user clicks button , selects 1 hdd in openfilediaglog
. function called reloadtexture()
. function attempts delete old image/pixel data memory , replace new data file selected user. when happens, deletes texture name using gldeletetextures
, , assigns new texture name , loads new pixel data memory using function texglinit()
. texture name same 1 before (usually '1') 100% of time.
the image displayed after happens odd. has new images dimensions, still old images pixels. put simply, distorts old image down new images size. it's still drawing using supposedly deleted pixel data. should happen screen displays new image file on screen. believe texture name not being unique.
the code included below:
texture::texture(string filename)//---constructor loads in initial image. works fine! { textureid[0]=0; const char* fnptr = filename.c_str(); //our image loader accepts ptr char, not string //printf(fnptr); lodepng::load_file(buffer, fnptr);//load file buffer unsigned error = lodepng::decode(image,w,h,buffer);//lodepng's decode function load pixel data image vector buffer //display errors texture if(error) { cout << "\ndecoder error " << error << ": " << lodepng_error_text(error) <<endl; } //execute code that'll throw exceptions images size checkpot(w); checkpot(h); //image contains our pixeldata. ready opengl thing //let's texture in video memory texglinit(); draw_from_corner = center; } void texture::reloadtexture(string filename)//reload texture replaces texture name , image/pixel data bound texture { //first , foremost clear image , buffer vectors down nothing can start afresh buffer.clear(); image.clear(); w = 0; h = 0; //also delete texture name using before gldeletetextures(1, &textureid[0]); const char* fnptr = filename.c_str(); //our image loader accepts ptr char, not string //printf(fnptr); lodepng::load_file(buffer, fnptr);//load file buffer unsigned error = lodepng::decode(image,w,h,buffer);//lodepng's decode function load pixel data image vector buffer //display errors texture if(error) { cout << "\ndecoder error " << error << ": " << lodepng_error_text(error) <<endl; } //execute code that'll throw exceptions images size checkpot(w); checkpot(h); //image contains our pixeldata. ready thing //let's texture in video memoryopengl texglinit(); draw_from_corner = center; } void texture::texglinit()//actually gets new texture name loads pixeldata opengl { glgentextures(1, &textureid[0]); ////printf("\ntextureid = %u", textureid[0]); glbindtexture(gl_texture_2d, textureid[0]);//evrything we're about texture glpixelstorei(gl_unpack_alignment, 1); gltexparameteri (gl_texture_2d, gl_texture_min_filter, gl_nearest); gltexenvf(gl_texture_env, gl_texture_env_mode, gl_modulate); //gldisable(gl_color_material); glteximage2d(gl_texture_2d, 0, gl_rgba8,w,h,0, gl_rgba, gl_unsigned_byte, &image[0]); //we free image vectors memory right now. we'll when there's need to. @ beginning of reloadtexture func, makes sure happens when need to. }
for it's worth here draw function in texture class.
void texture::draw(point* origin, anchor drawfrom) { //let set dfc enum here. draw_from_corner = drawfrom; glenable(gl_texture_2d); //printf("\ndrawing texture @ (%f, %f)",centerpoint.x, centerpoint.y); glbindtexture(gl_texture_2d, textureid[0]);//bind texture //create quick vertex array primitive we're going bind texture ////printf("texid = %u",textureid[0]); glfloat varray[8]; #pragma region anchor switch switch (draw_from_corner) { case center: varray[0] = origin->x-(w/2); varray[1] = origin->y-(h/2);//bottom left i0 varray[2] = origin->x-(w/2); varray[3] = origin->y+(h/2);//top left i1 varray[4] = origin->x+(w/2); varray[5] = origin->y+(h/2);//top right i2 varray[6] = origin->x+(w/2); varray[7] = origin->y-(h/2);//bottom right i3 break; case bottomleft: varray[0] = origin->x; varray[1] = origin->y;//bottom left i0 varray[2] = origin->x; varray[3] = origin->y+h;//top left i1 varray[4] = origin->x+w; varray[5] = origin->y+h;//top right i2 varray[6] = origin->x+w; varray[7] = origin->y;//bottom right i3 break; case topleft: varray[0] = origin->x; varray[1] = origin->y-h;//bottom left i0 varray[2] = origin->x; varray[3] = origin->y;//top left i1 varray[4] = origin->x+w; varray[5] = origin->y;//top right i2 varray[6] = origin->x+w; varray[7] = origin->y-h;//bottom right i3 break; case topright: varray[0] = origin->x-w; varray[1] = origin->y-h;//bottom left i0 varray[2] = origin->x-w; varray[3] = origin->y;//top left i1 varray[4] = origin->x; varray[5] = origin->y;//top right i2 varray[6] = origin->x; varray[7] = origin->y-h;//bottom right i3 break; case bottomright: varray[0] = origin->x-w; varray[1] = origin->y;//bottom left i0 varray[2] = origin->x-w; varray[3] = origin->y+h;//top left i1 varray[4] = origin->x-h; varray[5] = origin->y;//top right i2 varray[6] = origin->x; varray[7] = origin->y;//bottom right i3 break; default: //same center varray[0] = origin->x-(w/2); varray[1] = origin->y-(h/2);//bottom left i0 varray[2] = origin->x-(w/2); varray[3] = origin->y+(h/2);//top left i1 varray[4] = origin->x+(w/2); varray[5] = origin->y+(h/2);//top right i2 varray[6] = origin->x+(w/2); varray[7] = origin->y-(h/2);//bottom right i3 break; } #pragma endregion //create quick texture array (we create on heap rather creating/destoying every cycle) glfloat tarray[8] = { //this has been tinkered normal order. think lodepng bringing pd upside down. quick fix here necessary. 0.0f,1.0f,//0 0.0f,0.0f,//1 1.0f,0.0f,//2 1.0f,1.0f//3 }; //and finally.. index array...remember, draw in triangles....(and we'll go cw) glubyte iarray[6] = { 0,1,2, 0,2,3 }; //activate arrays glenableclientstate(gl_vertex_array); glenableclientstate(gl_texture_coord_array); //give opengl pointer our varray , tarray glvertexpointer(2, gl_float, 0, &varray[0]); gltexcoordpointer(2, gl_float, 0, &tarray[0]); //draw gldrawelements(gl_triangles, 6, gl_unsigned_byte, &iarray[0]); //gldrawarrays(gl_triangles,0,6); //disable vertex arrays gldisableclientstate(gl_vertex_array); gldisableclientstate(gl_texture_coord_array); gldisable(gl_texture_2d); }
could tell me why opengl not loading , drawing new pixel data i've loaded it? said, suspect it's glgentextures not giving me new texture name.
you're calling glteximage2d
, passing pointer client memory. beware, documentation says:
if non-zero named buffer object bound
gl_pixel_unpack_buffer
target (seeglbindbuffer
) while texture image specified,data
treated byte offset buffer object's data store.
you may wish call glbindbuffer(gl_pixel_unpack_buffer, 0)
unbind buffer object safe.
Comments
Post a Comment