Functions to rasterize textures to bitmaps

metadata
Wenzel Jakob 2013-09-05 15:05:03 +02:00
parent d582d8578d
commit 11452f7c86
5 changed files with 82 additions and 4 deletions

View File

@ -75,6 +75,8 @@ public:
Shader *createShader(Renderer *renderer) const;
ref<Bitmap> getBitmap(const Vector2i &resolutionHint) const;
void serialize(Stream *stream, InstanceManager *manager) const;
MTS_DECLARE_CLASS()
@ -128,6 +130,8 @@ public:
Shader *createShader(Renderer *renderer) const;
ref<Bitmap> getBitmap(const Vector2i &resolutionHint) const;
void serialize(Stream *stream, InstanceManager *manager) const;
MTS_DECLARE_CLASS()
@ -185,6 +189,8 @@ public:
Shader *createShader(Renderer *renderer) const;
ref<Bitmap> getBitmap(const Vector2i &resolutionHint) const;
void serialize(Stream *stream, InstanceManager *manager) const;
MTS_DECLARE_CLASS()
@ -242,6 +248,8 @@ public:
Shader *createShader(Renderer *renderer) const;
ref<Bitmap> getBitmap(const Vector2i &resolutionHint) const;
void serialize(Stream *stream, InstanceManager *manager) const;
MTS_DECLARE_CLASS()
@ -302,6 +310,8 @@ public:
void serialize(Stream *stream, InstanceManager *manager) const;
ref<Bitmap> getBitmap(const Vector2i &resolutionHint) const;
MTS_DECLARE_CLASS()
protected:
ref<const Texture> m_a, m_b;

View File

@ -74,8 +74,17 @@ public:
/// Serialize to a binary data stream
virtual void serialize(Stream *stream, InstanceManager *manager) const;
/// Return the underlying bitmap representation (if any)
virtual ref<Bitmap> getBitmap() const;
/**
* \brief Return a bitmap representation of the texture
*
* When the class implementing this interface is a bitmap-backed texture,
* this function directly returns the underlying bitmap. When it is procedural,
* a bitmap version must first be generated. In this case, the parameter
* \ref resolutionHint is used to control the target resolution. The default
* value <tt>-1, -1</tt> allows the implementation to choose a suitable
* resolution by itself.
*/
virtual ref<Bitmap> getBitmap(const Vector2i &resolutionHint = Vector2i(-1, -1)) const;
MTS_DECLARE_CLASS()
protected:
@ -109,6 +118,18 @@ public:
virtual Spectrum eval(const Point2 &uv, const Vector2 &d0,
const Vector2 &d1) const = 0;
/**
* \brief Return a bitmap representation of the texture
*
* When the class implementing this interface is a bitmap-backed texture,
* this function directly returns the underlying bitmap. When it is procedural,
* a bitmap version must first be generated. In this case, the parameter
* \ref resolutionHint is used to control the target resolution. The default
* value <tt>-1, -1</tt> allows the implementation to choose a suitable
* resolution by itself.
*/
virtual ref<Bitmap> getBitmap(const Vector2i &resolutionHint = Vector2i(-1, -1)) const;
MTS_DECLARE_CLASS()
protected:
Texture2D(const Properties &props);

View File

@ -20,6 +20,7 @@
MTS_NAMESPACE_BEGIN
ConstantSpectrumTexture::ConstantSpectrumTexture(Stream *stream, InstanceManager *manager)
: Texture(stream, manager) {
m_value = Spectrum(stream);
@ -31,6 +32,12 @@ void ConstantSpectrumTexture::serialize(Stream *stream, InstanceManager *manager
m_value.serialize(stream);
}
ref<Bitmap> ConstantSpectrumTexture::getBitmap(const Vector2i &resolutionHint) const {
ref<Bitmap> result = new Bitmap(Bitmap::ESpectrum, Bitmap::EFloat, Vector2i(1, 1));
*((Spectrum *) result->getFloatData()) = m_value;
return result;
}
ConstantFloatTexture::ConstantFloatTexture(Stream *stream, InstanceManager *manager)
: Texture(stream, manager) {
m_value = stream->readFloat();
@ -41,6 +48,12 @@ void ConstantFloatTexture::serialize(Stream *stream, InstanceManager *manager) c
stream->writeFloat(m_value);
}
ref<Bitmap> ConstantFloatTexture::getBitmap(const Vector2i &resolutionHint) const {
ref<Bitmap> result = new Bitmap(Bitmap::ELuminance, Bitmap::EFloat, Vector2i(1, 1));
*result->getFloatData() = m_value;
return result;
}
SpectrumProductTexture::SpectrumProductTexture(Stream *stream, InstanceManager *manager)
: Texture(stream, manager) {
m_a = static_cast<Texture *>(manager->getInstance(stream));
@ -53,6 +66,12 @@ void SpectrumProductTexture::serialize(Stream *stream, InstanceManager *manager)
manager->serialize(stream, m_b.get());
}
ref<Bitmap> SpectrumProductTexture::getBitmap(const Vector2i &resolutionHint) const {
ref<Bitmap> bitmap1 = m_a->getBitmap(resolutionHint);
ref<Bitmap> bitmap2 = m_b->getBitmap(resolutionHint);
return Bitmap::arithmeticOperation(Bitmap::EMultiplication, bitmap1.get(), bitmap2.get());
}
SpectrumAdditionTexture::SpectrumAdditionTexture(Stream *stream, InstanceManager *manager)
: Texture(stream, manager) {
m_a = static_cast<Texture *>(manager->getInstance(stream));
@ -65,6 +84,12 @@ void SpectrumAdditionTexture::serialize(Stream *stream, InstanceManager *manager
manager->serialize(stream, m_b.get());
}
ref<Bitmap> SpectrumAdditionTexture::getBitmap(const Vector2i &resolutionHint) const {
ref<Bitmap> bitmap1 = m_a->getBitmap(resolutionHint);
ref<Bitmap> bitmap2 = m_b->getBitmap(resolutionHint);
return Bitmap::arithmeticOperation(Bitmap::EAddition, bitmap1.get(), bitmap2.get());
}
SpectrumSubtractionTexture::SpectrumSubtractionTexture(Stream *stream, InstanceManager *manager)
: Texture(stream, manager) {
m_a = static_cast<Texture *>(manager->getInstance(stream));
@ -77,6 +102,12 @@ void SpectrumSubtractionTexture::serialize(Stream *stream, InstanceManager *mana
manager->serialize(stream, m_b.get());
}
ref<Bitmap> SpectrumSubtractionTexture::getBitmap(const Vector2i &resolutionHint) const {
ref<Bitmap> bitmap1 = m_a->getBitmap(resolutionHint);
ref<Bitmap> bitmap2 = m_b->getBitmap(resolutionHint);
return Bitmap::arithmeticOperation(Bitmap::ESubtraction, bitmap1.get(), bitmap2.get());
}
class ConstantSpectrumTextureShader : public Shader {
public:
ConstantSpectrumTextureShader(Renderer *renderer, const Spectrum &value)

View File

@ -47,7 +47,7 @@ Spectrum Texture::getMinimum() const { NotImplementedError("getMinimum"); }
Spectrum Texture::getMaximum() const { NotImplementedError("getMaximum"); }
bool Texture::isConstant() const { NotImplementedError("isConstant"); }
bool Texture::usesRayDifferentials() const { NotImplementedError("usesRayDifferentials"); }
ref<Bitmap> Texture::getBitmap() const { return NULL; }
ref<Bitmap> Texture::getBitmap(const Vector2i &) const { NotImplementedError("getBitmap"); }
ref<Texture> Texture::expand() {
return this;
@ -100,6 +100,22 @@ Spectrum Texture2D::eval(const Intersection &its, bool filter) const {
return eval(uv);
}
}
ref<Bitmap> Texture2D::getBitmap(const Vector2i &resolutionHint) const {
Vector2i res(resolutionHint);
if (res.x <= 0 || res.y <= 0)
res = Vector2i(32);
Float invX = 1.0f / res.x, invY = 1.0f / res.y;
ref<Bitmap> bitmap = new Bitmap(Bitmap::ESpectrum, Bitmap::EFloat, res);
Spectrum *target = (Spectrum *) bitmap->getFloatData();
for (int y=0; y<res.y; ++y)
for (int x=0; x<res.x; ++x)
*target++ = eval(Point2((x + 0.5f) * invX, (y + 0.5f) * invY));
return bitmap;
}
MTS_IMPLEMENT_CLASS(Texture, true, ConfigurableObject)
MTS_IMPLEMENT_CLASS(Texture2D, true, Texture)
MTS_NAMESPACE_END

View File

@ -428,7 +428,7 @@ public:
return result;
}
ref<Bitmap> getBitmap() const {
ref<Bitmap> getBitmap(const Vector2i &/* unused */) {
return m_mipmap1.get() ? m_mipmap1->toBitmap() : m_mipmap3->toBitmap();
}