📄 gameswf_render_handler_ogl.cpp
字号:
glTexCoord2f(0, 0); glVertex3f(0, (float) dst_height, -1); } glEnd(); glCopyTexImage2D(GL_TEXTURE_2D, 0, out_format, 0,0, dst_width, dst_height, 0); delete temp; } glPopAttrib(); glPopMatrix(); glPopMatrix();}void generate_mipmaps(unsigned int internal_format, unsigned int input_format, int bytes_per_pixel, image::image_base* im)// DESTRUCTIVELY generate mipmaps of the given image. The image data// and width/height of im are munged in this process.{ int level = 1; while (im->m_width > 1 || im->m_height > 1) { if (bytes_per_pixel == 3) { image::make_next_miplevel((image::rgb*) im); } else { image::make_next_miplevel((image::rgba*) im); } glTexImage2D(GL_TEXTURE_2D, level, internal_format, im->m_width, im->m_height, 0, input_format, GL_UNSIGNED_BYTE, im->m_data); level++; }}void software_resample( int bytes_per_pixel, int src_width, int src_height, int src_pitch, uint8* src_data, int dst_width, int dst_height)// Code from Alex Streit//// Creates an OpenGL texture of the specified dst dimensions, from a// resampled version of the given src image. Does a bilinear// resampling to create the dst image.{ assert(bytes_per_pixel == 3 || bytes_per_pixel == 4); assert(dst_width >= src_width); assert(dst_height >= src_height); unsigned int internal_format = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; unsigned int input_format = bytes_per_pixel == 3 ? GL_RGB : GL_RGBA; // FAST bi-linear filtering // the code here is designed to be fast, not readable Uint8* rescaled = new Uint8[dst_width * dst_height * bytes_per_pixel]; float Uf, Vf; // fractional parts float Ui, Vi; // integral parts float w1, w2, w3, w4; // weighting Uint8* psrc; Uint8* pdst = rescaled; // i1,i2,i3,i4 are the offsets of the surrounding 4 pixels const int i1 = 0; const int i2 = bytes_per_pixel; int i3 = src_pitch; int i4 = src_pitch + bytes_per_pixel; // change in source u and v float dv = (float)(src_height-2) / dst_height; float du = (float)(src_width-2) / dst_width; // source u and source v float U; float V=0;#define BYTE_SAMPLE(offset) \ (Uint8) (w1 * psrc[i1 + (offset)] + w2 * psrc[i2 + (offset)] + w3 * psrc[i3 + (offset)] + w4 * psrc[i4 + (offset)]) if (bytes_per_pixel == 3) { for (int v = 0; v < dst_height; ++v) { Vf = modff(V, &Vi); V+=dv; U=0; for (int u = 0; u < dst_width; ++u) { Uf = modff(U, &Ui); U+=du; w1 = (1 - Uf) * (1 - Vf); w2 = Uf * (1 - Vf); w3 = (1 - Uf) * Vf; w4 = Uf * Vf; psrc = &src_data[(int) (Vi * src_pitch) + (int) (Ui * bytes_per_pixel)]; *pdst++ = BYTE_SAMPLE(0); // red *pdst++ = BYTE_SAMPLE(1); // green *pdst++ = BYTE_SAMPLE(2); // blue psrc += 3; } }#ifdef DEBUG_WRITE_TEXTURES_TO_PPM static int s_image_sequence = 0; char temp[256]; sprintf(temp, "image%d.ppm", s_image_sequence++); FILE* f = fopen(temp, "wb"); if (f) { fprintf(f, "P6\n# test code\n%d %d\n255\n", dst_width, dst_height); fwrite(rescaled, dst_width * dst_height * 3, 1, f); fclose(f); }#endif } else { assert(bytes_per_pixel == 4); for (int v = 0; v < dst_height; ++v) { Vf = modff(V, &Vi); V+=dv; U=0; for (int u = 0; u < dst_width; ++u) { Uf = modff(U, &Ui); U+=du; w1 = (1 - Uf) * (1 - Vf); w2 = Uf * (1 - Vf); w3 = (1 - Uf) * Vf; w4 = Uf * Vf; psrc = &src_data[(int) (Vi * src_pitch) + (int) (Ui * bytes_per_pixel)]; *pdst++ = BYTE_SAMPLE(0); // red *pdst++ = BYTE_SAMPLE(1); // green *pdst++ = BYTE_SAMPLE(2); // blue *pdst++ = BYTE_SAMPLE(3); // alpha psrc += 4; } } } glTexImage2D(GL_TEXTURE_2D, 0, internal_format, dst_width, dst_height, 0, input_format, GL_UNSIGNED_BYTE, rescaled);#if GENERATE_MIPMAPS // Build mipmaps. image::image_base im(rescaled, dst_width, dst_height, dst_width * bytes_per_pixel); generate_mipmaps(internal_format, input_format, bytes_per_pixel, &im);#endif // GENERATE_MIPMAPS delete [] rescaled;}bitmap_info_ogl::bitmap_info_ogl()// Make a placeholder bitmap_info. Must be filled in later before// using.{ m_texture_id = 0; m_original_width = 0; m_original_height = 0;}bitmap_info_ogl::bitmap_info_ogl(int width, int height, Uint8* data)// Initialize this bitmap_info to an alpha image// containing the specified data (1 byte per texel).//// !! Munges *data in order to create mipmaps !!{ assert(width > 0); assert(height > 0); assert(data); m_texture_id = 0; // Create the texture. glEnable(GL_TEXTURE_2D); glGenTextures(1, (GLuint*)&m_texture_id); glBindTexture(GL_TEXTURE_2D, m_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // GL_NEAREST ? glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); m_original_width = width; m_original_height = height; #ifndef NDEBUG // You must use power-of-two dimensions!! int w = 1; while (w < width) { w <<= 1; } int h = 1; while (h < height) { h <<= 1; } assert(w == width); assert(h == height); #endif // not NDEBUG glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); // Build mips. int level = 1; while (width > 1 || height > 1) { render_handler_ogl::make_next_miplevel(&width, &height, data); glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); level++; }}bitmap_info_ogl::bitmap_info_ogl(image::rgb* im)// NOTE: This function destroys im's data in the process of making mipmaps.{ assert(im); // Create the texture. glEnable(GL_TEXTURE_2D); glGenTextures(1, (GLuint*)&m_texture_id); glBindTexture(GL_TEXTURE_2D, m_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);#if GENERATE_MIPMAPS glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);#else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);#endif m_original_width = im->m_width; m_original_height = im->m_height; int w = 1; while (w < im->m_width) { w <<= 1; } int h = 1; while (h < im->m_height) { h <<= 1; } if (w != im->m_width || h != im->m_height) {#if (RESAMPLE_METHOD == 1) int viewport_dim[2] = { 0, 0 }; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &viewport_dim[0]); if (w > viewport_dim[0] || h > viewport_dim[1] || im->m_width * 3 != im->m_pitch) { // Can't use hardware resample. Either frame // buffer isn't big enough to fit the source // texture, or the source data isn't padded // quite right. software_resample(3, im->m_width, im->m_height, im->m_pitch, im->m_data, w, h); } else { hardware_resample(3, im->m_width, im->m_height, im->m_data, w, h); }#elif (RESAMPLE_METHOD == 2) { // Faster/simpler software bilinear rescale. software_resample(3, im->m_width, im->m_height, im->m_pitch, im->m_data, w, h); }#else { // Fancy but slow software resampling. image::rgb* rescaled = image::create_rgb(w, h); image::resample(rescaled, 0, 0, w - 1, h - 1, im, 0, 0, (float) im->m_width, (float) im->m_height); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, rescaled->m_data);#if GENERATE_MIPMAPS generate_mipmaps(GL_RGB, GL_RGB, 3, rescaled);#endif // GENERATE_MIPMAPS delete rescaled; }#endif } else { // Use original image directly. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, im->m_data);#if GENERATE_MIPMAPS generate_mipmaps(GL_RGB, GL_RGB, 3, im);#endif // GENERATE_MIPMAPS }}bitmap_info_ogl::bitmap_info_ogl(image::rgba* im)// Version of the constructor that takes an image with alpha.// NOTE: This function destroys im's data in the process of making mipmaps.{ assert(im); // Create the texture. glEnable(GL_TEXTURE_2D); glGenTextures(1, (GLuint*)&m_texture_id); glBindTexture(GL_TEXTURE_2D, m_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // GL_NEAREST ?#if GENERATE_MIPMAPS glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);#else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);#endif m_original_width = im->m_width; m_original_height = im->m_height; int w = 1; while (w < im->m_width) { w <<= 1; } int h = 1; while (h < im->m_height) { h <<= 1; } if (w != im->m_width || h != im->m_height) {#if (RESAMPLE_METHOD == 1) int viewport_dim[2] = { 0, 0 }; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &viewport_dim[0]); if (w > viewport_dim[0] || h > viewport_dim[1] || im->m_width * 4 != im->m_pitch) { // Can't use hardware resample. Either frame // buffer isn't big enough to fit the source // texture, or the source data isn't padded // quite right. software_resample(4, im->m_width, im->m_height, im->m_pitch, im->m_data, w, h); } else { hardware_resample(4, im->m_width, im->m_height, im->m_data, w, h); }#elif (RESAMPLE_METHOD == 2) { // Faster/simpler software bilinear rescale. software_resample(4, im->m_width, im->m_height, im->m_pitch, im->m_data, w, h); }#else { // Fancy but slow software resampling. image::rgba* rescaled = image::create_rgba(w, h); image::resample(rescaled, 0, 0, w - 1, h - 1, im, 0, 0, (float) im->m_width, (float) im->m_height); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, rescaled->m_data);#if GENERATE_MIPMAPS generate_mipmaps(GL_RGBA, GL_RGBA, 4, rescaled);#endif // GENERATE_MIPMAPS delete rescaled; }#endif } else { // Use original image directly. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, im->m_data);#if GENERATE_MIPMAPS generate_mipmaps(GL_RGBA, GL_RGBA, 4, im);#endif // GENERATE_MIPMAPS }}gameswf::render_handler* gameswf::create_render_handler_ogl()// Factory.{ return new render_handler_ogl;}// Local Variables:// mode: C++// c-basic-offset: 8 // tab-width: 8// indent-tabs-mode: t// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -