?? gameswf_render_handler_xbox.cpp
字號(hào):
// 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).
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -