Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: include/effects/SkLightingShader.h

Issue 1245883003: Move LightingShader to effects (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: include/effects/SkLightingShader.h
diff --git a/include/effects/SkLightingShader.h b/include/effects/SkLightingShader.h
new file mode 100644
index 0000000000000000000000000000000000000000..7934345b7ef43c55bb473411c2a1d7af496ed760
--- /dev/null
+++ b/include/effects/SkLightingShader.h
@@ -0,0 +1,134 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkLightingShader_DEFINED
+#define SkLightingShader_DEFINED
+
+#include "SkPoint3.h"
+#include "SkShader.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ SkLightingShader TODOs:
+ support other than clamp mode
+ allow 'diffuse' & 'normal' to be of different dimensions?
+ support different light types
+ support multiple lights
+ enforce normal map is 4 channel
jvanverth1 2015/07/23 17:40:14 use SkImages instead of SkBitmaps
robertphillips 2015/07/28 14:15:45 Done.
+
+ To Test:
+ non-opaque diffuse textures
+ A8 diffuse textures
+ down & upsampled draws
+*/
+
+
+
+/** \class SkLightingShader
+ This subclass of shader applies lighting.
+*/
+class SK_API SkLightingShader : public SkShader {
+public:
+ struct Light {
+ SkVector3 fDirection; // direction towards the light (+Z is out of the screen)
+ SkColor fColor; // linear (unpremul) color
+ };
+
+ /** Create a new lighting shader that use the provided normal map, light
+ and ambient color to light the diffuse bitmap.
+ @param diffuse the diffuse bitmap
+ @param normal the normal map
+ @param light the light applied to the normal map
+ @param ambient the linear (unpremul) ambient light color
+ */
+ SkLightingShader(const SkBitmap& diffuse, const SkBitmap& normal, const Light& light,
+ const SkColor ambient)
+ : fDiffuseMap(diffuse)
+ , fNormalMap(normal)
+ , fLight(light)
+ , fAmbientColor(ambient) {
+ if (!fLight.fDirection.normalize()) {
+ fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f);
+ }
+ SkColorSetA(fLight.fColor, 0xFF);
+ SkColorSetA(fAmbientColor, 0xFF);
+ }
+
+ bool isOpaque() const override;
+
+ void setLight(const Light& light) {
+ fLight = light;
+ if (!fLight.fDirection.normalize()) {
+ fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f);
+ }
+ SkColorSetA(fLight.fColor, 0xFF);
+ SkColorSetA(fAmbientColor, 0xFF);
+ }
+
+ bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& viewM,
+ const SkMatrix* localMatrix, GrColor* color,
+ GrProcessorDataManager*, GrFragmentProcessor** fp) const override;
+
+ size_t contextSize() const override;
+
+ class LightingShaderContext : public SkShader::Context {
+ public:
+ // The context takes ownership of the states. It will call their destructors
+ // but will NOT free the memory.
+ LightingShaderContext(const SkLightingShader&, const ContextRec&,
+ SkBitmapProcState* diffuseState, SkBitmapProcState* normalState);
+ ~LightingShaderContext() override;
+
+ void shadeSpan(int x, int y, SkPMColor[], int count) override;
+
+ uint32_t getFlags() const override { return fFlags; }
+
+ private:
+ SkBitmapProcState* fDiffuseState;
+ SkBitmapProcState* fNormalState;
+ uint32_t fFlags;
+
+ typedef SkShader::Context INHERITED;
+ };
+
+ SK_TO_STRING_OVERRIDE()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(LightingShader)
+
+protected:
+ void flatten(SkWriteBuffer&) const override;
+ Context* onCreateContext(const ContextRec&, void*) const override;
+
+private:
+ SkBitmap fDiffuseMap;
+ SkBitmap fNormalMap;
+ Light fLight;
+ SkColor fAmbientColor; // linear (unpremul) color
+
+ typedef SkShader INHERITED;
+};
+
+// TODO: it would be nice to be able to call this from SkShader but this
+// would need to reside in core.
+#if 0
+// Commonly used allocator. It currently is only used to allocate up to 3 objects. The total
+// bytes requested is calculated using one of our large shaders, its context size plus the size of
+// an Sk3DBlitter in SkDraw.cpp
+// Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not
+// yet found a situation where the size below isn't big enough.
+typedef SkSmallAllocator<3, 1024> SkTBlitterAllocator;
+
+// If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive
+// the SkShader.
+SkShader* SkCreateLightingShader(const SkBitmap& diffuse, const SkBitmap& normal,
+ const SkLightingShader::Light& light, const SkColor ambient,
+ SkTBlitterAllocator* alloc);
+#endif
+
+#endif

Powered by Google App Engine
This is Rietveld 408576698