Merge branch 'DRTVWR-559' into euclid-17277
commit
82311e4b44
|
|
@ -166,6 +166,43 @@ void LLCubeMap::init(const std::vector<LLPointer<LLImageRaw> >& rawimages)
|
|||
}
|
||||
}
|
||||
|
||||
void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages)
|
||||
{
|
||||
llassert(rawimages.size() == 6);
|
||||
|
||||
U32 texname = 0;
|
||||
|
||||
LLImageGL::generateTextures(1, &texname);
|
||||
|
||||
U32 resolution = rawimages[0]->getWidth();
|
||||
U32 components = rawimages[0]->getComponents();
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
llassert(rawimages[i]->getWidth() == resolution);
|
||||
llassert(rawimages[i]->getHeight() == resolution);
|
||||
llassert(rawimages[i]->getComponents() == components);
|
||||
|
||||
mImages[i] = new LLImageGL(resolution, resolution, components, TRUE);
|
||||
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
|
||||
mRawImages[i] = rawimages[i];
|
||||
mImages[i]->createGLTexture(0, mRawImages[i], texname);
|
||||
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
|
||||
mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
|
||||
mImages[i]->setSubImage(mRawImages[i], 0, 0, resolution, resolution);
|
||||
}
|
||||
enableTexture(0);
|
||||
bind();
|
||||
mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
gGL.getTexUnit(0)->disable();
|
||||
disable();
|
||||
}
|
||||
|
||||
GLuint LLCubeMap::getGLName()
|
||||
{
|
||||
return mImages[0]->getTexName();
|
||||
|
|
@ -256,191 +293,6 @@ void LLCubeMap::restoreMatrix()
|
|||
}*/
|
||||
}
|
||||
|
||||
void LLCubeMap::setReflection (void)
|
||||
{
|
||||
gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName());
|
||||
mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
||||
mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
|
||||
LLVector3 LLCubeMap::map(U8 side, U16 v_val, U16 h_val) const
|
||||
{
|
||||
LLVector3 dir;
|
||||
|
||||
const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z
|
||||
const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1
|
||||
const U8 i_coef = (curr_coef + 1) % 3;
|
||||
const U8 j_coef = (i_coef + 1) % 3;
|
||||
|
||||
dir.mV[curr_coef] = side_dir;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0: // negative X
|
||||
dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
|
||||
dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
|
||||
break;
|
||||
case 1: // positive X
|
||||
dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
|
||||
dir.mV[j_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1;
|
||||
break;
|
||||
case 2: // negative Y
|
||||
dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
|
||||
dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
|
||||
break;
|
||||
case 3: // positive Y
|
||||
dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1;
|
||||
dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
|
||||
break;
|
||||
case 4: // negative Z
|
||||
dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1;
|
||||
dir.mV[j_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1;
|
||||
break;
|
||||
case 5: // positive Z
|
||||
dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1;
|
||||
dir.mV[j_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1;
|
||||
break;
|
||||
default:
|
||||
dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1;
|
||||
dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1;
|
||||
}
|
||||
|
||||
dir.normVec();
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLCubeMap::project(F32& v_val, F32& h_val, BOOL& outside,
|
||||
U8 side, const LLVector3& dir) const
|
||||
{
|
||||
const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z
|
||||
const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1
|
||||
const U8 i_coef = (curr_coef + 1) % 3;
|
||||
const U8 j_coef = (i_coef + 1) % 3;
|
||||
|
||||
outside = TRUE;
|
||||
if (side_dir * dir.mV[curr_coef] < 0)
|
||||
return FALSE;
|
||||
|
||||
LLVector3 ray;
|
||||
|
||||
F32 norm_val = fabs(dir.mV[curr_coef]);
|
||||
|
||||
if (norm_val < epsilon)
|
||||
norm_val = 1e-5f;
|
||||
|
||||
ray.mV[curr_coef] = side_dir;
|
||||
ray.mV[i_coef] = dir.mV[i_coef] / norm_val;
|
||||
ray.mV[j_coef] = dir.mV[j_coef] / norm_val;
|
||||
|
||||
|
||||
const F32 i_val = (ray.mV[i_coef] + 1) * 0.5f * RESOLUTION;
|
||||
const F32 j_val = (ray.mV[j_coef] + 1) * 0.5f * RESOLUTION;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0: // negative X
|
||||
v_val = RESOLUTION - i_val;
|
||||
h_val = j_val;
|
||||
break;
|
||||
case 1: // positive X
|
||||
v_val = RESOLUTION - i_val;
|
||||
h_val = RESOLUTION - j_val;
|
||||
break;
|
||||
case 2: // negative Y
|
||||
v_val = RESOLUTION - i_val;
|
||||
h_val = j_val;
|
||||
break;
|
||||
case 3: // positive Y
|
||||
v_val = i_val;
|
||||
h_val = j_val;
|
||||
break;
|
||||
case 4: // negative Z
|
||||
v_val = RESOLUTION - j_val;
|
||||
h_val = RESOLUTION - i_val;
|
||||
break;
|
||||
case 5: // positive Z
|
||||
v_val = RESOLUTION - j_val;
|
||||
h_val = i_val;
|
||||
break;
|
||||
default:
|
||||
v_val = i_val;
|
||||
h_val = j_val;
|
||||
}
|
||||
|
||||
outside = ((v_val < 0) || (v_val > RESOLUTION) ||
|
||||
(h_val < 0) || (h_val > RESOLUTION));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
|
||||
U8 side, LLVector3 dir[4]) const
|
||||
{
|
||||
v_min = h_min = RESOLUTION;
|
||||
v_max = h_max = 0;
|
||||
|
||||
BOOL fully_outside = TRUE;
|
||||
for (U8 vtx = 0; vtx < 4; ++vtx)
|
||||
{
|
||||
F32 v_val, h_val;
|
||||
BOOL outside;
|
||||
BOOL consider = project(v_val, h_val, outside, side, dir[vtx]);
|
||||
if (!outside)
|
||||
fully_outside = FALSE;
|
||||
if (consider)
|
||||
{
|
||||
if (v_val < v_min) v_min = v_val;
|
||||
if (v_val > v_max) v_max = v_val;
|
||||
if (h_val < h_min) h_min = h_val;
|
||||
if (h_val > h_max) h_max = h_val;
|
||||
}
|
||||
}
|
||||
|
||||
v_min = llmax(0.0f, v_min);
|
||||
v_max = llmin(RESOLUTION - epsilon, v_max);
|
||||
h_min = llmax(0.0f, h_min);
|
||||
h_max = llmin(RESOLUTION - epsilon, h_max);
|
||||
|
||||
return !fully_outside;
|
||||
}
|
||||
|
||||
|
||||
void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
F32 v_min, v_max, h_min, h_max;
|
||||
LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3];
|
||||
center.normVec();
|
||||
|
||||
for (U8 side = 0; side < 6; ++side)
|
||||
{
|
||||
if (!project(v_min, v_max, h_min, h_max, side, dir))
|
||||
continue;
|
||||
|
||||
U8 *td = mRawImages[side]->getData();
|
||||
|
||||
U16 v_minu = (U16) v_min;
|
||||
U16 v_maxu = (U16) (ceil(v_max) + 0.5);
|
||||
U16 h_minu = (U16) h_min;
|
||||
U16 h_maxu = (U16) (ceil(h_max) + 0.5);
|
||||
|
||||
for (U16 v = v_minu; v < v_maxu; ++v)
|
||||
for (U16 h = h_minu; h < h_maxu; ++h)
|
||||
//for (U16 v = 0; v < RESOLUTION; ++v)
|
||||
// for (U16 h = 0; h < RESOLUTION; ++h)
|
||||
{
|
||||
const LLVector3 ray = map(side, v, h);
|
||||
if (ray * center > 0.999)
|
||||
{
|
||||
const U32 offset = (RESOLUTION * v + h) * 4;
|
||||
for (U8 cc = 0; cc < 3; ++cc)
|
||||
td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5);
|
||||
}
|
||||
}
|
||||
mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCubeMap::destroyGL()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,6 +40,13 @@ class LLCubeMap : public LLRefCount
|
|||
public:
|
||||
LLCubeMap(bool init_as_srgb);
|
||||
void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
|
||||
|
||||
// init from environment map images
|
||||
// Similar to init, but takes ownership of rawimages and makes this cubemap
|
||||
// respect the resolution of rawimages
|
||||
// Raw images must point to array of six square images that are all the same resolution
|
||||
// For example usage, see LLEnvironmentMap
|
||||
void initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages);
|
||||
void initGL();
|
||||
void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);
|
||||
void initGLData();
|
||||
|
|
@ -54,18 +61,9 @@ public:
|
|||
void disableTexture(void);
|
||||
void setMatrix(S32 stage);
|
||||
void restoreMatrix();
|
||||
void setReflection (void);
|
||||
|
||||
void finishPaint();
|
||||
|
||||
GLuint getGLName();
|
||||
|
||||
LLVector3 map(U8 side, U16 v_val, U16 h_val) const;
|
||||
BOOL project(F32& v_val, F32& h_val, BOOL& outside,
|
||||
U8 side, const LLVector3& dir) const;
|
||||
BOOL project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
|
||||
U8 side, LLVector3 dir[4]) const;
|
||||
void paintIn(LLVector3 dir[4], const LLColor4U& col);
|
||||
void destroyGL();
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -832,6 +832,9 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
|
|||
|
||||
As example where this situation appear see: "Deferred Material Shader 28/29/30/31"
|
||||
And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437
|
||||
|
||||
--- davep TODO -- pretty sure the entire block here is superstitious and that the uniform index has nothing to do with the texture channel
|
||||
texture channel should follow the uniform VALUE
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -840,6 +843,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
|
|||
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
|
||||
S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
|
||||
S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
|
||||
S32 reflectionMap = glGetUniformLocationARB(mProgramObject, "reflectionMap");
|
||||
|
||||
std::set<S32> skip_index;
|
||||
|
||||
|
|
@ -882,6 +886,12 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (-1 == reflectionMap && std::string(name) == "reflectionMap")
|
||||
{
|
||||
reflectionMap = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
|
||||
{
|
||||
altDiffuseMap = i;
|
||||
|
|
@ -892,8 +902,9 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
|
|||
bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
|
||||
bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
|
||||
bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
|
||||
bool refLessDiff = reflectionMap < diffuseMap && -1 != reflectionMap;
|
||||
|
||||
if (specularDiff || bumpLessDiff || envLessDiff)
|
||||
if (specularDiff || bumpLessDiff || envLessDiff || refLessDiff)
|
||||
{
|
||||
mapUniform(diffuseMap, uniforms);
|
||||
skip_index.insert(diffuseMap);
|
||||
|
|
@ -912,6 +923,11 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
|
|||
mapUniform(environmentMap, uniforms);
|
||||
skip_index.insert(environmentMap);
|
||||
}
|
||||
|
||||
if (-1 != reflectionMap) {
|
||||
mapUniform(reflectionMap, uniforms);
|
||||
skip_index.insert(reflectionMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1155,6 +1155,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("bumpMap");
|
||||
mReservedUniforms.push_back("bumpMap2");
|
||||
mReservedUniforms.push_back("environmentMap");
|
||||
mReservedUniforms.push_back("reflectionMap");
|
||||
mReservedUniforms.push_back("cloud_noise_texture");
|
||||
mReservedUniforms.push_back("cloud_noise_texture_next");
|
||||
mReservedUniforms.push_back("fullbright");
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public:
|
|||
BUMP_MAP, // "bumpMap"
|
||||
BUMP_MAP2, // "bumpMap2"
|
||||
ENVIRONMENT_MAP, // "environmentMap"
|
||||
REFLECTION_MAP, // "reflectionMap"
|
||||
CLOUD_NOISE_MAP, // "cloud_noise_texture"
|
||||
CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
|
||||
FULLBRIGHT, // "fullbright"
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ set(viewer_SOURCE_FILES
|
|||
lldynamictexture.cpp
|
||||
llemote.cpp
|
||||
llenvironment.cpp
|
||||
llenvironmentmap.cpp
|
||||
llestateinfomodel.cpp
|
||||
lleventnotifier.cpp
|
||||
lleventpoll.cpp
|
||||
|
|
@ -832,6 +833,7 @@ set(viewer_HEADER_FILES
|
|||
lldynamictexture.h
|
||||
llemote.h
|
||||
llenvironment.h
|
||||
llenvironmentmap.h
|
||||
llestateinfomodel.h
|
||||
lleventnotifier.h
|
||||
lleventpoll.h
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ out vec4 frag_color;
|
|||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ uniform sampler2DRect diffuseRect;
|
|||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D projectionMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ out vec4 frag_color;
|
|||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
uniform sampler2DRect depthMap;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ uniform sampler2DRect normalMap;
|
|||
uniform sampler2DRect lightMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform samplerCube reflectionMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
uniform float blur_size;
|
||||
|
|
@ -119,6 +120,8 @@ void main()
|
|||
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
|
||||
if (spec.a > 0.0) // specular reflection
|
||||
{
|
||||
float sa = dot(refnormpersp, light_dir.xyz);
|
||||
|
|
@ -128,13 +131,28 @@ void main()
|
|||
vec3 spec_contrib = dumbshiny * spec.rgb;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 6;
|
||||
color.rgb += spec_contrib;
|
||||
|
||||
// add reflection map - EXPERIMENTAL WORK IN PROGRESS
|
||||
float reflection_lods = 11; // TODO -- base this on resolution of reflection map instead of hard coding
|
||||
float min_lod = textureQueryLod(reflectionMap,env_vec).y; // lower is higher res
|
||||
|
||||
//vec3 reflected_color = texture(reflectionMap, env_vec, (1.0-spec.a)*reflection_lod).rgb;
|
||||
vec3 reflected_color = textureLod(reflectionMap, env_vec, max(min_lod, (1.0-spec.a)*reflection_lods)).rgb;
|
||||
//vec3 reflected_color = texture(reflectionMap, env_vec).rgb;
|
||||
//vec3 reflected_color = normalize(env_vec)*0.5+0.5;
|
||||
reflected_color *= spec.rgb;
|
||||
vec3 mixer = clamp(color.rgb + vec3(1,1,1) - spec.rgb, vec3(0,0,0), vec3(1,1,1));
|
||||
|
||||
color.rgb = mix(reflected_color*sqrt(spec.a*0.8), color, mixer);
|
||||
|
||||
//color.rgb = mix(reflected_color * spec.rgb * sqrt(spec.a*0.8), color.rgb, color.rgb);
|
||||
//color.rgb += reflected_color * spec.rgb; // * sqrt(spec.a*0.8), color.rgb, color.rgb);
|
||||
}
|
||||
|
||||
color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{ // add environmentmap
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
|
||||
color = mix(color.rgb, reflected_color, envIntensity);
|
||||
}
|
||||
|
|
@ -154,5 +172,6 @@ void main()
|
|||
// convert to linear as fullscreen lights need to sum in linear colorspace
|
||||
// and will be gamma (re)corrected downstream...
|
||||
frag_color.rgb = srgb_to_linear(color.rgb);
|
||||
//frag_color.r = 1.0;
|
||||
frag_color.a = bloom;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* @file llenvironmentmap.cpp
|
||||
* @brief LLEnvironmentMap class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llenvironmentmap.h"
|
||||
#include "pipeline.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
LLEnvironmentMap::LLEnvironmentMap()
|
||||
{
|
||||
mOrigin.setVec(0, 0, 0);
|
||||
}
|
||||
|
||||
void LLEnvironmentMap::update(const LLVector3& origin, U32 resolution)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
|
||||
mOrigin = origin;
|
||||
|
||||
// allocate images
|
||||
std::vector<LLPointer<LLImageRaw> > rawimages;
|
||||
rawimages.reserve(6);
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
rawimages.push_back(new LLImageRaw(resolution, resolution, 3));
|
||||
}
|
||||
|
||||
// ============== modified copy/paste of LLFloater360Capture::capture360Images() follows ==============
|
||||
|
||||
// these are the 6 directions we will point the camera, see LLCubeMap::mTargets
|
||||
LLVector3 look_dirs[6] = {
|
||||
LLVector3(-1, 0, 0),
|
||||
LLVector3(1, 0, 0),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, 1, 0),
|
||||
LLVector3(0, 0, -1),
|
||||
LLVector3(0, 0, 1)
|
||||
};
|
||||
|
||||
LLVector3 look_upvecs[6] = {
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, 0, -1),
|
||||
LLVector3(0, 0, 1),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, -1, 0)
|
||||
};
|
||||
|
||||
// save current view/camera settings so we can restore them afterwards
|
||||
S32 old_occlusion = LLPipeline::sUseOcclusion;
|
||||
|
||||
// set new parameters specific to the 360 requirements
|
||||
LLPipeline::sUseOcclusion = 0;
|
||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
LLVector3 old_origin = camera->getOrigin();
|
||||
F32 old_fov = camera->getView();
|
||||
F32 old_aspect = camera->getAspect();
|
||||
F32 old_yaw = camera->getYaw();
|
||||
|
||||
// camera constants for the square, cube map capture image
|
||||
camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
|
||||
camera->setView(F_PI_BY_TWO);
|
||||
camera->yaw(0.0);
|
||||
camera->setOrigin(mOrigin);
|
||||
|
||||
// for each of the 6 directions we shoot...
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
// set up camera to look in each direction
|
||||
camera->lookDir(look_dirs[i], look_upvecs[i]);
|
||||
|
||||
// call the (very) simplified snapshot code that simply deals
|
||||
// with a single image, no sub-images etc. but is very fast
|
||||
gViewerWindow->simpleSnapshot(rawimages[i],
|
||||
resolution, resolution, 1);
|
||||
}
|
||||
|
||||
// restore original view/camera/avatar settings settings
|
||||
camera->setAspect(old_aspect);
|
||||
camera->setView(old_fov);
|
||||
camera->yaw(old_yaw);
|
||||
camera->setOrigin(old_origin);
|
||||
|
||||
LLPipeline::sUseOcclusion = old_occlusion;
|
||||
|
||||
// ====================================================
|
||||
|
||||
mCubeMap = new LLCubeMap(false);
|
||||
mCubeMap->initEnvironmentMap(rawimages);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @file llenvironmentmap.h
|
||||
* @brief LLEnvironmentMap class declaration
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llcubemap.h"
|
||||
|
||||
class LLEnvironmentMap
|
||||
{
|
||||
public:
|
||||
// allocate an environment map of the given resolution
|
||||
LLEnvironmentMap();
|
||||
|
||||
// update this environment map
|
||||
// origin - position in agent space to generate environment map from in agent space
|
||||
// resolution - size of cube map to generate
|
||||
void update(const LLVector3& origin, U32 resolution);
|
||||
|
||||
// cube map used to sample this environment map
|
||||
LLPointer<LLCubeMap> mCubeMap;
|
||||
|
||||
// point at which environment map was generated from (in agent space)
|
||||
LLVector3 mOrigin;
|
||||
};
|
||||
|
||||
|
|
@ -8304,6 +8304,12 @@ void handle_cache_clear_immediately()
|
|||
LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
|
||||
}
|
||||
|
||||
void handle_override_environment_map()
|
||||
{
|
||||
gPipeline.overrideEnvironmentMap();
|
||||
}
|
||||
|
||||
|
||||
void handle_web_content_test(const LLSD& param)
|
||||
{
|
||||
std::string url = param.asString();
|
||||
|
|
@ -9402,6 +9408,8 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");
|
||||
//Develop (clear cache immediately)
|
||||
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
|
||||
//Develop (override environment map)
|
||||
commit.add("Develop.OverrideEnvironmentMap", boost::bind(&handle_override_environment_map));
|
||||
|
||||
// Admin >Object
|
||||
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
|
||||
|
|
|
|||
|
|
@ -8188,24 +8188,42 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
|
||||
stop_glerror();
|
||||
|
||||
bool setup_env_mat = false;
|
||||
channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
|
||||
if (channel > -1)
|
||||
{
|
||||
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
|
||||
if (cube_map)
|
||||
{
|
||||
setup_env_mat = true;
|
||||
cube_map->enable(channel);
|
||||
cube_map->bind();
|
||||
F32* m = gGLModelView;
|
||||
|
||||
F32 mat[] = { m[0], m[1], m[2],
|
||||
m[4], m[5], m[6],
|
||||
m[8], m[9], m[10] };
|
||||
|
||||
shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
|
||||
}
|
||||
}
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::REFLECTION_MAP, LLTexUnit::TT_CUBE_MAP);
|
||||
if (channel > -1)
|
||||
{
|
||||
LLCubeMap* cube_map = mEnvironmentMap.mCubeMap;
|
||||
if (cube_map)
|
||||
{
|
||||
setup_env_mat = true;
|
||||
cube_map->enable(channel);
|
||||
cube_map->bind();
|
||||
}
|
||||
}
|
||||
|
||||
if (setup_env_mat)
|
||||
{
|
||||
F32* m = gGLModelView;
|
||||
|
||||
F32 mat[] = { m[0], m[1], m[2],
|
||||
m[4], m[5], m[6],
|
||||
m[8], m[9], m[10] };
|
||||
|
||||
shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
|
||||
}
|
||||
|
||||
if (gAtmosphere)
|
||||
{
|
||||
// bind precomputed textures necessary for calculating sun and sky luminance
|
||||
|
|
@ -9103,6 +9121,17 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
|
|||
cube_map->disable();
|
||||
}
|
||||
}
|
||||
|
||||
channel = shader.disableTexture(LLShaderMgr::REFLECTION_MAP, LLTexUnit::TT_CUBE_MAP);
|
||||
if (channel > -1)
|
||||
{
|
||||
LLCubeMap* cube_map = mEnvironmentMap.mCubeMap;
|
||||
if (cube_map)
|
||||
{
|
||||
cube_map->disable();
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
shader.unbind();
|
||||
|
|
@ -11467,3 +11496,8 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::overrideEnvironmentMap()
|
||||
{
|
||||
mEnvironmentMap.update(LLViewerCamera::instance().getOrigin(), 1024);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "llgl.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llrendertarget.h"
|
||||
#include "llenvironmentmap.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
|
|
@ -426,6 +427,9 @@ public:
|
|||
void hideObject( const LLUUID& id );
|
||||
void restoreHiddenObject( const LLUUID& id );
|
||||
|
||||
LLEnvironmentMap mEnvironmentMap;
|
||||
void overrideEnvironmentMap();
|
||||
|
||||
private:
|
||||
void unloadShaders();
|
||||
void addToQuickLookup( LLDrawPool* new_poolp );
|
||||
|
|
|
|||
|
|
@ -3250,6 +3250,13 @@ function="World.EnvPreset"
|
|||
function="ToggleControl"
|
||||
parameter="RenderHoverGlowEnable" />
|
||||
</menu_item_check>
|
||||
<menu_item_call
|
||||
enabled="true"
|
||||
label="Override Environment Map"
|
||||
name="Override Environment Map">
|
||||
<menu_item_call.on_click
|
||||
function="Develop.OverrideEnvironmentMap" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
|
||||
<menu_item_call
|
||||
|
|
|
|||
Loading…
Reference in New Issue