void GrTextBlob::appendGlyph(int runIndex, const SkRect& positions, GrColor color, const sk_sp<GrTextStrike>& strike, GrGlyph* glyph, bool preTransformed) { Run& run = fRuns[runIndex]; GrMaskFormat format = glyph->fMaskFormat; Run::SubRunInfo* subRun = &run.fSubRunInfo.back(); if (run.fInitialized && subRun->maskFormat() != format) { subRun = &run.push_back(); subRun->setStrike(strike); } else if (!run.fInitialized) { subRun->setStrike(strike); } run.fInitialized = true; bool hasW = subRun->hasWCoord(); // glyphs drawn in perspective must always have a w coord. SkASSERT(hasW || !fInitialViewMatrix.hasPerspective()); size_t vertexStride = GetVertexStride(format, hasW); subRun->setMaskFormat(format); subRun->joinGlyphBounds(positions); subRun->setColor(color); intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex()); // We always write the third position component used by SDFs. If it is unused it gets // overwritten. Similarly, we always write the color and the blob will later overwrite it // with texture coords if it is unused. size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint); // V0 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fTop, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; vertex += vertexStride; // V1 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fBottom, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; vertex += vertexStride; // V2 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fTop, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; vertex += vertexStride; // V3 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fBottom, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; subRun->appendVertices(vertexStride); fGlyphs[subRun->glyphEndIndex()] = glyph; subRun->glyphAppended(); subRun->setNeedsTransform(!preTransformed); }
void GrAtlasTextBlob::appendGlyph(int runIndex, const SkRect& positions, GrColor color, GrBatchTextStrike* strike, GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph, SkScalar x, SkScalar y, SkScalar scale, bool applyVM) { // If the glyph is too large we fall back to paths if (glyph->fTooLargeForAtlas) { this->appendLargeGlyph(glyph, cache, skGlyph, x, y, scale, applyVM); return; } Run& run = fRuns[runIndex]; GrMaskFormat format = glyph->fMaskFormat; Run::SubRunInfo* subRun = &run.fSubRunInfo.back(); if (run.fInitialized && subRun->maskFormat() != format) { subRun = &run.push_back(); subRun->setStrike(strike); } else if (!run.fInitialized) { subRun->setStrike(strike); } run.fInitialized = true; size_t vertexStride = GetVertexStride(format); subRun->setMaskFormat(format); subRun->joinGlyphBounds(positions); subRun->setColor(color); intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex()); if (kARGB_GrMaskFormat != glyph->fMaskFormat) { // V0 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fTop); SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; vertex += vertexStride; // V1 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fBottom); colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; vertex += vertexStride; // V2 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fBottom); colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; vertex += vertexStride; // V3 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fTop); colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; } else { // V0 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fTop); vertex += vertexStride; // V1 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fBottom); vertex += vertexStride; // V2 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fBottom); vertex += vertexStride; // V3 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fTop); } subRun->appendVertices(vertexStride); fGlyphs[subRun->glyphEndIndex()] = glyph; subRun->glyphAppended(); }
void CUnit::CreateRenderable(IVertex *pVertex, const char *texfile) { uint vertAttr = pVertex->GetVertexAttribute(); if (m_pRenderable) { m_pVAO->Bind(); IShaderProgram *pShaderProgram = m_pRenderable->GetShaderProgram(); if (pShaderProgram) { if (vertAttr == VF_POSITION) pShaderProgram->CreateStandShader(ESS_SHADER_IDENTITY); else if (vertAttr == (VF_POSITION | VF_COLOR)) pShaderProgram->CreateStandShader(ESS_SHADER_FLAT); else if (vertAttr == (VF_POSITION | VF_TEXCOORD)) pShaderProgram->CreateStandShader(ESS_SHADER_TEXTURE_REPLACE); else if (vertAttr == (VF_POSITION | VF_COLOR)) pShaderProgram->CreateStandShader(ESS_SHADER_SHADED); else if (vertAttr == (VF_POSITION | VF_COLOR | VF_TEXCOORD)) pShaderProgram->CreateStandShader(ESS_SHADER_TEXTURE_MODULATE); else if (vertAttr == (VF_POSITION | VF_TEXCOORD | VF_NORMAL)) pShaderProgram->CreateStandShader(ESS_SHADER_TEXTURE_REPLACE); else if (vertAttr == (VF_POSITION | VF_COLOR | VF_NORMAL | VF_TEXCOORD)) pShaderProgram->CreateStandShader(ESS_SHADER_TEXTURE_REPLACE); m_pTexture = RENDERER->CreateTexture(texfile); m_pRenderable->SetTexture(0, m_pTexture); uint pUnit = 0; pShaderProgram->SetUniform("textureUnit0", &pUnit); float vColor[] = { 1, 1, 1, 1 }; pShaderProgram->SetUniform("vColor", vColor); m_pRenderable->CreateVertexBufferObject(pVertex->GetVertexData(), pVertex->GetVerticeSize(), 0, pVertex->GetVerticeCount(), GBM_TRIANGLES, GBU_DYNAMIC_DRAW); m_pRenderable->CreateIndexBufferObject(pVertex->GetIndicesData(), pVertex->GetIndicesCount(), RVT_UINT, GBM_TRIANGLES, GBU_DYNAMIC_DRAW); uint stride = GetVertexStride(EVertexAttribute(vertAttr)); uint offset = 0; if (vertAttr & VF_POSITION) { m_pVAO->EnableVertexAttrib(render::VAL_POSITION, 3, render::RVT_FLOAT, stride, offset); offset += 3 * sizeof(float); } if (vertAttr & VF_COLOR) { m_pVAO->EnableVertexAttrib(render::VAL_COLOR, 4, render::RVT_FLOAT, stride, offset); offset += 4 * sizeof(float); } if (vertAttr & VF_TEXCOORD) { m_pVAO->EnableVertexAttrib(render::VAL_TEXTURE0, 2, render::RVT_FLOAT, stride, offset); offset += 2 * sizeof(float); } if (vertAttr & VF_NORMAL) { m_pVAO->EnableVertexAttrib(render::VAL_NORMAL, 3, render::RVT_FLOAT, stride, offset); offset += 3 * sizeof(float); } m_pVAO->UnBind(); } } }
Mesh* Mesh::CreateFromFBX(RenderSystem* pRenderSys, tstring const& filename) { try { tstring path = Core::GetInstance()->GetAssetsDir() + TEXT("/Models/") + filename; const aiScene* scene = aiImportFile(wstr2str(path).c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_ConvertToLeftHanded | aiProcess_TransformUVCoords); Float3 min, max; if (scene == nullptr || scene->mNumMeshes == 0) throw std::exception("No Mesh in this file"); Mesh* ret = new Mesh(); for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { MeshPart* part = ret->CreatePart(); aiMesh* pAiPart = scene->mMeshes[meshIndex]; int32 numVertices = pAiPart->mNumVertices; int32 numFaces = pAiPart->mNumFaces; int32 numUVChannels = scene->mMeshes[meshIndex]->GetNumUVChannels(); if (!pAiPart->HasFaces() || !pAiPart->HasNormals() || !pAiPart->HasPositions() || !pAiPart->HasTextureCoords(0) || !pAiPart->HasTangentsAndBitangents()) { ret->RemovePart(part); continue; }; min = Float3((float*)&(pAiPart->mVertices[0])); max = Float3((float*)&(pAiPart->mVertices[0])); part->m_pInputLayout.reset(new InputLayout{ { VertexElemType::Float3, ElemSemantic::Position, 0, 0, ElementClass::PerVertex, 0 }, { VertexElemType::Float3, ElemSemantic::Normal, 0, 0, ElementClass::PerVertex, 0 }, { VertexElemType::Float3, ElemSemantic::Tangent, 0, 0, ElementClass::PerVertex, 0 }, }); auto layout = part->m_pInputLayout; for (int32 i = 0; i < numUVChannels; ++i) layout->Insert(layout->End(), { VertexElemType::Float2, ElemSemantic::TexCoord, (uint32)i, 0, ElementClass::PerVertex, 0 }); uint32 stride = layout->GetVertexStride(0); byte* vertices = new byte[stride * numVertices]; uint16* indices = new uint16[3 * numFaces]; auto elemPosition = layout->Begin(); auto elemNormal = elemPosition + 1; auto elemTangent = elemNormal + 1; #define Get(V,i,stride,offset) (V + stride * i + offset) for (int32 i = 0; i < numVertices; ++i) { *(Float3*)Get(vertices, i, stride, elemPosition->AlignedByteOffset) = Float3((float*)&(pAiPart->mVertices[i])); *(Float3*)Get(vertices, i, stride, elemTangent->AlignedByteOffset) = Float3((float*)&(pAiPart->mTangents[i])); *(Float3*)Get(vertices, i, stride, elemNormal->AlignedByteOffset) = Float3((float*)&(pAiPart->mNormals[i])); auto elemTexCoord = elemTangent + 1; for (int32 j = 0; j < numUVChannels; ++j) { aiVector3D texcoord = pAiPart->mTextureCoords[j][i]; *(Float2*)Get(vertices, i, stride, elemTexCoord->AlignedByteOffset) = Float2((float*)&(pAiPart->mTextureCoords[j][i])); ++elemTexCoord; } #if UV_MIRROR float t = dot(cross(scene->mMeshes[meshIndex]->mNormals[i], scene->mMeshes[meshIndex]->mTangents[i]), scene->mMeshes[meshIndex]->mBitangents[i]); if (t < 0) vertices[i].Tangent = float3(-vertices[i].Tangent.r, vertices[i].Tangent.g, vertices[i].Tangent.b); #endif min.x = std::min(min.x, pAiPart->mVertices[i].x); min.y = std::min(min.y, pAiPart->mVertices[i].y); min.z = std::min(min.z, pAiPart->mVertices[i].z); max.x = std::max(max.x, pAiPart->mVertices[i].x); max.y = std::max(max.y, pAiPart->mVertices[i].y); max.z = std::max(max.z, pAiPart->mVertices[i].z); } part->m_Size = std::max(max.x - min.x, std::max(max.y - min.y, max.z - min.z)); part->m_Center = Float3((min.x + max.x) / 2.0f, (min.y + max.y) / 2.0f, (min.z + max.z) / 2.0f); for (long long i = 0; i < numFaces; ++i) { aiFace* face = &(scene->mMeshes[meshIndex]->mFaces[i]); indices[3 * i] = face->mIndices[0]; indices[3 * i + 1] = face->mIndices[1]; indices[3 * i + 2] = face->mIndices[2]; assert( indices[3 * i] <= numVertices && indices[3 * i + 1] <= numVertices && indices[3 * i + 2] <= numVertices ); } part->m_NumPrimitives = numFaces; part->m_pVertexBuffer.reset( VertexBuffer::Create(pRenderSys, vertices, layout->GetVertexStride(0) * numVertices, layout->GetVertexStride(0))); part->m_pIndexBuffer.reset( IndexBuffer::Create(pRenderSys, (byte*)indices, sizeof(uint16) * 3 * numFaces, DataFormat::R16_UINT)); delete vertices; delete indices; } aiReleaseImport(scene); return ret; } catch (std::exception& e) { Log(e.what()); return nullptr; } }