bool SkPatchUtils::getVertexData(SkPatchUtils::VertexData* data, const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], int lodX, int lodY) { if (lodX < 1 || lodY < 1 || NULL == cubics || NULL == data) { return false; } // check for overflow in multiplication const int64_t lodX64 = (lodX + 1), lodY64 = (lodY + 1), mult64 = lodX64 * lodY64; if (mult64 > SK_MaxS32) { return false; } data->fVertexCount = SkToS32(mult64); // it is recommended to generate draw calls of no more than 65536 indices, so we never generate // more than 60000 indices. To accomplish that we resize the LOD and vertex count if (data->fVertexCount > 10000 || lodX > 200 || lodY > 200) { SkScalar weightX = static_cast<SkScalar>(lodX) / (lodX + lodY); SkScalar weightY = static_cast<SkScalar>(lodY) / (lodX + lodY); // 200 comes from the 100 * 2 which is the max value of vertices because of the limit of // 60000 indices ( sqrt(60000 / 6) that comes from data->fIndexCount = lodX * lodY * 6) lodX = static_cast<int>(weightX * 200); lodY = static_cast<int>(weightY * 200); data->fVertexCount = (lodX + 1) * (lodY + 1); } data->fIndexCount = lodX * lodY * 6; data->fPoints = SkNEW_ARRAY(SkPoint, data->fVertexCount); data->fIndices = SkNEW_ARRAY(uint16_t, data->fIndexCount); // if colors is not null then create array for colors SkPMColor colorsPM[kNumCorners]; if (NULL != colors) { // premultiply colors to avoid color bleeding. for (int i = 0; i < kNumCorners; i++) { colorsPM[i] = SkPreMultiplyColor(colors[i]); } data->fColors = SkNEW_ARRAY(uint32_t, data->fVertexCount); } // if texture coordinates are not null then create array for them if (NULL != texCoords) { data->fTexCoords = SkNEW_ARRAY(SkPoint, data->fVertexCount); } SkPoint pts[kNumPtsCubic]; SkPatchUtils::getBottomCubic(cubics, pts); FwDCubicEvaluator fBottom(pts); SkPatchUtils::getTopCubic(cubics, pts); FwDCubicEvaluator fTop(pts); SkPatchUtils::getLeftCubic(cubics, pts); FwDCubicEvaluator fLeft(pts); SkPatchUtils::getRightCubic(cubics, pts); FwDCubicEvaluator fRight(pts); fBottom.restart(lodX); fTop.restart(lodX); SkScalar u = 0.0f; int stride = lodY + 1; for (int x = 0; x <= lodX; x++) { SkPoint bottom = fBottom.next(), top = fTop.next(); fLeft.restart(lodY); fRight.restart(lodY); SkScalar v = 0.f; for (int y = 0; y <= lodY; y++) { int dataIndex = x * (lodY + 1) + y; SkPoint left = fLeft.next(), right = fRight.next(); SkPoint s0 = SkPoint::Make((1.0f - v) * top.x() + v * bottom.x(), (1.0f - v) * top.y() + v * bottom.y()); SkPoint s1 = SkPoint::Make((1.0f - u) * left.x() + u * right.x(), (1.0f - u) * left.y() + u * right.y()); SkPoint s2 = SkPoint::Make( (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].x() + u * fTop.getCtrlPoints()[3].x()) + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].x() + u * fBottom.getCtrlPoints()[3].x()), (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].y() + u * fTop.getCtrlPoints()[3].y()) + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].y() + u * fBottom.getCtrlPoints()[3].y())); data->fPoints[dataIndex] = s0 + s1 - s2; if (NULL != colors) { uint8_t a = uint8_t(bilerp(u, v, SkScalar(SkColorGetA(colorsPM[kTopLeft_Corner])), SkScalar(SkColorGetA(colorsPM[kTopRight_Corner])), SkScalar(SkColorGetA(colorsPM[kBottomLeft_Corner])), SkScalar(SkColorGetA(colorsPM[kBottomRight_Corner])))); uint8_t r = uint8_t(bilerp(u, v, SkScalar(SkColorGetR(colorsPM[kTopLeft_Corner])), SkScalar(SkColorGetR(colorsPM[kTopRight_Corner])), SkScalar(SkColorGetR(colorsPM[kBottomLeft_Corner])), SkScalar(SkColorGetR(colorsPM[kBottomRight_Corner])))); uint8_t g = uint8_t(bilerp(u, v, SkScalar(SkColorGetG(colorsPM[kTopLeft_Corner])), SkScalar(SkColorGetG(colorsPM[kTopRight_Corner])), SkScalar(SkColorGetG(colorsPM[kBottomLeft_Corner])), SkScalar(SkColorGetG(colorsPM[kBottomRight_Corner])))); uint8_t b = uint8_t(bilerp(u, v, SkScalar(SkColorGetB(colorsPM[kTopLeft_Corner])), SkScalar(SkColorGetB(colorsPM[kTopRight_Corner])), SkScalar(SkColorGetB(colorsPM[kBottomLeft_Corner])), SkScalar(SkColorGetB(colorsPM[kBottomRight_Corner])))); data->fColors[dataIndex] = SkPackARGB32(a,r,g,b); } if (NULL != texCoords) { data->fTexCoords[dataIndex] = SkPoint::Make( bilerp(u, v, texCoords[kTopLeft_Corner].x(), texCoords[kTopRight_Corner].x(), texCoords[kBottomLeft_Corner].x(), texCoords[kBottomRight_Corner].x()), bilerp(u, v, texCoords[kTopLeft_Corner].y(), texCoords[kTopRight_Corner].y(), texCoords[kBottomLeft_Corner].y(), texCoords[kBottomRight_Corner].y())); } if(x < lodX && y < lodY) { int i = 6 * (x * lodY + y); data->fIndices[i] = x * stride + y; data->fIndices[i + 1] = x * stride + 1 + y; data->fIndices[i + 2] = (x + 1) * stride + 1 + y; data->fIndices[i + 3] = data->fIndices[i]; data->fIndices[i + 4] = data->fIndices[i + 2]; data->fIndices[i + 5] = (x + 1) * stride + y; } v = SkScalarClampMax(v + 1.f / lodY, 1); } u = SkScalarClampMax(u + 1.f / lodX, 1); } return true; }
void SkDrawColor::dump(SkAnimateMaker* maker) { dumpBase(maker); SkDebugf("alpha=\"%d\" red=\"%d\" green=\"%d\" blue=\"%d\" />\n", SkColorGetA(color)/255, SkColorGetR(color), SkColorGetG(color), SkColorGetB(color)); }
SkPMColor SkPreMultiplyColor(SkColor c) { return SkPremultiplyARGBInline(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); }
// populateDict and operator== have to stay in sync with each other. void SkPDFGraphicState::populateDict() { if (!fPopulated) { fPopulated = true; SkRefPtr<SkPDFName> typeName = new SkPDFName("ExtGState"); typeName->unref(); // SkRefPtr and new both took a reference. insert("Type", typeName.get()); SkScalar maxAlpha = SkIntToScalar(0xFF); SkRefPtr<SkPDFScalar> alpha = new SkPDFScalar(SkColorGetA(fPaint.getColor())/maxAlpha); alpha->unref(); // SkRefPtr and new both took a reference. insert("CA", alpha.get()); insert("ca", alpha.get()); SkASSERT(SkPaint::kButt_Cap == 0); SkASSERT(SkPaint::kRound_Cap == 1); SkASSERT(SkPaint::kSquare_Cap == 2); SkASSERT(fPaint.getStrokeCap() >= 0 && fPaint.getStrokeCap() <= 2); SkRefPtr<SkPDFInt> strokeCap = new SkPDFInt(fPaint.getStrokeCap()); strokeCap->unref(); // SkRefPtr and new both took a reference. insert("LC", strokeCap.get()); SkASSERT(SkPaint::kMiter_Join == 0); SkASSERT(SkPaint::kRound_Join == 1); SkASSERT(SkPaint::kBevel_Join == 2); SkASSERT(fPaint.getStrokeJoin() >= 0 && fPaint.getStrokeJoin() <= 2); SkRefPtr<SkPDFInt> strokeJoin = new SkPDFInt(fPaint.getStrokeJoin()); strokeJoin->unref(); // SkRefPtr and new both took a reference. insert("LJ", strokeJoin.get()); /* TODO(vandebo) Font. if (fPaint.getTypeFace() != NULL) { SkRefPtr<SkPDFTypeFace> typeFace = SkPDFTypeFace::getFontForTypeFace(fPaint.getTypeFace); SkRefPtr<SkPDFObjRef> typeFaceRef = new SkPDFObjRef(typeFace.get()); fontRef->unref(); // SkRefPtr and new both took a reference. SkRefPtr<SkPDFScalar> fontSize = new SkPDFScalar(fPaint.getTetSize()); fontSize->unref(); // SkRefPtr and new both took a reference. SkRefPtr<SkPDFArray> font = new SkPDFArray(); font->unref(); // SkRefPtr and new both took a reference. font->reserve(2); font->append(typeFaceRef.get()); font->append(fontSize.get()); insert("LJ", font.get()); } */ SkRefPtr<SkPDFScalar> strokeWidth = new SkPDFScalar(fPaint.getStrokeWidth()); strokeWidth->unref(); // SkRefPtr and new both took a reference. insert("LW", strokeWidth.get()); SkRefPtr<SkPDFScalar> strokeMiterLimit = new SkPDFScalar( fPaint.getStrokeMiter()); strokeMiterLimit->unref(); // SkRefPtr and new both took a reference. insert("ML", strokeWidth.get()); // Turn on automatic stroke adjustment. SkRefPtr<SkPDFBool> trueVal = new SkPDFBool(true); trueVal->unref(); // SkRefPtr and new both took a reference. insert("SA", trueVal.get()); } }
void SkGradientShaderBase::GradientShaderCache::Build32bitCache( SkPMColor cache[], SkColor c0, SkColor c1, int count, U8CPU paintAlpha, uint32_t gradFlags) { SkASSERT(count > 1); // need to apply paintAlpha to our two endpoints uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha); const bool interpInPremul = SkToBool(gradFlags & SkGradientShader::kInterpolateColorsInPremul_Flag); uint32_t r0 = SkColorGetR(c0); uint32_t g0 = SkColorGetG(c0); uint32_t b0 = SkColorGetB(c0); uint32_t r1 = SkColorGetR(c1); uint32_t g1 = SkColorGetG(c1); uint32_t b1 = SkColorGetB(c1); if (interpInPremul) { r0 = SkMulDiv255Round(r0, a0); g0 = SkMulDiv255Round(g0, a0); b0 = SkMulDiv255Round(b0, a0); r1 = SkMulDiv255Round(r1, a1); g1 = SkMulDiv255Round(g1, a1); b1 = SkMulDiv255Round(b1, a1); } SkFixed da = SkIntToFixed(a1 - a0) / (count - 1); SkFixed dr = SkIntToFixed(r1 - r0) / (count - 1); SkFixed dg = SkIntToFixed(g1 - g0) / (count - 1); SkFixed db = SkIntToFixed(b1 - b0) / (count - 1); /* We pre-add 1/8 to avoid having to add this to our [0] value each time in the loop. Without this, the bias for each would be 0x2000 0xA000 0xE000 0x6000 With this trick, we can add 0 for the first (no-op) and just adjust the others. */ SkUFixed a = SkIntToFixed(a0) + 0x2000; SkUFixed r = SkIntToFixed(r0) + 0x2000; SkUFixed g = SkIntToFixed(g0) + 0x2000; SkUFixed b = SkIntToFixed(b0) + 0x2000; /* * Our dither-cell (spatially) is * 0 2 * 3 1 * Where * [0] -> [-1/8 ... 1/8 ) values near 0 * [1] -> [ 1/8 ... 3/8 ) values near 1/4 * [2] -> [ 3/8 ... 5/8 ) values near 1/2 * [3] -> [ 5/8 ... 7/8 ) values near 3/4 */ if (0xFF == a0 && 0 == da) { do { cache[kCache32Count*0] = SkPackARGB32(0xFF, (r + 0 ) >> 16, (g + 0 ) >> 16, (b + 0 ) >> 16); cache[kCache32Count*1] = SkPackARGB32(0xFF, (r + 0x8000) >> 16, (g + 0x8000) >> 16, (b + 0x8000) >> 16); cache[kCache32Count*2] = SkPackARGB32(0xFF, (r + 0xC000) >> 16, (g + 0xC000) >> 16, (b + 0xC000) >> 16); cache[kCache32Count*3] = SkPackARGB32(0xFF, (r + 0x4000) >> 16, (g + 0x4000) >> 16, (b + 0x4000) >> 16); cache += 1; r += dr; g += dg; b += db; } while (--count != 0); } else if (interpInPremul) {
bool SkColorShader::isOpaque() const { return SkColorGetA(fColor) == 255; }
// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into // the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's // paint. static void apply_7(SkDebugCanvas* canvas, int curCommand) { SkSaveLayerCommand* saveLayer0 = (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2); SkSaveLayerCommand* saveLayer1 = (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5); SkClipRectCommand* clip2 = (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7); SkDrawBitmapRectCommand* dbmr = (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8); SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft; SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop; SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop, clip2->rect().width(), clip2->rect().height()); dbmr->setSrcRect(newSrc); dbmr->setDstRect(clip2->rect()); SkColor color = 0xFF000000; int a0, a1; const SkPaint* saveLayerPaint0 = saveLayer0->paint(); if (saveLayerPaint0) { color = saveLayerPaint0->getColor(); a0 = SkColorGetA(color); } else { a0 = 0xFF; } const SkPaint* saveLayerPaint1 = saveLayer1->paint(); if (saveLayerPaint1) { color = saveLayerPaint1->getColor(); a1 = SkColorGetA(color); } else { a1 = 0xFF; } int newA = SkMulDiv255Round(a0, a1); SkASSERT(newA <= 0xFF); SkPaint* dbmrPaint = dbmr->paint(); if (dbmrPaint) { SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA); dbmrPaint->setColor(newColor); } else { SkColor newColor = SkColorSetA(color, newA); SkPaint newPaint; newPaint.setColor(newColor); dbmr->setPaint(newPaint); } // remove everything except the drawbitmaprect canvas->deleteDrawCommandAt(curCommand+13); // restore canvas->deleteDrawCommandAt(curCommand+12); // restore canvas->deleteDrawCommandAt(curCommand+11); // restore canvas->deleteDrawCommandAt(curCommand+10); // restore canvas->deleteDrawCommandAt(curCommand+9); // restore canvas->deleteDrawCommandAt(curCommand+7); // clipRect canvas->deleteDrawCommandAt(curCommand+6); // save canvas->deleteDrawCommandAt(curCommand+5); // saveLayer canvas->deleteDrawCommandAt(curCommand+4); // clipRect canvas->deleteDrawCommandAt(curCommand+3); // save canvas->deleteDrawCommandAt(curCommand+2); // saveLayer canvas->deleteDrawCommandAt(curCommand+1); // clipRect canvas->deleteDrawCommandAt(curCommand); // save }
PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const { GraphicsContext* gc = this->context(); if (!gc) { return 0; } const SkBitmap& src = imageBufferCanvas(this)->getDevice()->accessBitmap(false); SkAutoLockPixels alp(src); if (!src.getPixels()) { return 0; } RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4); unsigned char* data = result->data(); if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > m_size.width() || rect.maxY() > m_size.height()) memset(data, 0, result->length()); int originx = rect.x(); int destx = 0; if (originx < 0) { destx = -originx; originx = 0; } int endx = rect.x() + rect.width(); if (endx > m_size.width()) endx = m_size.width(); int numColumns = endx - originx; int originy = rect.y(); int desty = 0; if (originy < 0) { desty = -originy; originy = 0; } int endy = rect.y() + rect.height(); if (endy > m_size.height()) endy = m_size.height(); int numRows = endy - originy; unsigned srcPixelsPerRow = src.rowBytesAsPixels(); unsigned destBytesPerRow = 4 * rect.width(); const SkPMColor* srcRows = src.getAddr32(originx, originy); unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; for (int y = 0; y < numRows; ++y) { for (int x = 0; x < numColumns; x++) { // ugh, it appears they want unpremultiplied pixels SkColor c = SkUnPreMultiply::PMColorToColor(srcRows[x]); int basex = x * 4; destRows[basex + 0] = SkColorGetR(c); destRows[basex + 1] = SkColorGetG(c); destRows[basex + 2] = SkColorGetB(c); destRows[basex + 3] = SkColorGetA(c); } srcRows += srcPixelsPerRow; destRows += destBytesPerRow; } return result.release(); }
void GrBitmapTextContext::flushGlyphs() { if (NULL == fDrawTarget) { return; } GrDrawState* drawState = fDrawTarget->drawState(); GrDrawState::AutoRestoreEffects are(drawState); drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget()); if (fCurrVertex > 0) { // setup our sampler state for our text texture/atlas SkASSERT(SkIsAlign4(fCurrVertex)); GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode); GrTexture* currTexture = fStrike->getTexture(); SkASSERT(currTexture); uint32_t textureUniqueID = currTexture->getUniqueID(); if (textureUniqueID != fEffectTextureUniqueID) { fCachedEffect.reset(GrCustomCoordsTextureEffect::Create(currTexture, params)); fEffectTextureUniqueID = textureUniqueID; } // This effect could be stored with one of the cache objects (atlas?) int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex : kGlyphCoordsNoColorAttributeIndex; drawState->addCoverageEffect(fCachedEffect.get(), coordsIdx); SkASSERT(NULL != fStrike); switch (fStrike->getMaskFormat()) { // Color bitmap text case kARGB_GrMaskFormat: SkASSERT(!drawState->hasColorVertexAttribute()); drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); drawState->setColor(0xffffffff); break; // LCD text case kA888_GrMaskFormat: case kA565_GrMaskFormat: { if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || fPaint.numColorStages()) { GrPrintf("LCD Text will not draw correctly.\n"); } SkASSERT(!drawState->hasColorVertexAttribute()); // We don't use the GrPaint's color in this case because it's been premultiplied by // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor int a = SkColorGetA(fSkPaint.getColor()); // paintAlpha drawState->setColor(SkColorSetARGB(a, a, a, a)); // paintColor drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor())); drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); break; } // Grayscale/BW text case kA8_GrMaskFormat: // set back to normal in case we took LCD path previously. drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); //drawState->setColor(fPaint.getColor()); // We're using per-vertex color. SkASSERT(drawState->hasColorVertexAttribute()); drawState->setColor(0xFFFFFFFF); break; default: SkFAIL("Unexepected mask format."); } int nGlyphs = fCurrVertex / 4; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, nGlyphs, 4, 6, &fVertexBounds); fCurrVertex = 0; fVertexBounds.setLargestInverted(); } fDrawTarget->resetVertexSource(); fVertices = NULL; }
bool OsmAnd::AtlasMapRendererDebugStage_OpenGL::renderQuads3D() { const auto gpuAPI = getGPUAPI(); const auto& internalState = getInternalState(); GL_CHECK_PRESENT(glUseProgram); GL_CHECK_PRESENT(glUniformMatrix4fv); GL_CHECK_PRESENT(glUniform1f); GL_CHECK_PRESENT(glUniform2f); GL_CHECK_PRESENT(glUniform3f); GL_CHECK_PRESENT(glDrawElements); gpuAPI->useVAO(_vaoQuad3D); // Activate program glUseProgram(_programQuad3D.id); GL_CHECK_RESULT; // Set projection*view*model matrix: glUniformMatrix4fv(_programQuad3D.vs.param.mProjectionViewModel, 1, GL_FALSE, glm::value_ptr(internalState.mPerspectiveProjectionView)); GL_CHECK_RESULT; for(const auto& primitive : constOf(_quads3D)) { const auto& p0 = std::get<0>(primitive); const auto& p1 = std::get<1>(primitive); const auto& p2 = std::get<2>(primitive); const auto& p3 = std::get<3>(primitive); const auto& color = std::get<4>(primitive); // Set quad color glUniform4f(_programQuad3D.fs.param.color, SkColorGetR(color) / 255.0f, SkColorGetG(color) / 255.0f, SkColorGetB(color) / 255.0f, SkColorGetA(color) / 255.0f); GL_CHECK_RESULT; // Set points glUniform4f(_programQuad3D.vs.param.v0, p0.x, p0.y, p0.z, 1.0f); GL_CHECK_RESULT; glUniform4f(_programQuad3D.vs.param.v1, p1.x, p1.y, p1.z, 1.0f); GL_CHECK_RESULT; glUniform4f(_programQuad3D.vs.param.v2, p2.x, p2.y, p2.z, 1.0f); GL_CHECK_RESULT; glUniform4f(_programQuad3D.vs.param.v3, p3.x, p3.y, p3.z, 1.0f); GL_CHECK_RESULT; // Draw the quad actually glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr); GL_CHECK_RESULT; } // Deactivate program glUseProgram(0); GL_CHECK_RESULT; gpuAPI->unuseVAO(); return true; }
bool OsmAnd::AtlasMapRendererDebugStage_OpenGL::renderLines3D() { const auto gpuAPI = getGPUAPI(); const auto& internalState = getInternalState(); GL_CHECK_PRESENT(glUseProgram); GL_CHECK_PRESENT(glUniformMatrix4fv); GL_CHECK_PRESENT(glUniform1f); GL_CHECK_PRESENT(glUniform2f); GL_CHECK_PRESENT(glUniform3f); GL_CHECK_PRESENT(glDrawElements); gpuAPI->useVAO(_vaoLine3D); // Activate program glUseProgram(_programLine3D.id); GL_CHECK_RESULT; // Set projection*view*model matrix: glUniformMatrix4fv(_programLine3D.vs.param.mProjectionViewModel, 1, GL_FALSE, glm::value_ptr(internalState.mPerspectiveProjectionView)); GL_CHECK_RESULT; for(const auto& primitive : constOf(_lines3D)) { const auto& line = primitive.first; const auto& color = primitive.second; // Set line color glUniform4f(_programLine3D.fs.param.color, SkColorGetR(color) / 255.0f, SkColorGetG(color) / 255.0f, SkColorGetB(color) / 255.0f, SkColorGetA(color) / 255.0f); GL_CHECK_RESULT; // Iterate over pairs of points auto itV0 = line.cbegin(); auto itV1 = itV0 + 1; for(const auto itEnd = line.cend(); itV1 != itEnd; itV0 = itV1, ++itV1) { const auto& v0 = *itV0; const auto& v1 = *itV1; // Set line coordinates glUniform4f(_programLine3D.vs.param.v0, v0.x, v0.y, v0.z, 1.0f); GL_CHECK_RESULT; glUniform4f(_programLine3D.vs.param.v1, v1.x, v1.y, v1.z, 1.0f); GL_CHECK_RESULT; // Draw the line actually glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, nullptr); GL_CHECK_RESULT; } } // Deactivate program glUseProgram(0); GL_CHECK_RESULT; gpuAPI->unuseVAO(); return true; }
bool OsmAnd::AtlasMapRendererDebugStage_OpenGL::renderRects2D() { const auto gpuAPI = getGPUAPI(); const auto& internalState = getInternalState(); GL_CHECK_PRESENT(glUseProgram); GL_CHECK_PRESENT(glUniformMatrix4fv); GL_CHECK_PRESENT(glUniform1f); GL_CHECK_PRESENT(glUniform2f); GL_CHECK_PRESENT(glUniform3f); GL_CHECK_PRESENT(glDrawElements); gpuAPI->useVAO(_vaoRect2D); // Activate program glUseProgram(_programRect2D.id); GL_CHECK_RESULT; // Set projection*view*model matrix: glUniformMatrix4fv(_programRect2D.vs.param.mProjectionViewModel, 1, GL_FALSE, glm::value_ptr(internalState.mOrthographicProjection)); GL_CHECK_RESULT; for(const auto& primitive : constOf(_rects2D)) { const auto& rect = std::get<0>(primitive); const auto& color = std::get<1>(primitive); const auto& angle = std::get<2>(primitive); // Set rectangle coordinates const auto center = rect.center(); glUniform4f(_programRect2D.vs.param.rect, currentState.windowSize.y - center.y, center.x, rect.height(), rect.width()); GL_CHECK_RESULT; // Set rotation angle glUniform1f(_programRect2D.vs.param.angle, angle); GL_CHECK_RESULT; // Set rectangle color glUniform4f(_programRect2D.fs.param.color, SkColorGetR(color) / 255.0f, SkColorGetG(color) / 255.0f, SkColorGetB(color) / 255.0f, SkColorGetA(color) / 255.0f); GL_CHECK_RESULT; // Draw the rectangle actually glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr); GL_CHECK_RESULT; } // Deactivate program glUseProgram(0); GL_CHECK_RESULT; gpuAPI->unuseVAO(); return true; }
// This swizzles SkColor into the same component order as SkPMColor, but does not actually // "pre" multiply the color components. // // This allows us to map directly to Sk4f, and eventually scale down to bytes to output a // SkPMColor from the floats, without having to swizzle each time. // static uint32_t SkSwizzle_Color_to_PMColor(SkColor c) { return SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); }
static void color_to_floats(SkColor c, SkScalar f[4]) { f[0] = SkIntToScalar(SkColorGetA(c)); f[1] = SkIntToScalar(SkColorGetR(c)); f[2] = SkIntToScalar(SkColorGetG(c)); f[3] = SkIntToScalar(SkColorGetB(c)); }