void CzBitmapSprite::setColour(int index, const CzColour& colour) { if (Geometry == NULL) Prim->Colours[index] = colour.get(); else { if (Geometry->Colours == NULL) Prim->Colours[index] = colour.get(); else { Prim->Colours[index].r = (uint8)(((int)Geometry->Colours[index].r * colour.r) / 255); Prim->Colours[index].g = (uint8)(((int)Geometry->Colours[index].g * colour.g) / 255); Prim->Colours[index].b = (uint8)(((int)Geometry->Colours[index].b * colour.b) / 255); Prim->Colours[index].a = (uint8)(((int)Geometry->Colours[index].a * colour.a) / 255); } } }
// BatchDrawPrims - Currently only supports batching of Quad lists void CzPlatformRender::BatchDrawPrims(bool filter) { if (NextMaterial == 0) return; // Allocate memory from data cache for verts, UV's and colours for (int t = 0; t < NextMaterial; t++) { int prim_count = MaterialUsedCounts[t] * 4; BatchVerts[t] = IW_GX_ALLOC(CzVec2, prim_count); BatchUVs[t] = IW_GX_ALLOC(CzVec2, prim_count); BatchColours[t] = IW_GX_ALLOC(CzColour, prim_count); BatchIndices[t] = IW_GX_ALLOC(uint16, prim_count); } // Populate the data cache CzRenderPrim** prims = Primitives; for (int t = 0; t < NextPrimitive; t++) { CzRenderPrim *prim = *prims; int mat_id = prim->MaterialID; int idx = MaterialIndices[mat_id]; CzVec2* v = BatchVerts[mat_id] + idx; CzVec2* uv = BatchUVs[mat_id] + idx; CzColour* c = BatchColours[mat_id] + idx; uint16* i = BatchIndices[mat_id] + idx; for (int t2 = 0; t2 < 4; t2++) { v->x = (prim->Verts + t2)->x; v->y = (prim->Verts + t2)->y; uv->x = (prim->UVs + t2)->x; uv->y = (prim->UVs + t2)->y; c->set(*(prim->Colours + t2)); v++; uv++; c++; } // TODO: ERROR - Does not work with batched ngon *i++ = idx; *i++ = idx + 3; *i++ = idx + 2; *i++ = idx + 1; MaterialIndices[mat_id] += 4; prims++; } // Render batched streams CzRenderMaterial** mats = Materials; for (int t = 0; t < NextMaterial; t++) { int count = MaterialUsedCounts[t] * 4; IwGxSetUVStream((CIwFVec2*)BatchUVs[t], 0); IwGxSetVertStreamScreenSpace((CIwFVec2*)BatchVerts[t], count); IwGxSetColStream((CIwColour*)(BatchColours[t]), count); IwGxSetNormStream(NULL); CIwMaterial* mat = IW_GX_ALLOC_MATERIAL(); CIwTexture* texture = static_cast<CIwTexture*>((*mats)->Image->getTexture()); mat->SetTexture(texture); mat->SetDepthWriteMode(CIwMaterial::DEPTH_WRITE_DISABLED); mat->SetClamping(false); mat->SetFiltering(filter); mat->SetAlphaMode(CIwMaterial::ALPHA_BLEND); mat->SetCullMode(CIwMaterial::CULL_BACK); // mat->SetCullMode(CIwMaterial::CULL_NONE); IwGxSetMaterial(mat); IwGxDrawPrims(IW_GX_QUAD_LIST, BatchIndices[t], count); mats++; } // Reset batch pointers for (int t = 0; t < NextMaterial; t++) MaterialUsedCounts[t] = 0; for (int t = 0; t < NextMaterial; t++) MaterialIndices[t] = 0; NextPrimitive = 0; NextMaterial = 0; }
void CzPlatformRender::DrawText(CzFontPreparedText prepared_text, CzFont* font, CzMatrix3* transform, const CzColour& colour, CzVec4& skew, bool filter, eCzAlphaMode alpha_mode) { CIwMaterial::AlphaMode am = (CIwMaterial::AlphaMode)alpha_mode; // TODO Add proper method map Marmalade Alpha mode to Marmalade // Cache the transform float m00 = transform->m[0][0]; float m01 = transform->m[0][1]; float m10 = transform->m[1][0]; float m11 = transform->m[1][1]; float tx = transform->getX(); float ty = transform->getY(); float sx1 = (float)skew.x; float sx2 = (float)skew.y; float sy1 = (float)skew.z; float sy2 = (float)skew.w; /* CzIRect clip = ScreenClipRect; clip.x <<= 3; clip.y <<= 3; clip.w = clip.x + (clip.w << 3); clip.h = clip.y + (clip.h << 3);*/ IwGxLightingOn(); IwGxSetColStream(NULL); IwGxSetNormStream(NULL); CIwGxFont* mfont = static_cast<CIwGxFont*>(font->getFontHandle()); CIwGxFontPreparedData* prep_text = static_cast<CIwGxFontPreparedData*>(prepared_text); // A font can consist of multiple materials so we need to process all of them for (int t = 0; t < mfont->GetNumberMaterials(); t++) { // Set UV stream uint32* char_ids; int num_chars = IwGxFontSetUVs(*prep_text, -1, t, &char_ids); // Generate transformed vertices from glyphs int nv = num_chars << 2; CzVec2* pVerts = IW_GX_ALLOC(CzVec2, nv); CzVec2* pVert = pVerts; if (m01 == 0 && m10 == 0) { // No rotation optimisation for (int t2 = 0; t2 < num_chars; t2++) { CIwRect rc = prep_text->GetCharacterArea(char_ids[t2]); float x1 = (float)rc.x; float y1 = (float)rc.y; float x2 = x1 + (float)rc.w; float y2 = y1 + (float)rc.h; float ax = (m00 * x1) + tx; float ay = (m11 * y1) + ty; float bx = (m00 * x2) + tx; float by = (m11 * y2) + ty; // if ((ax < clip.w && bx >= clip.x) && (ay < clip.h && by >= clip.y)) // { pVert->x = ax + sx1; pVert->y = ay + sy1; pVert++; pVert->x = ax - sx1; pVert->y = by + sy2; pVert++; pVert->x = bx - sx2; pVert->y = by - sy2; pVert++; pVert->x = bx + sx2; pVert->y = ay - sy1; pVert++; // } } } else { for (int t2 = 0; t2 < num_chars; t2++) { CIwRect rc = prep_text->GetCharacterArea(char_ids[t2]); float x1 = (float)rc.x; float y1 = (float)rc.y; float x2 = x1 + (float)rc.w; float y2 = y1 + (float)rc.h; pVert->x = (m00 * x1 + m10 * y1 + tx + sx1); pVert->y = (m01 * x1 + m11 * y1 + ty + sy1); pVert++; pVert->x = (m00 * x1 + m10 * y2 + tx - sx1); pVert->y = (m01 * x1 + m11 * y2 + ty + sy2); pVert++; pVert->x = (m00 * x2 + m10 * y2 + tx - sx2); pVert->y = (m01 * x2 + m11 * y2 + ty - sy2); pVert++; pVert->x = (m00 * x2 + m10 * y1 + tx + sx2); pVert->y = (m01 * x2 + m11 * y1 + ty - sy1); pVert++; } } if (nv > 0) { // Set vertex stream IwGxSetVertStreamScreenSpace((CIwFVec2*)pVerts, nv); // Create a material CIwMaterial* mat = IW_GX_ALLOC_MATERIAL(); mat->Copy(*IwGxFontGetFont()->GetMaterial(t)); mat->SetDepthWriteMode(CIwMaterial::DEPTH_WRITE_DISABLED); mat->SetColEmissive(colour.get()); mat->SetClamping(true); mat->SetFiltering(filter); mat->SetAlphaMode(am); mat->SetCullMode(CIwMaterial::CULL_BACK); // mat->SetCullMode(CIwMaterial::CULL_NONE); IwGxSetMaterial(mat); // Finally draw the glyphs IwGxDrawPrims(IW_GX_QUAD_LIST, NULL, nv); CurrentAlphaMode = alpha_mode; } } IwGxLightingOff(); CurrentTexture = NULL; }