⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameswf_render_handler_ogl.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			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 + -