Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 | |
| 2 /* | |
| 3 * Copyright 2015 Google Inc. | |
| 4 * | |
| 5 * Use of this source code is governed by a BSD-style license that can be | |
| 6 * found in the LICENSE file. | |
| 7 */ | |
| 8 | |
| 9 | |
| 10 #ifndef SkLightingShader_DEFINED | |
| 11 #define SkLightingShader_DEFINED | |
| 12 | |
| 13 #include "SkPoint3.h" | |
| 14 #include "SkShader.h" | |
| 15 | |
| 16 //////////////////////////////////////////////////////////////////////////////// /////////// | |
| 17 | |
| 18 /* | |
| 19 SkLightingShader TODOs: | |
| 20 support other than clamp mode | |
| 21 allow 'diffuse' & 'normal' to be of different dimensions? | |
| 22 support different light types | |
| 23 support multiple lights | |
| 24 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.
| |
| 25 | |
| 26 To Test: | |
| 27 non-opaque diffuse textures | |
| 28 A8 diffuse textures | |
| 29 down & upsampled draws | |
| 30 */ | |
| 31 | |
| 32 | |
| 33 | |
| 34 /** \class SkLightingShader | |
| 35 This subclass of shader applies lighting. | |
| 36 */ | |
| 37 class SK_API SkLightingShader : public SkShader { | |
| 38 public: | |
| 39 struct Light { | |
| 40 SkVector3 fDirection; // direction towards the light (+Z is out of the screen) | |
| 41 SkColor fColor; // linear (unpremul) color | |
| 42 }; | |
| 43 | |
| 44 /** Create a new lighting shader that use the provided normal map, light | |
| 45 and ambient color to light the diffuse bitmap. | |
| 46 @param diffuse the diffuse bitmap | |
| 47 @param normal the normal map | |
| 48 @param light the light applied to the normal map | |
| 49 @param ambient the linear (unpremul) ambient light color | |
| 50 */ | |
| 51 SkLightingShader(const SkBitmap& diffuse, const SkBitmap& normal, const Ligh t& light, | |
| 52 const SkColor ambient) | |
| 53 : fDiffuseMap(diffuse) | |
| 54 , fNormalMap(normal) | |
| 55 , fLight(light) | |
| 56 , fAmbientColor(ambient) { | |
| 57 if (!fLight.fDirection.normalize()) { | |
| 58 fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f); | |
| 59 } | |
| 60 SkColorSetA(fLight.fColor, 0xFF); | |
| 61 SkColorSetA(fAmbientColor, 0xFF); | |
| 62 } | |
| 63 | |
| 64 bool isOpaque() const override; | |
| 65 | |
| 66 void setLight(const Light& light) { | |
| 67 fLight = light; | |
| 68 if (!fLight.fDirection.normalize()) { | |
| 69 fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f); | |
| 70 } | |
| 71 SkColorSetA(fLight.fColor, 0xFF); | |
| 72 SkColorSetA(fAmbientColor, 0xFF); | |
| 73 } | |
| 74 | |
| 75 bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& v iewM, | |
| 76 const SkMatrix* localMatrix, GrColor* color, | |
| 77 GrProcessorDataManager*, GrFragmentProcessor** fp) const override; | |
| 78 | |
| 79 size_t contextSize() const override; | |
| 80 | |
| 81 class LightingShaderContext : public SkShader::Context { | |
| 82 public: | |
| 83 // The context takes ownership of the states. It will call their destruc tors | |
| 84 // but will NOT free the memory. | |
| 85 LightingShaderContext(const SkLightingShader&, const ContextRec&, | |
| 86 SkBitmapProcState* diffuseState, SkBitmapProcState * normalState); | |
| 87 ~LightingShaderContext() override; | |
| 88 | |
| 89 void shadeSpan(int x, int y, SkPMColor[], int count) override; | |
| 90 | |
| 91 uint32_t getFlags() const override { return fFlags; } | |
| 92 | |
| 93 private: | |
| 94 SkBitmapProcState* fDiffuseState; | |
| 95 SkBitmapProcState* fNormalState; | |
| 96 uint32_t fFlags; | |
| 97 | |
| 98 typedef SkShader::Context INHERITED; | |
| 99 }; | |
| 100 | |
| 101 SK_TO_STRING_OVERRIDE() | |
| 102 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(LightingShader) | |
| 103 | |
| 104 protected: | |
| 105 void flatten(SkWriteBuffer&) const override; | |
| 106 Context* onCreateContext(const ContextRec&, void*) const override; | |
| 107 | |
| 108 private: | |
| 109 SkBitmap fDiffuseMap; | |
| 110 SkBitmap fNormalMap; | |
| 111 Light fLight; | |
| 112 SkColor fAmbientColor; // linear (unpremul) color | |
| 113 | |
| 114 typedef SkShader INHERITED; | |
| 115 }; | |
| 116 | |
| 117 // TODO: it would be nice to be able to call this from SkShader but this | |
| 118 // would need to reside in core. | |
| 119 #if 0 | |
| 120 // Commonly used allocator. It currently is only used to allocate up to 3 object s. The total | |
| 121 // bytes requested is calculated using one of our large shaders, its context siz e plus the size of | |
| 122 // an Sk3DBlitter in SkDraw.cpp | |
| 123 // Note that some contexts may contain other contexts (e.g. for compose shaders) , but we've not | |
| 124 // yet found a situation where the size below isn't big enough. | |
| 125 typedef SkSmallAllocator<3, 1024> SkTBlitterAllocator; | |
| 126 | |
| 127 // If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive | |
| 128 // the SkShader. | |
| 129 SkShader* SkCreateLightingShader(const SkBitmap& diffuse, const SkBitmap& normal , | |
| 130 const SkLightingShader::Light& light, const SkC olor ambient, | |
| 131 SkTBlitterAllocator* alloc); | |
| 132 #endif | |
| 133 | |
| 134 #endif | |
| OLD | NEW |