c++ - Scaling a texture with a Framebuffer -
my goal able scale textures when loaded, don't have on every frame sprite gets rendered. figured best method render scaled texture onto texture, caching it. however, following code, red quads (due glclearcolor) know fbo working, not method rendering new texture
texture *graphics::loadtexture(const std::string& filename, int scale = 0) { sdl_surface *surface; gluint texture; if((surface = img_load(filename.c_str()))) { // number of colors glint numberofcolors = surface->format->bytesperpixel; glenum format; // set format of texture based on number of channels if(numberofcolors == 4) { if(surface->format->rmask == 0x000000ff) { format = gl_rgba; } else { format = gl_bgra; } } else if(numberofcolors == 3) { if(surface->format->rmask == 0x000000ff) { format = gl_rgb; } else { format = gl_bgr; } } else { throw exception("invalid image type image " + filename); } // generate texture id glgentextures(1, &texture); // bind texture glbindtexture(gl_texture_2d, texture); // texture stretching properties gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_nearest); gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_nearest); // create image glteximage2d(gl_texture_2d, 0, 4, surface->w, surface->h, 0, format, gl_unsigned_byte, surface->pixels); glbindtexture(gl_texture_2d, 0); } else { return null; } texture *result; if(scale > 1) { gluint scaledtexture; gluint fbo; gluint fbod; // first setup depth buffer // // create framebuffer glgenrenderbuffersext(1, &fbod); // bind render buffer glbindrenderbufferext(gl_renderbuffer_ext, fbod); // set render buffer storage depth component glrenderbufferstorageext(gl_renderbuffer_ext, gl_depth_component, surface->w*scale, surface->h*scale); // set render buffer of buffer depth buffer glframebufferrenderbufferext(gl_framebuffer_ext, gl_depth_attachment_ext, gl_renderbuffer_ext, fbod); // unbind render buffer glbindrenderbufferext(gl_renderbuffer_ext, 0); // next setup texture // glgentextures(1, &scaledtexture); glbindtexture(gl_texture_2d, scaledtexture); glteximage2d(gl_texture_2d, 0, gl_rgba, surface->w*scale, surface->h*scale, 0, gl_rgba, gl_unsigned_byte, null); gltexparameterf(gl_texture_2d, gl_texture_wrap_s, gl_clamp_to_edge); gltexparameterf(gl_texture_2d, gl_texture_wrap_t, gl_clamp_to_edge); gltexparameterf(gl_texture_2d, gl_texture_mag_filter, gl_linear); gltexparameterf(gl_texture_2d, gl_texture_min_filter, gl_linear); glbindtexture(gl_texture_2d, 0); // setup frame buffer // glgenframebuffersext(1, &fbo); glbindframebufferext(gl_framebuffer_ext, fbo); // attach texture , render buffer frame buffer glframebuffertexture2dext(gl_framebuffer_ext, gl_color_attachment0_ext, gl_texture_2d, scaledtexture, 0); // attach depth buffer glframebufferrenderbufferext(gl_framebuffer_ext, gl_depth_attachment_ext, gl_renderbuffer_ext, fbod); glpushattrib(gl_viewport_bit | gl_enable_bit); glviewport(0, 0, surface->w*scale, surface->h*scale); glloadidentity(); glclearcolor(1.0f, 0.0f, 0.0f, 1.0f); glclear(gl_color_buffer_bit | gl_depth_buffer_bit); glbindtexture(gl_texture_2d, texture); glpushmatrix(); glbegin(gl_quads); gltexcoord2i( 0, 0 ); glvertex3f( 0.f, 0.f, 0.0f ); gltexcoord2i( 1, 0 ); glvertex3f( (glfloat)surface->w*scale, 0.0f, 0.0f ); gltexcoord2i( 1, 1 ); glvertex3f( (glfloat)surface->w*scale, (glfloat)surface->h*scale, 0.f ); gltexcoord2i( 0, 1 ); glvertex3f( 0.0f, (glfloat)surface->h*scale, 0.f ); glend(); glpopmatrix(); glclearcolor(0.0f, 0.0f, 0.0f, 1.0f); glpopattrib(); glbindframebufferext(gl_framebuffer_ext, 0); result = new texture(scaledtexture, surface->w, surface->h); } else { result = new texture(texture, surface->w, surface->h); } //texture *result = new texture(texture, surface->w, surface->h); if(surface) { sdl_freesurface(surface); } return result; }
several comments :
- when glloadidentity(), know matrix resetting ? use glmatrixmode.
- your glpushmatrix()/glpopmatrix() useless since don't modify matrix inbetween.
- are sure 2d textures enabled ? use glenable(gl_texture_2d);
but anyway, clear both matrices , should see texture in upper right part of screen (or whatever polygon on you're using generated texture) ; you'll have fix uvs et graphics::loadtexture :
glmatrixmode(gl_modelview); glloadidentity(); glmatrixmode(gl_projection); glloadidentity();
this should work, think should scaling in software.
Comments
Post a Comment