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

📄 gameswf_render_handler_xbox.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// gameswf_render_handler_xbox.cpp	-- Thatcher Ulrich <http://tulrich.com> 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// A gameswf::render_handler that uses Xbox API's#ifdef _XBOX#include "gameswf.h"#include "gameswf/gameswf_log.h"#include "gameswf_types.h"#include "base/image.h"#include "base/container.h"#include <xtl.h>#include <d3d8.h>#include <string.h>namespace{	array<IDirect3DBaseTexture8*>	s_d3d_textures;	DWORD	s_vshader_handle = 0;	// Our vertex coords consist of two signed 16-bit integers, for (x,y) position only.	DWORD	s_vshader_decl[] =	{		D3DVSD_STREAM(0),		D3DVSD_REG(0, D3DVSDT_SHORT2),		0xFFFFFFFF	};	void	init_vshader()	// Initialize the vshader we use for SWF mesh rendering.	{		if (s_vshader_handle == 0)		{			HRESULT	result;			/* Shader source:				xvs.1.1				#pragma screenspace				mov	oD0, v3				dp4 oPos.x, v0, c[0]	// Transform position				dp4 oPos.y, v0, c[1]				dp4 oPos.z, v0, c[2]				dp4 oPos.w, v0, c[3]				dp4 oT0.x, v0, c[4]	// texgen				dp4 oT0.y, v0, c[5]			   Compile that with xsasm -h sometmp.vsh, and insert the contents of sometmp.h below:			*/			static const DWORD	s_compiled_shader[] =			{				0x00072078,				0x00000000, 0x0020061b, 0x0836106c, 0x2070f818,				0x00000000, 0x00ec001b, 0x0836186c, 0x20708800,				0x00000000, 0x00ec201b, 0x0836186c, 0x20704800,				0x00000000, 0x00ec401b, 0x0836186c, 0x20702800,				0x00000000, 0x00ec601b, 0x0836186c, 0x20701800,				0x00000000, 0x00ec801b, 0x0836186c, 0x20708848,				0x00000000, 0x00eca01b, 0x0836186c, 0x20704849			};			result = IDirect3DDevice8::CreateVertexShader(				s_vshader_decl,				s_compiled_shader,				&s_vshader_handle,				D3DUSAGE_PERSISTENTDIFFUSE);			if (result != S_OK)			{				gameswf::log_error("error: can't create Xbox vshader; error code = %d\n", result);				return;			}		}	}};// bitmap_info_xbox declarationstruct bitmap_info_xbox : public gameswf::bitmap_info{	bitmap_info_xbox(create_empty e);	bitmap_info_xbox(image::rgb* im);	bitmap_info_xbox(image::rgba* im);	virtual void set_alpha_image(int width, int height, Uint8* data);};struct render_handler_xbox : public gameswf::render_handler{	// Some renderer state.	gameswf::matrix	m_viewport_matrix;	gameswf::matrix	m_current_matrix;	gameswf::cxform	m_current_cxform;		void set_antialiased(bool enable)	{		// not supported	}	static void make_next_miplevel(int* width, int* height, Uint8* data)	// Utility.  Mutates *width, *height and *data to create the	// next mip level.	{		assert(width);		assert(height);		assert(data);		int	new_w = *width >> 1;		int	new_h = *height >> 1;		if (new_w < 1) new_w = 1;		if (new_h < 1) new_h = 1;				if (new_w * 2 != *width	 || new_h * 2 != *height)		{			// Image can't be shrunk along (at least) one			// of its dimensions, so don't bother			// resampling.	Technically we should, but			// it's pretty useless at this point.  Just			// change the image dimensions and leave the			// existing pixels.		}		else		{			// Resample.  Simple average 2x2 --> 1, in-place.			for (int j = 0; j < new_h; j++) {				Uint8*	out = ((Uint8*) data) + j * new_w;				Uint8*	in = ((Uint8*) data) + (j << 1) * *width;				for (int i = 0; i < new_w; i++) {					int	a;					a = (*(in + 0) + *(in + 1) + *(in + 0 + *width) + *(in + 1 + *width));					*(out) = (Uint8) (a >> 2);					out++;					in += 2;				}			}		}		// Munge parameters to reflect the shrunken image.		*width = new_w;		*height = new_h;	}	struct fill_style	{		enum mode		{			INVALID,			COLOR,			BITMAP_WRAP,			BITMAP_CLAMP,			LINEAR_GRADIENT,			RADIAL_GRADIENT,		};		mode	m_mode;		gameswf::rgba	m_color;		const gameswf::bitmap_info*	m_bitmap_info;		gameswf::matrix	m_bitmap_matrix;		gameswf::cxform	m_bitmap_color_transform;		bool	m_has_nonzero_bitmap_additive_color;		fill_style()			:			m_mode(INVALID),			m_has_nonzero_bitmap_additive_color(false)		{		}		void	apply(/*const matrix& current_matrix*/) const		// Push our style into D3D.		{			assert(m_mode != INVALID);			if (m_mode == COLOR)			{				apply_color(m_color);				IDirect3DDevice8::SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);				//IDirect3DDevice8::SetRenderState(state, value);//				glDisable(GL_TEXTURE_2D);			}			else if (m_mode == BITMAP_WRAP				 || m_mode == BITMAP_CLAMP)			{				assert(m_bitmap_info != NULL);				apply_color(m_color);				if (m_bitmap_info == NULL)				{					IDirect3DDevice8::SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);					//glDisable(GL_TEXTURE_2D);				}				else				{					// Set up the texture for rendering.					{						// Do the modulate part of the color						// transform in the first pass.  The						// additive part, if any, needs to						// happen in a second pass.// 						glColor4f(m_bitmap_color_transform.m_[0][0],// 							  m_bitmap_color_transform.m_[1][0],// 							  m_bitmap_color_transform.m_[2][0],// 							  m_bitmap_color_transform.m_[3][0]// 							  );						IDirect3DDevice8::SetVertexData4f(							D3DVSDE_DIFFUSE, 							m_bitmap_color_transform.m_[0][0],							m_bitmap_color_transform.m_[1][0],							m_bitmap_color_transform.m_[2][0],							m_bitmap_color_transform.m_[3][0]);					}//					glBindTexture(GL_TEXTURE_2D, m_bitmap_info->m_texture_id);//					glEnable(GL_TEXTURE_2D);//					glEnable(GL_TEXTURE_GEN_S);//					glEnable(GL_TEXTURE_GEN_T);					IDirect3DDevice8::SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);					IDirect3DDevice8::SetTexture(0, s_d3d_textures[m_bitmap_info->m_texture_id]);									if (m_mode == BITMAP_CLAMP)					{//						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);//						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);						IDirect3DDevice8::SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);						IDirect3DDevice8::SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);					}					else					{						assert(m_mode == BITMAP_WRAP);//						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//						glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);						IDirect3DDevice8::SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);						IDirect3DDevice8::SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);					}					// Set up the bitmap matrix for texgen.					float	inv_width = 1.0f / m_bitmap_info->m_original_width;					float	inv_height = 1.0f / m_bitmap_info->m_original_height;					const gameswf::matrix&	m = m_bitmap_matrix;//					glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);					float	p[4] = { 0, 0, 0, 0 };					p[0] = m.m_[0][0] * inv_width;					p[1] = m.m_[0][1] * inv_width;					p[3] = m.m_[0][2] * inv_width;//					glTexGenfv(GL_S, GL_OBJECT_PLANE, p);					IDirect3DDevice8::SetVertexShaderConstant(4, p, 1);//					glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);					p[0] = m.m_[1][0] * inv_height;					p[1] = m.m_[1][1] * inv_height;					p[3] = m.m_[1][2] * inv_height;//					glTexGenfv(GL_T, GL_OBJECT_PLANE, p);					IDirect3DDevice8::SetVertexShaderConstant(5, p, 1);				}			}		}		bool	needs_second_pass() const		// Return true if we need to do a second pass to make		// a valid color.  This is for cxforms with additive		// parts.		{			if (m_mode == BITMAP_WRAP			    || m_mode == BITMAP_CLAMP)			{				return m_has_nonzero_bitmap_additive_color;			}			else			{				return false;			}		}		void	apply_second_pass() const		// Set D3D state for a necessary second pass.		{			assert(needs_second_pass());			// Additive color.			IDirect3DDevice8::SetVertexData4f(				D3DVSDE_DIFFUSE,				m_bitmap_color_transform.m_[0][1] / 255.0f,				m_bitmap_color_transform.m_[1][1] / 255.0f,				m_bitmap_color_transform.m_[2][1] / 255.0f,				m_bitmap_color_transform.m_[3][1] / 255.0f				);			IDirect3DDevice8::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);			IDirect3DDevice8::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);#if 0			glDisable(GL_TEXTURE_2D);			glColor4f(				m_bitmap_color_transform.m_[0][1] / 255.0f,				m_bitmap_color_transform.m_[1][1] / 255.0f,				m_bitmap_color_transform.m_[2][1] / 255.0f,				m_bitmap_color_transform.m_[3][1] / 255.0f				);			glBlendFunc(GL_ONE, GL_ONE);#endif // 0		}		void	cleanup_second_pass() const		{			IDirect3DDevice8::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);			IDirect3DDevice8::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);#if 0			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);#endif // 0		}		void	disable() { m_mode = INVALID; }		void	set_color(gameswf::rgba color) { m_mode = COLOR; m_color = color; }		void	set_bitmap(const gameswf::bitmap_info* bi, const gameswf::matrix& m, bitmap_wrap_mode wm, const gameswf::cxform& color_transform)		{			m_mode = (wm == WRAP_REPEAT) ? BITMAP_WRAP : BITMAP_CLAMP;			m_color = gameswf::rgba();			m_bitmap_info = bi;			m_bitmap_matrix = m;			m_bitmap_color_transform = color_transform;			if (m_bitmap_color_transform.m_[0][1] > 1.0f			    || m_bitmap_color_transform.m_[1][1] > 1.0f			    || m_bitmap_color_transform.m_[2][1] > 1.0f			    || m_bitmap_color_transform.m_[3][1] > 1.0f)			{				m_has_nonzero_bitmap_additive_color = true;			}			else			{				m_has_nonzero_bitmap_additive_color = false;			}		}		bool	is_valid() const { return m_mode != INVALID; }	};	render_handler_xbox()	// Constructor.	{		init_vshader();	}	// Style state.	enum style_index	{		LEFT_STYLE = 0,		RIGHT_STYLE,		LINE_STYLE,		STYLE_COUNT	};	fill_style	m_current_styles[STYLE_COUNT];	gameswf::bitmap_info*	create_bitmap_info(image::rgb* im)	// Given an image, returns a pointer to a bitmap_info struct	// that can later be passed to fill_styleX_bitmap(), to set a	// bitmap fill style.	{		return new bitmap_info_xbox(im);	}	gameswf::bitmap_info*	create_bitmap_info(image::rgba* im)	// Given an image, returns a pointer to a bitmap_info struct	// that can later be passed to fill_style_bitmap(), to set a	// bitmap fill style.	//	// This version takes an image with an alpha channel.	{		return new bitmap_info_xbox(im);	}	gameswf::bitmap_info*	create_bitmap_info_blank()	// Creates and returns an empty bitmap_info structure.	Image data	// can be bound to this info later, via set_alpha_image().	{		return new bitmap_info_xbox(gameswf::bitmap_info::empty);	}	void	set_alpha_image(gameswf::bitmap_info* bi, int w, int h, Uint8* data)	// Set the specified bitmap_info so that it contains an alpha	// texture with the given data (1 byte per texel).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -