significant rehaul of the dielectric.cpp implementation. Fixed some OpenGL errors on MacOS X

metadata
Wenzel Jakob 2011-07-01 18:54:46 +02:00
parent cb3dcdb377
commit 7c5f924fad
6 changed files with 214 additions and 116 deletions

View File

@ -17,17 +17,24 @@
*/ */
#include <mitsuba/render/bsdf.h> #include <mitsuba/render/bsdf.h>
#include <mitsuba/render/sampler.h> #include <mitsuba/render/consttexture.h>
MTS_NAMESPACE_BEGIN MTS_NAMESPACE_BEGIN
const bool importanceSampleComponents = true; /*! \plugin{dielectric}{Ideal dielectric/glass material}
*
/** * \parameters{
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the reflectance component\default{1.0}}
* \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the transmittance component\default{1.0}}
* }
*
* Models an interface between two materials with non-matched indices of refraction. * Models an interface between two materials with non-matched indices of refraction.
* The microscopic surface structure is assumed to be perfectly flat, resulting * The microscopic surface structure is assumed to be perfectly flat, resulting
* in a BSDF equal to a Dirac delta function. * in a BSDF equal to a Dirac delta function.
*
* The default settings are set to a borosilicate glass BK7/air interface. * The default settings are set to a borosilicate glass BK7/air interface.
*/ */
class Dielectric : public BSDF { class Dielectric : public BSDF {
@ -38,10 +45,11 @@ public:
m_intIOR = props.getFloat("intIOR", 1.5046f); m_intIOR = props.getFloat("intIOR", 1.5046f);
/* Specifies the external index of refraction at the interface */ /* Specifies the external index of refraction at the interface */
m_extIOR = props.getFloat("extIOR", 1); m_extIOR = props.getFloat("extIOR", 1);
/* Reflectance modulation term */
m_reflectance = props.getSpectrum("specularReflectance", Spectrum(1.0f)); m_specularReflectance = new ConstantSpectrumTexture(
/* Transmittance modulation term */ props.getSpectrum("specularReflectance", Spectrum(1.0f)));
m_transmittance = props.getSpectrum("specularTransmittance", Spectrum(1.0f)); m_specularTransmittance = new ConstantSpectrumTexture(
props.getSpectrum("specularTransmittance", Spectrum(1.0f)));
m_componentCount = 2; m_componentCount = 2;
m_type = new unsigned int[m_componentCount]; m_type = new unsigned int[m_componentCount];
@ -55,8 +63,8 @@ public:
: BSDF(stream, manager) { : BSDF(stream, manager) {
m_intIOR = stream->readFloat(); m_intIOR = stream->readFloat();
m_extIOR = stream->readFloat(); m_extIOR = stream->readFloat();
m_transmittance = Spectrum(stream); m_specularReflectance = static_cast<Texture *>(manager->getInstance(stream));
m_reflectance = Spectrum(stream); m_specularTransmittance = static_cast<Texture *>(manager->getInstance(stream));
m_componentCount = 2; m_componentCount = 2;
m_type = new unsigned int[m_componentCount]; m_type = new unsigned int[m_componentCount];
@ -75,8 +83,8 @@ public:
stream->writeFloat(m_intIOR); stream->writeFloat(m_intIOR);
stream->writeFloat(m_extIOR); stream->writeFloat(m_extIOR);
m_transmittance.serialize(stream); manager->serialize(stream, m_specularReflectance.get());
m_reflectance.serialize(stream); manager->serialize(stream, m_specularTransmittance.get());
} }
Spectrum getDiffuseReflectance(const Intersection &its) const { Spectrum getDiffuseReflectance(const Intersection &its) const {
@ -91,101 +99,187 @@ public:
return 0.0f; return 0.0f;
} }
inline void reflect(const Vector &wo, Vector &wi) const { /// Reflection in local coordinates
wi = Vector(-wo.x, -wo.y, wo.z); inline Vector reflect(const Vector &wi) const {
return Vector(-wi.x, -wi.y, wi.z);
} }
Float refract(Float intIOR, Float extIOR, /// Refraction in local coordinates
const Vector &wi, Vector &wo, ETransportQuantity quantity) const { inline Vector refract(const Vector &wi, Float eta, Float cosThetaT) const {
Float cosThetaI = Frame::cosTheta(wi), return Vector(-eta*wi.x, -eta*wi.y, cosThetaT);
etaI = extIOR, etaT = intIOR;
bool entering = cosThetaI > 0.0f;
if (!entering)
std::swap(etaT, etaI);
Float eta = etaI / etaT;
/* Using Snell's law, calculate the squared sine of the
angle between the normal and the transmitted ray */
Float sinThetaTSqr = eta*eta * Frame::sinTheta2(wi);
if (sinThetaTSqr > 1.0f) /* Total internal reflection! */
return 0.0f;
Float cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
if (entering)
cosThetaT = -cosThetaT;
/* With cos(N, transmittedRay) avilable, calculating the
transmission direction is straightforward */
wo = Vector(-eta*wi.x, -eta*wi.y, cosThetaT);
/* Finally compute transmission coefficient. When transporting
radiance, account for the solid angle change at boundaries
with different indices of refraction. */
if (quantity == ERadiance)
return (etaI*etaI) / (etaT*etaT);
else
return 1.0f;
} }
inline Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const { Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const {
Float pdf = 0;
Spectrum spec = Dielectric::sample(bRec, pdf, sample);
if (pdf == 0 || spec.isZero())
return Spectrum(0.0f);
return spec/pdf;
}
inline Spectrum sample(BSDFQueryRecord &bRec, Float &pdf, const Point2 &sample) const {
bool sampleReflection = (bRec.typeMask & EDeltaReflection) bool sampleReflection = (bRec.typeMask & EDeltaReflection)
&& (bRec.component == -1 || bRec.component == 0); && (bRec.component == -1 || bRec.component == 0);
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission) bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
&& (bRec.component == -1 || bRec.component == 1); && (bRec.component == -1 || bRec.component == 1);
if (!sampleTransmission && !sampleReflection)
return Spectrum(0.0f);
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR); Float cosThetaI = Frame::cosTheta(bRec.wi),
etaI = m_extIOR,
etaT = m_intIOR;
bool entering = cosThetaI > 0.0f;
/* Determine the respective indices of refraction */
if (!entering)
std::swap(etaI, etaT);
/* Using Snell's law, calculate the squared sine of the
angle between the normal and the transmitted ray */
Float eta = etaI / etaT,
sinThetaTSqr = eta*eta * Frame::sinTheta2(bRec.wi);
Float Fr, cosThetaT = 0;
if (sinThetaTSqr >= 1.0f) {
/* Total internal reflection */
Fr = 1.0f;
} else {
cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
/* Compute the Fresnel refletance */
Fr = fresnelDielectric(std::abs(cosThetaI),
cosThetaT, etaI, etaT);
if (entering)
cosThetaT = -cosThetaT;
}
/* Calculate the refracted/reflected vectors+coefficients */ /* Calculate the refracted/reflected vectors+coefficients */
if (sampleTransmission && sampleReflection) { if (sampleTransmission && sampleReflection) {
/* Importance sample according to the reflectance/transmittance */ /* Importance sample according to the reflectance/transmittance */
if (sample.x < (importanceSampleComponents ? fr : 0.5f)) { if (sample.x <= Fr) {
reflect(bRec.wi, bRec.wo);
bRec.sampledComponent = 0; bRec.sampledComponent = 0;
bRec.sampledType = EDeltaReflection; bRec.sampledType = EDeltaReflection;
pdf = (importanceSampleComponents ? fr : 0.5f) * std::abs(Frame::cosTheta(bRec.wo)); bRec.wo = reflect(bRec.wi);
/* Cancel out the cosine term */
return m_reflectance * fr; return m_specularReflectance->getValue(bRec.its)
/ std::abs(Frame::cosTheta(bRec.wo));
} else { } else {
pdf = importanceSampleComponents ? (1-fr) : 0.5f;
bRec.sampledComponent = 1; bRec.sampledComponent = 1;
bRec.sampledType = EDeltaTransmission; bRec.sampledType = EDeltaTransmission;
Float result = refract(m_intIOR, m_extIOR, bRec.wi, bRec.wo, bRec.quantity); /* Given cos(N, transmittedRay), compute the
if (result == 0) transmitted direction */
return Spectrum(0.0f); bRec.wo = refract(bRec.wi, eta, cosThetaT);
pdf *= std::abs(Frame::cosTheta(bRec.wo));
return m_transmittance * result * (1-fr); /* When transporting radiance, account for the solid angle
change at boundaries with different indices of refraction. */
return m_specularTransmittance->getValue(bRec.its)
* (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1)
/ std::abs(Frame::cosTheta(bRec.wo));
} }
} else if (sampleReflection) { } else if (sampleReflection) {
reflect(bRec.wi, bRec.wo);
bRec.sampledComponent = 0; bRec.sampledComponent = 0;
bRec.sampledType = EDeltaReflection; bRec.sampledType = EDeltaReflection;
pdf = std::abs(Frame::cosTheta(bRec.wo)); bRec.wo = reflect(bRec.wi);
return m_reflectance * fr; return m_specularReflectance->getValue(bRec.its) * (Fr
} else if (sampleTransmission) { / std::abs(Frame::cosTheta(bRec.wo)));
} else {
bRec.sampledComponent = 1; bRec.sampledComponent = 1;
bRec.sampledType = EDeltaTransmission; bRec.sampledType = EDeltaTransmission;
Float result = refract(m_intIOR, m_extIOR, bRec.wi, bRec.wo, bRec.quantity); if (Fr == 1.0f) /* Total internal reflection */
pdf = std::abs(Frame::cosTheta(bRec.wo));
if (result == 0)
return Spectrum(0.0f); return Spectrum(0.0f);
return m_transmittance * result * (1-fr); bRec.wo = refract(bRec.wi, eta, cosThetaT);
/* When transporting radiance, account for the solid angle
change at boundaries with different indices of refraction. */
return m_specularTransmittance->getValue(bRec.its)
* ((1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1))
/ std::abs(Frame::cosTheta(bRec.wo));
}
}
Spectrum sample(BSDFQueryRecord &bRec, Float &pdf, const Point2 &sample) const {
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
&& (bRec.component == -1 || bRec.component == 0);
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
&& (bRec.component == -1 || bRec.component == 1);
if (!sampleTransmission && !sampleReflection)
return Spectrum(0.0f);
Float cosThetaI = Frame::cosTheta(bRec.wi),
etaI = m_extIOR,
etaT = m_intIOR;
bool entering = cosThetaI > 0.0f;
/* Determine the respective indices of refraction */
if (!entering)
std::swap(etaI, etaT);
/* Using Snell's law, calculate the squared sine of the
angle between the normal and the transmitted ray */
Float eta = etaI / etaT,
sinThetaTSqr = eta*eta * Frame::sinTheta2(bRec.wi);
Float Fr, cosThetaT = 0;
if (sinThetaTSqr >= 1.0f) {
/* Total internal reflection */
Fr = 1.0f;
} else {
cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
/* Compute the Fresnel refletance */
Fr = fresnelDielectric(std::abs(cosThetaI),
cosThetaT, etaI, etaT);
if (entering)
cosThetaT = -cosThetaT;
}
/* Calculate the refracted/reflected vectors+coefficients */
if (sampleTransmission && sampleReflection) {
/* Importance sample according to the reflectance/transmittance */
if (sample.x <= Fr) {
bRec.sampledComponent = 0;
bRec.sampledType = EDeltaReflection;
bRec.wo = reflect(bRec.wi);
pdf = Fr * std::abs(Frame::cosTheta(bRec.wo));
return m_specularReflectance->getValue(bRec.its) * Fr;
} else {
bRec.sampledComponent = 1;
bRec.sampledType = EDeltaTransmission;
/* Given cos(N, transmittedRay), compute the
transmitted direction */
bRec.wo = refract(bRec.wi, eta, cosThetaT);
pdf = (1-Fr) * std::abs(Frame::cosTheta(bRec.wo));
/* When transporting radiance, account for the solid angle
change at boundaries with different indices of refraction. */
return m_specularTransmittance->getValue(bRec.its)
* (1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1);
}
} else if (sampleReflection) {
bRec.sampledComponent = 0;
bRec.sampledType = EDeltaReflection;
bRec.wo = reflect(bRec.wi);
pdf = std::abs(Frame::cosTheta(bRec.wo));
return m_specularReflectance->getValue(bRec.its) * Fr;
} else {
bRec.sampledComponent = 1;
bRec.sampledType = EDeltaTransmission;
if (Fr == 1.0f) /* Total internal reflection */
return Spectrum(0.0f);
bRec.wo = refract(bRec.wi, eta, cosThetaT);
pdf = std::abs(Frame::cosTheta(bRec.wo));
/* When transporting radiance, account for the solid angle
change at boundaries with different indices of refraction. */
return m_specularTransmittance->getValue(bRec.its)
* ((1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1));
} }
return Spectrum(0.0f);
} }
Float pdfDelta(const BSDFQueryRecord &bRec) const { Float pdfDelta(const BSDFQueryRecord &bRec) const {
@ -197,12 +291,8 @@ public:
Float result = 0.0f; Float result = 0.0f;
if (sampleTransmission && sampleReflection) { if (sampleTransmission && sampleReflection) {
if (!importanceSampleComponents) { Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
result = 0.5f; result = reflection ? fr : (1-fr);
} else {
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
result = reflection ? fr : (1-fr);
}
} else if (sampleReflection) { } else if (sampleReflection) {
result = reflection ? 1.0f : 0.0f; result = reflection ? 1.0f : 0.0f;
} else if (sampleTransmission) { } else if (sampleTransmission) {
@ -225,7 +315,7 @@ public:
return Spectrum(0.0f); return Spectrum(0.0f);
if (reflection) { if (reflection) {
return m_reflectance * fr; return m_specularReflectance->getValue(bRec.its) * fr;
} else { } else {
Float etaI = m_extIOR, etaT = m_intIOR; Float etaI = m_extIOR, etaT = m_intIOR;
bool entering = Frame::cosTheta(bRec.wi) > 0.0f; bool entering = Frame::cosTheta(bRec.wi) > 0.0f;
@ -235,7 +325,7 @@ public:
Float factor = (bRec.quantity == ERadiance) Float factor = (bRec.quantity == ERadiance)
? (etaI*etaI) / (etaT*etaT) : 1.0f; ? (etaI*etaI) / (etaT*etaT) : 1.0f;
return m_transmittance * factor * (1 - fr); return m_specularTransmittance->getValue(bRec.its) * factor * (1 - fr);
} }
} }
@ -245,8 +335,8 @@ public:
oss << "Dielectric[" << endl oss << "Dielectric[" << endl
<< " intIOR = " << m_intIOR << "," << endl << " intIOR = " << m_intIOR << "," << endl
<< " extIOR = " << m_extIOR << "," << endl << " extIOR = " << m_extIOR << "," << endl
<< " reflectance = " << m_reflectance.toString() << "," << endl << " specularReflectance = " << indent(m_specularReflectance->toString()) << "," << endl
<< " transmittance = " << m_transmittance.toString() << endl << " specularTransmittance = " << indent(m_specularTransmittance->toString()) << endl
<< "]"; << "]";
return oss.str(); return oss.str();
} }
@ -254,8 +344,8 @@ public:
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
private: private:
Float m_intIOR, m_extIOR; Float m_intIOR, m_extIOR;
Spectrum m_reflectance; ref<Texture> m_specularTransmittance;
Spectrum m_transmittance; ref<Texture> m_specularReflectance;
}; };

View File

@ -33,14 +33,14 @@ MTS_NAMESPACE_BEGIN
* Gaussian random surfaces. This is the default choice. * Gaussian random surfaces. This is the default choice.
* \item \code{phong}: Classical $\cos^p\theta$ distribution. * \item \code{phong}: Classical $\cos^p\theta$ distribution.
* The Phong exponent $p$ is obtained using a transformation that * The Phong exponent $p$ is obtained using a transformation that
* produces roughness similar to a Beckmann distribution with the same * produces roughness similar to a Beckmann distribution of the same
* parameter. Note that due to the underlying microfacet theory, * parameter. Note that due to the underlying microfacet theory,
* the use of this distribution here leads to more realistic * the use of this distribution here leads to more realistic
* behavior than the separately available \pluginref{phong} plugin. * behavior than the separately available \pluginref{phong} plugin.
* \item \code{ggx}: New distribution proposed by * \item \code{ggx}: New distribution proposed by
* Walter et al. meant to better handle the long * Walter et al. meant to better handle the long
* tails observed in transmission measurements through * tails observed in transmission measurements through
* ground glass. * ground glass.
* \end{enumerate} * \end{enumerate}
* Default: \code{beckmann} * Default: \code{beckmann}
* } * }
@ -51,11 +51,11 @@ MTS_NAMESPACE_BEGIN
* \default{0.1} * \default{0.1}
* } * }
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}} * \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1}} * \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional * \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the reflectance component\default{1}} * factor used to modulate the reflectance component\default{1.0}}
* \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional * \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the transmittance component\default{0.9}} * factor used to modulate the transmittance component\default{1.0}}
* } * }
* *
* This plugin implements a realistic microfacet scattering model for rendering * This plugin implements a realistic microfacet scattering model for rendering
@ -66,18 +66,14 @@ MTS_NAMESPACE_BEGIN
* these facets, it is possible to reproduce the off-specular reflections * these facets, it is possible to reproduce the off-specular reflections
* peaks observed in measurements of real-world materials. * peaks observed in measurements of real-world materials.
* *
* This plugin is essentially the ``roughened'' equivalent of the * This plugin is essentially the ``roughened'' equivalent of the plugin
* plugin \pluginref{dielectric}. The model supports several types of * \pluginref{dielectric}. Its implementation is based on the paper
* microfacet distributions and a texturable roughness. * ``Microfacet Models for Refraction through Rough Surfaces''
* The default settings are set to a borosilicate glass BK7/air interface * \cite{Walter07Microfacet}. The model supports several types of microfacet
* with a light amount of rougness modeled by a Beckmann distribution. * distributions and a texturable roughness. The default settings are set
* * to a borosilicate glass BK7/air interface with a light amount of rougness
* The implementation is based on the paper ``Microfacet Models for Refraction * modeled using a Beckmann distribution.
* through Rough Surfaces'' \cite{Walter07Microfacet}. It furthermore uses an
* improved sampling technique presented in \cite{Zhao11Building} when given
* access to an arbitrarily long stream of random numbers.
*/ */
class RoughGlass : public BSDF { class RoughGlass : public BSDF {
public: public:
//// Microfacet distribution types supported by the model //// Microfacet distribution types supported by the model
@ -95,7 +91,7 @@ public:
m_specularReflectance = new ConstantSpectrumTexture( m_specularReflectance = new ConstantSpectrumTexture(
props.getSpectrum("specularReflectance", Spectrum(1.0f))); props.getSpectrum("specularReflectance", Spectrum(1.0f)));
m_specularTransmittance = new ConstantSpectrumTexture( m_specularTransmittance = new ConstantSpectrumTexture(
props.getSpectrum("specularTransmittance", Spectrum(0.9f))); props.getSpectrum("specularTransmittance", Spectrum(1.9f)));
Float alpha; Float alpha;
if (props.hasProperty("alphaB")) { if (props.hasProperty("alphaB")) {
@ -229,13 +225,13 @@ public:
case EGGX: { case EGGX: {
/* Empirical GGX distribution function for rough surfaces */ /* Empirical GGX distribution function for rough surfaces */
const Float tanTheta = Frame::tanTheta(m); const Float tanTheta = Frame::tanTheta(m),
const Float cosTheta = Frame::cosTheta(m); cosTheta = Frame::cosTheta(m);
const Float root = alpha / (cosTheta*cosTheta * const Float root = alpha / (cosTheta*cosTheta *
(alpha*alpha + tanTheta*tanTheta)); (alpha*alpha + tanTheta*tanTheta));
result = INV_PI * (root*root); result = INV_PI * (root * root);
} }
break; break;

View File

@ -705,12 +705,12 @@ Float fresnel(Float cosThetaI, Float etaExt, Float etaInt) {
Float etaI = etaExt, etaT = etaInt; Float etaI = etaExt, etaT = etaInt;
/* Swap the indices of refraction if the interaction starts /* Swap the indices of refraction if the interaction starts
at the inside of the object */ at the inside of the object */
if (cosThetaI < 0.0f) if (cosThetaI < 0.0f)
std::swap(etaI, etaT); std::swap(etaI, etaT);
/* Using Snell's law, calculate the sine of the angle /* Using Snell's law, calculate the sine of the angle
between the transmitted ray and the surface normal */ between the transmitted ray and the surface normal */
Float sinThetaT = etaI / etaT * Float sinThetaT = etaI / etaT *
std::sqrt(std::max((Float) 0.0f, 1.0f - cosThetaI*cosThetaI)); std::sqrt(std::max((Float) 0.0f, 1.0f - cosThetaI*cosThetaI));

View File

@ -29,11 +29,15 @@ MTS_NAMESPACE_BEGIN
GLProgram::GLProgram(const std::string &name) GLProgram::GLProgram(const std::string &name)
: GPUProgram(name) { : GPUProgram(name) {
m_id[0] = m_id[1] = m_program = 0; m_id[EVertexProgram] = 0;
m_id[EFragmentProgram] = 0;
m_id[EGeometryProgram] = 0;
m_program = 0;
} }
void GLProgram::init() { void GLProgram::init() {
Assert(m_id[0] == 0 && m_id[1] == 0 && m_program == 0); Assert(m_id[EVertexProgram] == 0 && m_id[EFragmentProgram] == 0
&& m_id[EGeometryProgram] == 0 && m_program == 0);
Log(EDebug, "Uploading a GPU program : %s", toString().c_str()); Log(EDebug, "Uploading a GPU program : %s", toString().c_str());
if (!GLEW_ARB_shader_objects) if (!GLEW_ARB_shader_objects)

View File

@ -534,6 +534,7 @@ void GLRenderer::drawAll(const std::vector<std::pair<const GPUGeometry *, Transf
GLRenderer::beginDrawingMeshes(true); GLRenderer::beginDrawingMeshes(true);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
std::vector<std::pair<const GPUGeometry *, Transform> >::const_iterator it; std::vector<std::pair<const GPUGeometry *, Transform> >::const_iterator it;
if (m_capabilities->isSupported(RendererCapabilities::EBindless)) { if (m_capabilities->isSupported(RendererCapabilities::EBindless)) {
for (it = geo.begin(); it != geo.end(); ++it) { for (it = geo.begin(); it != geo.end(); ++it) {
@ -577,7 +578,6 @@ void GLRenderer::drawAll(const std::vector<std::pair<const GPUGeometry *, Transf
finish(); finish();
} }
} }
glPopMatrix();
} }
} else { } else {
for (it = geo.begin(); it != geo.end(); ++it) { for (it = geo.begin(); it != geo.end(); ++it) {
@ -616,7 +616,6 @@ void GLRenderer::drawAll(const std::vector<std::pair<const GPUGeometry *, Transf
finish(); finish();
} }
} }
glPopMatrix();
} }
} }
GLRenderer::endDrawingMeshes(); GLRenderer::endDrawingMeshes();
@ -633,6 +632,10 @@ void GLRenderer::blitTexture(const GPUTexture *tex, bool flipVertically,
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
Vector2i scrSize = Vector2i(viewport[2], viewport[3]); Vector2i scrSize = Vector2i(viewport[2], viewport[3]);
Vector2i texSize = Vector2i(tex->getSize().x, tex->getSize().y); Vector2i texSize = Vector2i(tex->getSize().x, tex->getSize().y);
if (scrSize.x == 0 || scrSize.y == 0) {
tex->unbind();
return;
}
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();

View File

@ -23,6 +23,11 @@ SceneInformationDialog::SceneInformationDialog(QWidget *parent, Scene *scene) :
QDialog(parent), QDialog(parent),
ui(new Ui::SceneInformationDialog) { ui(new Ui::SceneInformationDialog) {
ui->setupUi(this); ui->setupUi(this);
#if defined(__OSX__)
QFont font = ui->textEdit->currentFont();
font.setPointSize(12);
ui->textEdit->setCurrentFont(font);
#endif
ui->textEdit->setText(scene->toString().c_str()); ui->textEdit->setText(scene->toString().c_str());
} }