Merge. Pull in viewer-release after materials viewer release.
commit
eaef5e63d5
4
.hgtags
4
.hgtags
|
|
@ -56,11 +56,11 @@ a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
|
|||
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
|
||||
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
|
||||
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
|
||||
b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
|
||||
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
|
||||
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
|
||||
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
|
||||
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
|
||||
b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
|
||||
63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
|
||||
4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
|
||||
4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
|
||||
|
|
@ -464,3 +464,5 @@ f6741d5fe8d632651424484df0fe0cb4a01e9fbe 3.6.2-release
|
|||
fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
|
||||
83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
|
||||
91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
|
||||
bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
|
||||
b62e417982d9d4f3ec49d0de3b3c2e37c6d394c1 3.6.6-release
|
||||
|
|
|
|||
|
|
@ -1,164 +0,0 @@
|
|||
diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.cpp
|
||||
--- a/indra/llprimitive/llrendermaterialtable.cpp Wed May 15 17:57:21 2013 +0000
|
||||
+++ b/indra/llprimitive/llrendermaterialtable.cpp Wed May 22 14:23:04 2013 -0700
|
||||
@@ -184,6 +184,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
+// 'v' is an integer value for 100ths of radians (don't ask...)
|
||||
+//
|
||||
+void LLRenderMaterialEntry::LLRenderMaterial::setSpecularMapRotation(S32 v) const
|
||||
+{
|
||||
+ // Store the fact that we're using the new rotation rep
|
||||
+ //
|
||||
+ m_flags |= kNewSpecularMapRotation;
|
||||
+
|
||||
+ // Store 'sign bit' in our m_flags
|
||||
+ //
|
||||
+ m_flags &= ~kSpecularMapRotationNegative;
|
||||
+ m_flags |= (specularMapRotation < 0) ? kSpecularMapRotationNegative : 0;
|
||||
+
|
||||
+ specularRotation = abs(specularRotation);
|
||||
+ specularRotation = llmin(specularRotation, MAX_MATERIAL_MAP_ROTATION);
|
||||
+
|
||||
+ m_specularRotation = (U16)(abs(specularMapRotation));
|
||||
+}
|
||||
+
|
||||
+// 'v' is an integer value for 100ths of radians (don't ask...)
|
||||
+//
|
||||
+void LLRenderMaterialEntry::LLRenderMaterial::setNormalMapRotation(S32 v) const
|
||||
+{
|
||||
+
|
||||
+ // Store the fact that we're using the new rep for this material
|
||||
+ //
|
||||
+ m_flags |= kNewNormalMapRotation;
|
||||
+
|
||||
+ // Store 'sign bit' in our m_flags
|
||||
+ //
|
||||
+ m_flags &= ~kNormalMapRotationNegative;
|
||||
+ m_flags |= (normalMapRotation < 0) ? kNormalMapRotationNegative : 0;
|
||||
+
|
||||
+ normalRotation = abs(normalRotation);
|
||||
+ normalRotation = llmin(normalRotation, MAX_MATERIAL_MAP_ROTATION);
|
||||
+
|
||||
+ m_normalRotation = (U16)(abs(normalMapRotation));
|
||||
+}
|
||||
|
||||
void LLRenderMaterialEntry::LLRenderMaterial::asLLSD( LLSD& dest ) const
|
||||
{
|
||||
@@ -193,20 +231,45 @@
|
||||
dest["NormOffsetY"] = (S32)m_normalOffsetY;
|
||||
dest["NormRepeatX"] = m_normalRepeatX;
|
||||
dest["NormRepeatY"] = m_normalRepeatY;
|
||||
- dest["NormRotation"] = (S32)m_normalRotation;
|
||||
+
|
||||
+ S32 value = (S32)m_normalMapRotation;
|
||||
+
|
||||
+ // If we don't have the flag for new rotations set,
|
||||
+ // then we need to convert it now
|
||||
+ if (!(m_flags & kNewNormalMapRotation))
|
||||
+ {
|
||||
+ F32 old_radians = ((F32)m_normalMapRotation / 10000.0f)
|
||||
+ S32 new_val = (S32)(old_radians * 100.0f);
|
||||
+ setNormalMapRotation(new_Val);
|
||||
+ }
|
||||
+
|
||||
+ dest["NormRotation"] = (m_flags & kNormalMapRotationNegative) ? -(S32)m_normalRotation : (S32)m_normalRotation;
|
||||
|
||||
dest["SpecOffsetX"] = (S32)m_specularOffsetX;
|
||||
dest["SpecOffsetY"] = (S32)m_specularOffsetY;
|
||||
dest["SpecRepeatX"] = m_specularRepeatX;
|
||||
dest["SpecRepeatY"] = m_specularRepeatY;
|
||||
- dest["SpecRotation"] = (S32)m_specularRotation;
|
||||
+
|
||||
+
|
||||
+ value = (S32)m_specularRotation;
|
||||
+
|
||||
+ // If we don't have the flag for new rotations set,
|
||||
+ // then we need to convert it now
|
||||
+ if (!(m_flags & kNewSpecularMapRotation))
|
||||
+ {
|
||||
+ F32 old_radians = ((F32)m_specularMapRotation / 10000.0f)
|
||||
+ S32 new_val = (S32)(old_radians * 100.0f);
|
||||
+ setSpecularMapRotation(new_Val);
|
||||
+ }
|
||||
+
|
||||
+ dest["SpecRotation"] = (m_flags & kSpecularMapRotationNegative) ? -(S32)m_specularRotation : (S32)m_specularRotation;
|
||||
|
||||
dest["SpecMap"] = m_specularMap;
|
||||
dest["SpecColor"] = m_specularLightColor.getValue();
|
||||
dest["SpecExp"] = (S32)m_specularLightExponent;
|
||||
dest["EnvIntensity"] = (S32)m_environmentIntensity;
|
||||
dest["AlphaMaskCutoff"] = (S32)m_alphaMaskCutoff;
|
||||
- dest["DiffuseAlphaMode"] = (S32)m_diffuseAlphaMode;
|
||||
+ dest["DiffuseAlphaMode"] = (S32)(m_diffuseAlphaMode & 0xF);
|
||||
|
||||
}
|
||||
|
||||
@@ -217,7 +280,10 @@
|
||||
m_normalOffsetY = (U16)materialDefinition["NormOffsetY"].asInteger();
|
||||
m_normalRepeatX = materialDefinition["NormRepeatX"].asInteger();
|
||||
m_normalRepeatY = materialDefinition["NormRepeatY"].asInteger();
|
||||
- m_normalRotation = (U16)materialDefinition["NormRotation"].asInteger();
|
||||
+
|
||||
+ S32 normalRotation = materialDefinition["NormRotation"].asInteger();
|
||||
+
|
||||
+ setNormalMapRotation(normalRotation);
|
||||
|
||||
m_specularMap = materialDefinition["SpecMap"].asUUID();
|
||||
|
||||
@@ -225,7 +291,10 @@
|
||||
m_specularOffsetY = (U16)materialDefinition["SpecOffsetY"].asInteger();
|
||||
m_specularRepeatX = materialDefinition["SpecRepeatX"].asInteger();
|
||||
m_specularRepeatY = materialDefinition["SpecRepeatY"].asInteger();
|
||||
- m_specularRotation = (U16)materialDefinition["SpecRotation"].asInteger();
|
||||
+
|
||||
+ S32 specularRotation = materialDefinition["SpecRotation"].asInteger();
|
||||
+
|
||||
+ setSpecularMapRotation(specularRotation);
|
||||
|
||||
m_specularLightColor.setValue( materialDefinition["SpecColor"] );
|
||||
m_specularLightExponent = (U8)materialDefinition["SpecExp"].asInteger();
|
||||
diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.h
|
||||
--- a/indra/llprimitive/llrendermaterialtable.h Wed May 15 17:57:21 2013 +0000
|
||||
+++ b/indra/llprimitive/llrendermaterialtable.h Wed May 22 14:23:04 2013 -0700
|
||||
@@ -89,11 +89,17 @@
|
||||
|
||||
void computeID();
|
||||
|
||||
+
|
||||
struct LLRenderMaterial
|
||||
{
|
||||
void asLLSD( LLSD& dest ) const;
|
||||
void setFromLLSD( const LLSD& materialDefinition );
|
||||
|
||||
+ void setNormalMapRotation(S32 v);
|
||||
+ void setSpecularMapRotation(S32 v);
|
||||
+
|
||||
+ const S32 MAX_MATERIAL_MAP_ROTATION = 62800;
|
||||
+
|
||||
// 36 bytes
|
||||
LLUUID m_normalMap;
|
||||
LLUUID m_specularMap;
|
||||
@@ -119,7 +125,20 @@
|
||||
U8 m_specularLightExponent;
|
||||
U8 m_environmentIntensity;
|
||||
U8 m_alphaMaskCutoff;
|
||||
- U8 m_diffuseAlphaMode;
|
||||
+ U8 m_diffuseAlphaMode : 4;
|
||||
+ U8 m_flags : 4;
|
||||
+ };
|
||||
+
|
||||
+ // Flags stored in LLRenderMaterial::m_flags to differentiate 'old' rotation format
|
||||
+ // which doesn't handle negative or large rotations correctly from new format.
|
||||
+ // All ancient materials will have these flags unset as the values for diffuseAlphaMode
|
||||
+ // from which the bits were stolen never used more than the bottom 2 bits.
|
||||
+ //
|
||||
+ enum RenderMaterialFlags {
|
||||
+ kNewNormalMapRotation = 0x1,
|
||||
+ kNewSpecularMapRotation = 0x2,
|
||||
+ kNormalMapRotationNegative = 0x4,
|
||||
+ kSpecularMapRotationNegative = 0x8
|
||||
};
|
||||
|
||||
friend struct eastl::hash<LLRenderMaterial>;
|
||||
|
|
@ -2638,7 +2638,6 @@
|
|||
<array>
|
||||
<string>/build</string>
|
||||
<string>"/cfg=Release|Win32"</string>
|
||||
<string>"/CL_ADD=/m:1"</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
|
|||
|
|
@ -679,6 +679,8 @@ Kagehi Kohn
|
|||
Kaimen Takahe
|
||||
Katharine Berry
|
||||
STORM-1900
|
||||
STORM-1940
|
||||
STORM-1941
|
||||
Keklily Longfall
|
||||
Ken Lavender
|
||||
Ken March
|
||||
|
|
|
|||
|
|
@ -134,15 +134,20 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|||
OUTPUT_VARIABLE XCODE_VERSION )
|
||||
|
||||
# To support a different SDK update these Xcode settings:
|
||||
if (XCODE_VERSION GREATER 4.5)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.8)
|
||||
else (XCODE_VERSION GREATER 4.5)
|
||||
if (XCODE_VERSION GREATER 4.2)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.7)
|
||||
else (XCODE_VERSION GREATER 4.2)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.7)
|
||||
endif (XCODE_VERSION GREATER 4.2)
|
||||
endif (XCODE_VERSION GREATER 4.5)
|
||||
|
||||
set(CMAKE_OSX_SYSROOT macosx10.6)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
|
||||
|
||||
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
|
|||
# Link with OS-specific libraries for LLWindow dependency
|
||||
if (DARWIN)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
set(OS_LIBRARIES ${COCOA_LIBRARY})
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
set(OS_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
|
||||
elseif (WINDOWS)
|
||||
#ll_stack_trace needs this now...
|
||||
list(APPEND WINDOWS_LIBRARIES dbghelp)
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()
|
|||
llassert_always(mNumActiveRef > 0) ;
|
||||
}
|
||||
|
||||
llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
|
||||
llassert(mNumTotalRef <= (FULL_VOLATILE_APR_POOL << 2)) ;
|
||||
}
|
||||
|
||||
BOOL LLVolatileAPRPool::isFull()
|
||||
|
|
|
|||
|
|
@ -67,12 +67,18 @@ using namespace llsd;
|
|||
# include <sys/sysctl.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <stdint.h>
|
||||
# include <Carbon/Carbon.h>
|
||||
# include <CoreServices/CoreServices.h>
|
||||
# include <stdexcept>
|
||||
# include <mach/host_info.h>
|
||||
# include <mach/mach_host.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/task_info.h>
|
||||
|
||||
// disable warnings about Gestalt calls being deprecated
|
||||
// until Apple get's on the ball and provides an alternative
|
||||
//
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
#elif LL_LINUX
|
||||
# include <errno.h>
|
||||
# include <sys/utsname.h>
|
||||
|
|
@ -1502,3 +1508,10 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
|
|||
if (dst != NULL) gzclose(dst);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if LL_DARWIN
|
||||
// disable warnings about Gestalt calls being deprecated
|
||||
// until Apple get's on the ball and provides an alternative
|
||||
//
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file llversionviewer.h
|
||||
* @brief
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLVERSIONVIEWER_H
|
||||
#define LL_LLVERSIONVIEWER_H
|
||||
|
||||
const S32 LL_VERSION_MAJOR = 3;
|
||||
const S32 LL_VERSION_MINOR = 4;
|
||||
const S32 LL_VERSION_PATCH = 6;
|
||||
const S32 LL_VERSION_BUILD = 0;
|
||||
|
||||
const char * const LL_CHANNEL = "Second Life Developer";
|
||||
|
||||
#if LL_DARWIN
|
||||
const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -409,6 +409,26 @@ inline void LLVector4a::normalize3fast()
|
|||
mQ = _mm_mul_ps( mQ, approxRsqrt );
|
||||
}
|
||||
|
||||
inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
|
||||
{
|
||||
if (!isFinite3())
|
||||
{
|
||||
*this = d ? *d : LLVector4a(0,1,0,1);
|
||||
return;
|
||||
}
|
||||
|
||||
LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this );
|
||||
|
||||
if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON)
|
||||
{
|
||||
*this = d ? *d : LLVector4a(0,1,0,1);
|
||||
return;
|
||||
}
|
||||
|
||||
const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ);
|
||||
mQ = _mm_mul_ps( mQ, approxRsqrt );
|
||||
}
|
||||
|
||||
// Return true if this vector is normalized with respect to x,y,z up to tolerance
|
||||
inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -136,6 +136,82 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent
|
|||
return true;
|
||||
}
|
||||
|
||||
// Finds tangent vec based on three vertices with texture coordinates.
|
||||
// Fills in dummy values if the triangle has degenerate texture coordinates.
|
||||
void calc_tangent_from_triangle(
|
||||
LLVector4a& normal,
|
||||
LLVector4a& tangent_out,
|
||||
const LLVector4a& v1,
|
||||
const LLVector2& w1,
|
||||
const LLVector4a& v2,
|
||||
const LLVector2& w2,
|
||||
const LLVector4a& v3,
|
||||
const LLVector2& w3)
|
||||
{
|
||||
const F32* v1ptr = v1.getF32ptr();
|
||||
const F32* v2ptr = v2.getF32ptr();
|
||||
const F32* v3ptr = v3.getF32ptr();
|
||||
|
||||
float x1 = v2ptr[0] - v1ptr[0];
|
||||
float x2 = v3ptr[0] - v1ptr[0];
|
||||
float y1 = v2ptr[1] - v1ptr[1];
|
||||
float y2 = v3ptr[1] - v1ptr[1];
|
||||
float z1 = v2ptr[2] - v1ptr[2];
|
||||
float z2 = v3ptr[2] - v1ptr[2];
|
||||
|
||||
float s1 = w2.mV[0] - w1.mV[0];
|
||||
float s2 = w3.mV[0] - w1.mV[0];
|
||||
float t1 = w2.mV[1] - w1.mV[1];
|
||||
float t2 = w3.mV[1] - w1.mV[1];
|
||||
|
||||
F32 rd = s1*t2-s2*t1;
|
||||
|
||||
float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
|
||||
|
||||
llassert(llfinite(r));
|
||||
llassert(!llisnan(r));
|
||||
|
||||
LLVector4a sdir(
|
||||
(t2 * x1 - t1 * x2) * r,
|
||||
(t2 * y1 - t1 * y2) * r,
|
||||
(t2 * z1 - t1 * z2) * r);
|
||||
|
||||
LLVector4a tdir(
|
||||
(s1 * x2 - s2 * x1) * r,
|
||||
(s1 * y2 - s2 * y1) * r,
|
||||
(s1 * z2 - s2 * z1) * r);
|
||||
|
||||
LLVector4a n = normal;
|
||||
LLVector4a t = sdir;
|
||||
|
||||
LLVector4a ncrosst;
|
||||
ncrosst.setCross3(n,t);
|
||||
|
||||
// Gram-Schmidt orthogonalize
|
||||
n.mul(n.dot3(t).getF32());
|
||||
|
||||
LLVector4a tsubn;
|
||||
tsubn.setSub(t,n);
|
||||
|
||||
if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
tsubn.normalize3fast_checked();
|
||||
|
||||
// Calculate handedness
|
||||
F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
|
||||
|
||||
tsubn.getF32ptr()[3] = handedness;
|
||||
|
||||
tangent_out = tsubn;
|
||||
}
|
||||
else
|
||||
{
|
||||
// degenerate, make up a value
|
||||
//
|
||||
tangent_out.set(0,0,1,1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
|
||||
|
|
@ -5908,10 +5984,10 @@ void LLVolumeFace::cacheOptimize()
|
|||
wght = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
}
|
||||
|
||||
LLVector4a* binorm = NULL;
|
||||
LLVector4a* tangent = NULL;
|
||||
if (mTangents)
|
||||
{
|
||||
binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
tangent = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
}
|
||||
|
||||
//allocate mapping of old indices to new indices
|
||||
|
|
@ -5936,7 +6012,7 @@ void LLVolumeFace::cacheOptimize()
|
|||
}
|
||||
if (mTangents)
|
||||
{
|
||||
binorm[cur_idx] = mTangents[idx];
|
||||
tangent[cur_idx] = mTangents[idx];
|
||||
}
|
||||
|
||||
cur_idx++;
|
||||
|
|
@ -5958,7 +6034,7 @@ void LLVolumeFace::cacheOptimize()
|
|||
mNormals = norm;
|
||||
mTexCoords = tc;
|
||||
mWeights = wght;
|
||||
mTangents = binorm;
|
||||
mTangents = tangent;
|
||||
|
||||
//std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
|
||||
//llinfos << result << llendl;
|
||||
|
|
@ -6306,6 +6382,43 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
|||
|
||||
cuv = (min_uv + max_uv)*0.5f;
|
||||
|
||||
|
||||
LLVector4a tangent;
|
||||
calc_tangent_from_triangle(
|
||||
*norm,
|
||||
tangent,
|
||||
*mCenter, cuv,
|
||||
pos[0], tc[0],
|
||||
pos[1], tc[1]);
|
||||
|
||||
if (tangent.getLength3() < 0.01)
|
||||
{
|
||||
tangent.set(1,0,0,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector4a default_tangent;
|
||||
default_tangent.set(1,0,0,1);
|
||||
tangent.normalize3fast_checked(&default_tangent);
|
||||
}
|
||||
|
||||
LLVector4a normal;
|
||||
LLVector4a d0, d1;
|
||||
|
||||
d0.setSub(*mCenter, pos[0]);
|
||||
d1.setSub(*mCenter, pos[1]);
|
||||
|
||||
if (mTypeMask & TOP_MASK)
|
||||
{
|
||||
normal.setCross3(d0, d1);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal.setCross3(d1, d0);
|
||||
}
|
||||
|
||||
normal.normalize3fast_checked();
|
||||
|
||||
VertexData vd;
|
||||
vd.setPosition(*mCenter);
|
||||
vd.mTexCoord = cuv;
|
||||
|
|
@ -6318,6 +6431,14 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
|||
num_vertices++;
|
||||
}
|
||||
|
||||
allocateTangents(num_vertices);
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
mTangents[i].load4a(tangent.getF32ptr());
|
||||
norm[i].load4a(normal.getF32ptr());
|
||||
}
|
||||
|
||||
if (partial_build)
|
||||
{
|
||||
return TRUE;
|
||||
|
|
@ -6553,36 +6674,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
|||
|
||||
}
|
||||
|
||||
LLVector4a d0,d1;
|
||||
|
||||
d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
|
||||
d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
|
||||
|
||||
LLVector4a normal;
|
||||
normal.setCross3(d0,d1);
|
||||
|
||||
if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
normal.normalize3fast();
|
||||
}
|
||||
else
|
||||
{ //degenerate, make up a value
|
||||
normal.set(0,0,1);
|
||||
}
|
||||
|
||||
llassert(llfinite(normal.getF32ptr()[0]));
|
||||
llassert(llfinite(normal.getF32ptr()[1]));
|
||||
llassert(llfinite(normal.getF32ptr()[2]));
|
||||
|
||||
llassert(!llisnan(normal.getF32ptr()[0]));
|
||||
llassert(!llisnan(normal.getF32ptr()[1]));
|
||||
llassert(!llisnan(normal.getF32ptr()[2]));
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
norm[i].load4a(normal.getF32ptr());
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -6611,11 +6702,13 @@ void LLVolumeFace::createTangents()
|
|||
CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
|
||||
|
||||
//normalize tangents
|
||||
LLVector4a default_norm;
|
||||
default_norm.set(0,1,0,1);
|
||||
for (U32 i = 0; i < mNumVertices; i++)
|
||||
{
|
||||
//binorm[i].normalize3fast();
|
||||
//tangent[i].normalize3fast();
|
||||
//bump map/planar projection code requires normals to be normalized
|
||||
mNormals[i].normalize3fast();
|
||||
mNormals[i].normalize3fast_checked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6800,7 +6893,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
|
|||
|
||||
//transform appended face normal and store
|
||||
norm_mat.rotate(src_norm[i], dst_norm[i]);
|
||||
dst_norm[i].normalize3fast();
|
||||
dst_norm[i].normalize3fast_checked();
|
||||
|
||||
//copy appended face texture coordinate
|
||||
dst_tc[i] = src_tc[i];
|
||||
|
|
@ -7209,11 +7302,61 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// Finds binormal based on three vertices with texture coordinates.
|
||||
// Fills in dummy values if the triangle has degenerate texture coordinates.
|
||||
void calc_binormal_from_triangle(LLVector4a& binormal,
|
||||
|
||||
const LLVector4a& pos0,
|
||||
const LLVector2& tex0,
|
||||
const LLVector4a& pos1,
|
||||
const LLVector2& tex1,
|
||||
const LLVector4a& pos2,
|
||||
const LLVector2& tex2)
|
||||
{
|
||||
LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
|
||||
LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
|
||||
LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
|
||||
|
||||
LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
|
||||
LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
|
||||
LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
|
||||
|
||||
LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
|
||||
LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
|
||||
LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
|
||||
|
||||
LLVector4a lhs, rhs;
|
||||
|
||||
LLVector4a r0;
|
||||
lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
|
||||
r0.setCross3(lhs, rhs);
|
||||
|
||||
LLVector4a r1;
|
||||
lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
|
||||
r1.setCross3(lhs, rhs);
|
||||
|
||||
LLVector4a r2;
|
||||
lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
|
||||
r2.setCross3(lhs, rhs);
|
||||
|
||||
if( r0[VX] && r1[VX] && r2[VX] )
|
||||
{
|
||||
binormal.set(
|
||||
-r0[VZ] / r0[VX],
|
||||
-r1[VZ] / r1[VX],
|
||||
-r2[VZ] / r2[VX]);
|
||||
// binormal.normVec();
|
||||
}
|
||||
else
|
||||
{
|
||||
binormal.set( 0, 1 , 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
|
||||
void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
|
||||
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
|
||||
{
|
||||
//LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
|
||||
LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
|
||||
|
||||
LLVector4a* tan2 = tan1 + vertexCount;
|
||||
|
|
|
|||
|
|
@ -545,7 +545,7 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
|
|||
{
|
||||
mMaterialUpdatePending = true;
|
||||
mMaterialID = pMaterialID;
|
||||
return TEM_CHANGE_NONE;
|
||||
return TEM_CHANGE_TEXTURE;
|
||||
}
|
||||
|
||||
mMaterialUpdatePending = false;
|
||||
|
|
|
|||
|
|
@ -647,7 +647,8 @@ bool LLGLManager::initGL()
|
|||
}
|
||||
#if LL_DARWIN
|
||||
else if ((mGLRenderer.find("9400M") != std::string::npos)
|
||||
|| (mGLRenderer.find("9600M") != std::string::npos))
|
||||
|| (mGLRenderer.find("9600M") != std::string::npos)
|
||||
|| (mGLRenderer.find("9800M") != std::string::npos))
|
||||
{
|
||||
mIsMobileGF = TRUE;
|
||||
}
|
||||
|
|
@ -1155,7 +1156,7 @@ void LLGLManager::initExtensions()
|
|||
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
|
||||
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
|
||||
|
||||
|
||||
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
|
||||
if (mHasVertexBufferObject)
|
||||
|
|
|
|||
|
|
@ -1009,12 +1009,7 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
|||
}
|
||||
#endif
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <AGL/gl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
|
||||
|
||||
|
|
|
|||
|
|
@ -374,6 +374,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
|
||||
// Create program
|
||||
mProgramObject = glCreateProgramObjectARB();
|
||||
|
||||
#if LL_DARWIN
|
||||
// work-around missing mix(vec3,vec3,bvec3)
|
||||
mDefines["OLD_SELECT"] = "1";
|
||||
#endif
|
||||
|
||||
//compile new source
|
||||
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
|
||||
|
|
|
|||
|
|
@ -1849,35 +1849,36 @@ void LLRender::flush()
|
|||
sUIVerts += mCount;
|
||||
}
|
||||
|
||||
if (gDebugGL)
|
||||
//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
|
||||
U32 count = mCount;
|
||||
|
||||
if (mMode == LLRender::QUADS && !sGLCoreProfile)
|
||||
{
|
||||
if (mMode == LLRender::QUADS && !sGLCoreProfile)
|
||||
if (mCount%4 != 0)
|
||||
{
|
||||
if (mCount%4 != 0)
|
||||
{
|
||||
llerrs << "Incomplete quad rendered." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::TRIANGLES)
|
||||
{
|
||||
if (mCount%3 != 0)
|
||||
{
|
||||
llerrs << "Incomplete triangle rendered." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::LINES)
|
||||
{
|
||||
if (mCount%2 != 0)
|
||||
{
|
||||
llerrs << "Incomplete line rendered." << llendl;
|
||||
}
|
||||
count -= (mCount % 4);
|
||||
llwarns << "Incomplete quad requested." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
|
||||
U32 count = mCount;
|
||||
if (mMode == LLRender::TRIANGLES)
|
||||
{
|
||||
if (mCount%3 != 0)
|
||||
{
|
||||
count -= (mCount % 3);
|
||||
llwarns << "Incomplete triangle requested." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::LINES)
|
||||
{
|
||||
if (mCount%2 != 0)
|
||||
{
|
||||
count -= (mCount % 2);
|
||||
llwarns << "Incomplete line requested." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
mCount = 0;
|
||||
|
||||
if (mBuffer->useVBOs() && !mBuffer->isLocked())
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ LLRenderTarget::~LLRenderTarget()
|
|||
release();
|
||||
}
|
||||
|
||||
void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
|
||||
void LLRenderTarget::resize(U32 resx, U32 resy)
|
||||
{
|
||||
//for accounting, get the number of pixels added/subtracted
|
||||
S32 pix_diff = (resx*resy)-(mResX*mResY);
|
||||
|
|
@ -87,10 +87,12 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
|
|||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
llassert(mInternalFormat.size() == mTex.size());
|
||||
|
||||
for (U32 i = 0; i < mTex.size(); ++i)
|
||||
{ //resize color attachments
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
|
||||
sBytesAllocated += pix_diff*4;
|
||||
}
|
||||
|
||||
|
|
@ -252,11 +254,14 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
mTex.push_back(tex);
|
||||
mInternalFormat.push_back(color_fmt);
|
||||
|
||||
#if !LL_DARWIN
|
||||
if (gDebugGL)
|
||||
{ //bind and unbind to validate target
|
||||
bindTarget();
|
||||
flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -359,36 +364,56 @@ void LLRenderTarget::release()
|
|||
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
}
|
||||
else if (mUseDepth && mFBO)
|
||||
{ //detach shared depth buffer
|
||||
else if (mFBO)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
mStencil = false;
|
||||
|
||||
if (mUseDepth)
|
||||
{ //detach shared depth buffer
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
mUseDepth = false;
|
||||
}
|
||||
else
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
|
||||
// Detach any extra color buffers (e.g. SRGB spec buffers)
|
||||
//
|
||||
if (mFBO && (mTex.size() > 1))
|
||||
{
|
||||
S32 z;
|
||||
for (z = mTex.size() - 1; z >= 1; z--)
|
||||
{
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
stop_glerror();
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[z], 0, 1, &mTex[z], true);
|
||||
}
|
||||
mUseDepth = false;
|
||||
}
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffers(1, (GLuint *) &mFBO);
|
||||
stop_glerror();
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
sBytesAllocated -= mResX*mResY*4*mTex.size();
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
|
||||
mTex.clear();
|
||||
mInternalFormat.clear();
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, 1, &mTex[0], true);
|
||||
}
|
||||
|
||||
|
||||
mTex.clear();
|
||||
mInternalFormat.clear();
|
||||
|
||||
mResX = mResY = 0;
|
||||
|
||||
sBoundTarget = NULL;
|
||||
|
|
@ -572,8 +597,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
|
|||
{
|
||||
if (!source.mFBO)
|
||||
{
|
||||
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public:
|
|||
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
|
||||
// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
|
||||
// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
|
||||
void resize(U32 resx, U32 resy, U32 color_fmt);
|
||||
void resize(U32 resx, U32 resy);
|
||||
|
||||
//add color buffer attachment
|
||||
//limit of 4 color attachments per render target
|
||||
|
|
|
|||
|
|
@ -1137,11 +1137,13 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("projectionMap");
|
||||
|
||||
mReservedUniforms.push_back("global_gamma");
|
||||
mReservedUniforms.push_back("texture_gamma");
|
||||
|
||||
mReservedUniforms.push_back("texture_gamma");
|
||||
|
||||
mReservedUniforms.push_back("specular_color");
|
||||
mReservedUniforms.push_back("env_intensity");
|
||||
|
||||
mReservedUniforms.push_back("display_gamma");
|
||||
|
||||
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
|
||||
|
||||
std::set<std::string> dupe_check;
|
||||
|
|
|
|||
|
|
@ -167,11 +167,13 @@ public:
|
|||
DEFERRED_PROJECTION,
|
||||
|
||||
GLOBAL_GAMMA,
|
||||
TEXTURE_GAMMA,
|
||||
|
||||
TEXTURE_GAMMA,
|
||||
|
||||
SPECULAR_COLOR,
|
||||
ENVIRONMENT_INTENSITY,
|
||||
|
||||
DISPLAY_GAMMA,
|
||||
|
||||
END_RESERVED_UNIFORMS
|
||||
} eGLSLReservedUniforms;
|
||||
|
||||
|
|
|
|||
|
|
@ -753,10 +753,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
|
|||
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
|
||||
|
||||
stop_glerror();
|
||||
LLGLSLShader::startProfile();
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
|
||||
LLGLSLShader::startProfile();
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
|
||||
idx);
|
||||
LLGLSLShader::stopProfile(count, mode);
|
||||
LLGLSLShader::stopProfile(count, mode);
|
||||
stop_glerror();
|
||||
|
||||
|
||||
|
|
@ -2236,10 +2236,41 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
|
|||
required_mask |= required;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((data_mask & required_mask) != required_mask)
|
||||
{
|
||||
llwarns << "Shader consumption mismatches data provision." << llendl;
|
||||
|
||||
U32 unsatisfied_mask = (required_mask & ~data_mask);
|
||||
U32 i = 0;
|
||||
|
||||
while (i < TYPE_MAX)
|
||||
{
|
||||
U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
|
||||
switch (unsatisfied_flag)
|
||||
{
|
||||
case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break;
|
||||
case MAP_NORMAL: llinfos << "Missing normals" << llendl; break;
|
||||
case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break;
|
||||
case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break;
|
||||
case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break;
|
||||
case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break;
|
||||
case MAP_COLOR: llinfos << "Missing vert color" << llendl; break;
|
||||
case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break;
|
||||
case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break;
|
||||
case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break;
|
||||
case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break;
|
||||
case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break;
|
||||
case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break;
|
||||
default: llinfos << "Missing who effin knows: " << unsatisfied_flag << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (unsatisfied_mask & (1 << TYPE_INDEX))
|
||||
{
|
||||
llinfos << "Missing indices" << llendl;
|
||||
}
|
||||
|
||||
llerrs << "Shader consumption mismatches data provision." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,11 +109,14 @@ if (DARWIN)
|
|||
llkeyboardmacosx.cpp
|
||||
llwindowmacosx.cpp
|
||||
llwindowmacosx-objc.mm
|
||||
llopenglview-objc.mm
|
||||
)
|
||||
list(APPEND llwindow_HEADER_FILES
|
||||
llkeyboardmacosx.h
|
||||
llwindowmacosx.h
|
||||
llwindowmacosx-objc.h
|
||||
llopenglview-objc.h
|
||||
llappdelegate-objc.h
|
||||
)
|
||||
|
||||
# We use a bunch of deprecated system APIs.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @file llappdelegate-objc.h
|
||||
* @brief Class interface for the Mac version's application delegate.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "llopenglview-objc.h"
|
||||
|
||||
@interface LLAppDelegate : NSObject <NSApplicationDelegate> {
|
||||
LLNSWindow *window;
|
||||
NSWindow *inputWindow;
|
||||
LLNonInlineTextView *inputView;
|
||||
NSTimer *frameTimer;
|
||||
NSString *currentInputLanguage;
|
||||
}
|
||||
|
||||
@property (assign) IBOutlet LLNSWindow *window;
|
||||
@property (assign) IBOutlet NSWindow *inputWindow;
|
||||
@property (assign) IBOutlet LLNonInlineTextView *inputView;
|
||||
|
||||
@property (retain) NSString *currentInputLanguage;
|
||||
|
||||
- (void) mainLoop;
|
||||
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
|
||||
- (void) languageUpdated;
|
||||
- (bool) romanScript;
|
||||
@end
|
||||
|
|
@ -82,6 +82,11 @@ public:
|
|||
|
||||
virtual BOOL handleKeyUp(const U16 key, MASK mask) = 0;
|
||||
virtual BOOL handleKeyDown(const U16 key, MASK mask) = 0;
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
// We only actually use this for OS X.
|
||||
virtual void handleModifier(MASK mask) = 0;
|
||||
#endif // LL_DARWIN
|
||||
|
||||
// Asynchronously poll the control, alt, and shift keys and set the
|
||||
// appropriate internal key masks.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,13 @@ BOOL LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask)
|
|||
MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event)
|
||||
{ return MASK_NONE; }
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
void LLKeyboardHeadless::handleModifier(MASK mask)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void LLKeyboardHeadless::scanKeyboard()
|
||||
{
|
||||
for (S32 key = 0; key < KEY_COUNT; key++)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ public:
|
|||
/*virtual*/ void resetMaskKeys();
|
||||
/*virtual*/ MASK currentMask(BOOL for_mouse_event);
|
||||
/*virtual*/ void scanKeyboard();
|
||||
#ifdef LL_DARWIN
|
||||
/*virtual*/ void handleModifier(MASK mask);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "llkeyboardmacosx.h"
|
||||
#include "llwindowcallbacks.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
LLKeyboardMacOSX::LLKeyboardMacOSX()
|
||||
{
|
||||
|
|
@ -162,23 +162,25 @@ LLKeyboardMacOSX::LLKeyboardMacOSX()
|
|||
|
||||
void LLKeyboardMacOSX::resetMaskKeys()
|
||||
{
|
||||
U32 mask = GetCurrentEventKeyModifiers();
|
||||
U32 mask = getModifiers();
|
||||
|
||||
// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
|
||||
// It looks a bit suspicious, as it won't correct for keys that have been released.
|
||||
// Is this the way it's supposed to work?
|
||||
|
||||
// We apply the modifier masks directly within getModifiers. So check to see which masks we've applied.
|
||||
|
||||
if(mask & shiftKey)
|
||||
if(mask & MAC_SHIFT_KEY)
|
||||
{
|
||||
mKeyLevel[KEY_SHIFT] = TRUE;
|
||||
}
|
||||
|
||||
if(mask & (controlKey))
|
||||
if(mask & MAC_CTRL_KEY)
|
||||
{
|
||||
mKeyLevel[KEY_CONTROL] = TRUE;
|
||||
}
|
||||
|
||||
if(mask & optionKey)
|
||||
if(mask & MAC_ALT_KEY)
|
||||
{
|
||||
mKeyLevel[KEY_ALT] = TRUE;
|
||||
}
|
||||
|
|
@ -196,22 +198,27 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out
|
|||
}
|
||||
*/
|
||||
|
||||
void LLKeyboardMacOSX::handleModifier(MASK mask)
|
||||
{
|
||||
updateModifiers(mask);
|
||||
}
|
||||
|
||||
MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
|
||||
{
|
||||
// translate the mask
|
||||
MASK out_mask = 0;
|
||||
|
||||
if(mask & shiftKey)
|
||||
if(mask & MAC_SHIFT_KEY)
|
||||
{
|
||||
out_mask |= MASK_SHIFT;
|
||||
}
|
||||
|
||||
if(mask & (controlKey | cmdKey))
|
||||
if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
|
||||
{
|
||||
out_mask |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
if(mask & optionKey)
|
||||
if(mask & MAC_ALT_KEY)
|
||||
{
|
||||
out_mask |= MASK_ALT;
|
||||
}
|
||||
|
|
@ -231,7 +238,7 @@ BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
|
|||
{
|
||||
handled = handleTranslatedKeyDown(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
@ -255,18 +262,18 @@ BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
|
|||
MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
|
||||
{
|
||||
MASK result = MASK_NONE;
|
||||
U32 mask = GetCurrentEventKeyModifiers();
|
||||
U32 mask = getModifiers();
|
||||
|
||||
if (mask & shiftKey) result |= MASK_SHIFT;
|
||||
if (mask & controlKey) result |= MASK_CONTROL;
|
||||
if (mask & optionKey) result |= MASK_ALT;
|
||||
if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT;
|
||||
if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL;
|
||||
if (mask & MAC_ALT_KEY) result |= MASK_ALT;
|
||||
|
||||
// For keyboard events, consider Command equivalent to Control
|
||||
if (!for_mouse_event)
|
||||
{
|
||||
if (mask & cmdKey) result |= MASK_CONTROL;
|
||||
if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@
|
|||
|
||||
#include "llkeyboard.h"
|
||||
|
||||
// These more or less mirror their equivalents in NSEvent.h.
|
||||
enum EMacEventKeys {
|
||||
MAC_SHIFT_KEY = 1 << 17,
|
||||
MAC_CTRL_KEY = 1 << 18,
|
||||
MAC_ALT_KEY = 1 << 19,
|
||||
MAC_CMD_KEY = 1 << 20,
|
||||
MAC_FN_KEY = 1 << 23
|
||||
};
|
||||
|
||||
class LLKeyboardMacOSX : public LLKeyboard
|
||||
{
|
||||
public:
|
||||
|
|
@ -40,6 +49,7 @@ public:
|
|||
/*virtual*/ void resetMaskKeys();
|
||||
/*virtual*/ MASK currentMask(BOOL for_mouse_event);
|
||||
/*virtual*/ void scanKeyboard();
|
||||
/*virtual*/ void handleModifier(MASK mask);
|
||||
|
||||
protected:
|
||||
MASK updateModifiers(const U32 mask);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* @file llopenglview-objc.h
|
||||
* @brief Class interfaces for most of the Mac facing window functionality.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LLOpenGLView_H
|
||||
#define LLOpenGLView_H
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <IOKit/IOKitLib.h>
|
||||
#import <CoreFoundation/CFBase.h>
|
||||
#import <CoreFoundation/CFNumber.h>
|
||||
#include <string>
|
||||
|
||||
@interface LLOpenGLView : NSOpenGLView <NSTextInputClient>
|
||||
{
|
||||
std::string mLastDraggedUrl;
|
||||
unsigned int mModifiers;
|
||||
float mMousePos[2];
|
||||
bool mHasMarkedText;
|
||||
unsigned int mMarkedTextLength;
|
||||
bool mMarkedTextAllowed;
|
||||
bool mSimulatedRightClick;
|
||||
}
|
||||
- (id) initWithSamples:(NSUInteger)samples;
|
||||
- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
|
||||
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
|
||||
|
||||
- (void)commitCurrentPreedit;
|
||||
|
||||
// rebuildContext
|
||||
// Destroys and recreates a context with the view's internal format set via setPixelFormat;
|
||||
// Use this in event of needing to rebuild a context for whatever reason, without needing to assign a new pixel format.
|
||||
- (BOOL) rebuildContext;
|
||||
|
||||
// rebuildContextWithFormat
|
||||
// Destroys and recreates a context with the specified pixel format.
|
||||
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format;
|
||||
|
||||
// These are mostly just for C++ <-> Obj-C interop. We can manipulate the CGLContext from C++ without reprecussions.
|
||||
- (CGLContextObj) getCGLContextObj;
|
||||
- (CGLPixelFormatObj*)getCGLPixelFormatObj;
|
||||
|
||||
- (unsigned long) getVramSize;
|
||||
|
||||
- (void) allowMarkedTextInput:(bool)allowed;
|
||||
|
||||
@end
|
||||
|
||||
@interface LLUserInputWindow : NSPanel
|
||||
|
||||
@end
|
||||
|
||||
@interface LLNonInlineTextView : NSTextView
|
||||
{
|
||||
LLOpenGLView *glview;
|
||||
}
|
||||
|
||||
- (void) setGLView:(LLOpenGLView*)view;
|
||||
|
||||
@end
|
||||
|
||||
@interface LLNSWindow : NSWindow
|
||||
|
||||
- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
|
||||
- (NSPoint)flipPoint:(NSPoint)aPoint;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSScreen (PointConversion)
|
||||
|
||||
/*
|
||||
Returns the screen where the mouse resides
|
||||
*/
|
||||
+ (NSScreen *)currentScreenForMouseLocation;
|
||||
|
||||
/*
|
||||
Allows you to convert a point from global coordinates to the current screen coordinates.
|
||||
*/
|
||||
- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint;
|
||||
|
||||
/*
|
||||
Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same
|
||||
*/
|
||||
- (NSPoint)flipPoint:(NSPoint)aPoint;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,686 @@
|
|||
/**
|
||||
* @file llopenglview-objc.mm
|
||||
* @brief Class implementation for most of the Mac facing window functionality.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#import "llopenglview-objc.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#import "llappdelegate-objc.h"
|
||||
|
||||
@implementation NSScreen (PointConversion)
|
||||
|
||||
+ (NSScreen *)currentScreenForMouseLocation
|
||||
{
|
||||
NSPoint mouseLocation = [NSEvent mouseLocation];
|
||||
|
||||
NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
|
||||
NSScreen *screen;
|
||||
while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO))
|
||||
;
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
|
||||
{
|
||||
float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
|
||||
float normalizedY = aPoint.y - self.frame.origin.y;
|
||||
|
||||
return NSMakePoint(normalizedX, normalizedY);
|
||||
}
|
||||
|
||||
- (NSPoint)flipPoint:(NSPoint)aPoint
|
||||
{
|
||||
return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
attributedStringInfo getSegments(NSAttributedString *str)
|
||||
{
|
||||
attributedStringInfo segments;
|
||||
segment_lengths seg_lengths;
|
||||
segment_standouts seg_standouts;
|
||||
NSRange effectiveRange;
|
||||
NSRange limitRange = NSMakeRange(0, [str length]);
|
||||
|
||||
while (limitRange.length > 0) {
|
||||
NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
|
||||
limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
|
||||
|
||||
if (effectiveRange.length <= 0)
|
||||
{
|
||||
effectiveRange.length = 1;
|
||||
}
|
||||
|
||||
if ([attr integerValue] == 2)
|
||||
{
|
||||
seg_lengths.push_back(effectiveRange.length);
|
||||
seg_standouts.push_back(true);
|
||||
} else
|
||||
{
|
||||
seg_lengths.push_back(effectiveRange.length);
|
||||
seg_standouts.push_back(false);
|
||||
}
|
||||
}
|
||||
segments.seg_lengths = seg_lengths;
|
||||
segments.seg_standouts = seg_standouts;
|
||||
return segments;
|
||||
}
|
||||
|
||||
@implementation LLOpenGLView
|
||||
|
||||
- (unsigned long)getVramSize
|
||||
{
|
||||
CGLRendererInfoObj info = 0;
|
||||
GLint vram_bytes = 0;
|
||||
int num_renderers = 0;
|
||||
CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
|
||||
if(0 == the_err)
|
||||
{
|
||||
CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes);
|
||||
CGLDestroyRendererInfo (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
vram_bytes = (256 << 20);
|
||||
}
|
||||
|
||||
return (unsigned long)vram_bytes / 1048576; // We need this in megabytes.
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowResized:) name:NSWindowDidResizeNotification
|
||||
object:[self window]];
|
||||
}
|
||||
|
||||
- (void)windowResized:(NSNotification *)notification;
|
||||
{
|
||||
NSSize size = [self frame].size;
|
||||
|
||||
callResize(size.width, size.height);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
|
||||
}
|
||||
|
||||
- (id) initWithSamples:(NSUInteger)samples
|
||||
{
|
||||
return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
|
||||
}
|
||||
|
||||
- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync
|
||||
{
|
||||
return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
|
||||
{
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
|
||||
[self initWithFrame:frame];
|
||||
|
||||
// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
|
||||
// Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
|
||||
// 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons).
|
||||
NSOpenGLPixelFormatAttribute attrs[] = {
|
||||
NSOpenGLPFANoRecovery,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAClosestPolicy,
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFASampleBuffers, (samples > 0 ? 1 : 0),
|
||||
NSOpenGLPFASamples, samples,
|
||||
NSOpenGLPFAStencilSize, 8,
|
||||
NSOpenGLPFADepthSize, 24,
|
||||
NSOpenGLPFAAlphaSize, 8,
|
||||
NSOpenGLPFAColorSize, 24,
|
||||
0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
|
||||
|
||||
if (pixelFormat == nil)
|
||||
{
|
||||
NSLog(@"Failed to create pixel format!", nil);
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
|
||||
|
||||
if (glContext == nil)
|
||||
{
|
||||
NSLog(@"Failed to create OpenGL context!", nil);
|
||||
return nil;
|
||||
}
|
||||
|
||||
[self setPixelFormat:pixelFormat];
|
||||
|
||||
[self setOpenGLContext:glContext];
|
||||
|
||||
[glContext setView:self];
|
||||
|
||||
[glContext makeCurrentContext];
|
||||
|
||||
if (vsync)
|
||||
{
|
||||
[glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
|
||||
} else {
|
||||
[glContext setValues:(const GLint*)0 forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) rebuildContext
|
||||
{
|
||||
return [self rebuildContextWithFormat:[self pixelFormat]];
|
||||
}
|
||||
|
||||
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format
|
||||
{
|
||||
NSOpenGLContext *ctx = [self openGLContext];
|
||||
|
||||
[ctx clearDrawable];
|
||||
[ctx initWithFormat:format shareContext:nil];
|
||||
|
||||
if (ctx == nil)
|
||||
{
|
||||
NSLog(@"Failed to create OpenGL context!", nil);
|
||||
return false;
|
||||
}
|
||||
|
||||
[self setOpenGLContext:ctx];
|
||||
[ctx setView:self];
|
||||
[ctx makeCurrentContext];
|
||||
return true;
|
||||
}
|
||||
|
||||
- (CGLContextObj)getCGLContextObj
|
||||
{
|
||||
NSOpenGLContext *ctx = [self openGLContext];
|
||||
return (CGLContextObj)[ctx CGLContextObj];
|
||||
}
|
||||
|
||||
- (CGLPixelFormatObj*)getCGLPixelFormatObj
|
||||
{
|
||||
NSOpenGLPixelFormat *fmt = [self pixelFormat];
|
||||
return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj];
|
||||
}
|
||||
|
||||
// Various events can be intercepted by our view, thus not reaching our window.
|
||||
// Intercept these events, and pass them to the window as needed. - Geenz
|
||||
|
||||
- (void) mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
// Apparently people still use this?
|
||||
if ([theEvent modifierFlags] & NSCommandKeyMask &&
|
||||
!([theEvent modifierFlags] & NSControlKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSShiftKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSAlternateKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSAlphaShiftKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSFunctionKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSHelpKeyMask))
|
||||
{
|
||||
callRightMouseDown(mMousePos, mModifiers);
|
||||
mSimulatedRightClick = true;
|
||||
} else {
|
||||
if ([theEvent clickCount] >= 2)
|
||||
{
|
||||
callDoubleClick(mMousePos, mModifiers);
|
||||
} else if ([theEvent clickCount] == 1) {
|
||||
callLeftMouseDown(mMousePos, mModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
if (mSimulatedRightClick)
|
||||
{
|
||||
callRightMouseUp(mMousePos, mModifiers);
|
||||
mSimulatedRightClick = false;
|
||||
} else {
|
||||
callLeftMouseUp(mMousePos, mModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) rightMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
callRightMouseDown(mMousePos, mModifiers);
|
||||
}
|
||||
|
||||
- (void) rightMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
callRightMouseUp(mMousePos, mModifiers);
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
float mouseDeltas[2] = {
|
||||
[theEvent deltaX],
|
||||
[theEvent deltaY]
|
||||
};
|
||||
|
||||
callDeltaUpdate(mouseDeltas, 0);
|
||||
|
||||
NSPoint mPoint = [theEvent locationInWindow];
|
||||
mMousePos[0] = mPoint.x;
|
||||
mMousePos[1] = mPoint.y;
|
||||
callMouseMoved(mMousePos, 0);
|
||||
}
|
||||
|
||||
// NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
|
||||
// Use mouseDragged for situations like this to trigger our movement callback instead.
|
||||
|
||||
- (void) mouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
// Trust the deltas supplied by NSEvent.
|
||||
// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
|
||||
// NSEvent isn't obsolete, and provides us with the correct deltas.
|
||||
float mouseDeltas[2] = {
|
||||
[theEvent deltaX],
|
||||
[theEvent deltaY]
|
||||
};
|
||||
|
||||
callDeltaUpdate(mouseDeltas, 0);
|
||||
|
||||
NSPoint mPoint = [theEvent locationInWindow];
|
||||
mMousePos[0] = mPoint.x;
|
||||
mMousePos[1] = mPoint.y;
|
||||
callMouseMoved(mMousePos, 0);
|
||||
}
|
||||
|
||||
- (void) otherMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
callMiddleMouseDown(mMousePos, mModifiers);
|
||||
}
|
||||
|
||||
- (void) otherMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
callMiddleMouseUp(mMousePos, mModifiers);
|
||||
}
|
||||
|
||||
- (void) otherMouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void) scrollWheel:(NSEvent *)theEvent
|
||||
{
|
||||
callScrollMoved(-[theEvent deltaY]);
|
||||
}
|
||||
|
||||
- (void) mouseExited:(NSEvent *)theEvent
|
||||
{
|
||||
callMouseExit();
|
||||
}
|
||||
|
||||
- (void) keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
callKeyUp([theEvent keyCode], mModifiers);
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
uint keycode = [theEvent keyCode];
|
||||
bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers);
|
||||
if (acceptsText &&
|
||||
!mMarkedTextAllowed &&
|
||||
![(LLAppDelegate*)[NSApp delegate] romanScript] &&
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter &&
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey &&
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey &&
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey &&
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey)
|
||||
{
|
||||
[(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
|
||||
} else
|
||||
{
|
||||
[[self inputContext] handleEvent:theEvent];
|
||||
}
|
||||
|
||||
if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
|
||||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
|
||||
{
|
||||
// callKeyDown won't return the value we expect for enter or return. Handle them as a separate case.
|
||||
[[self inputContext] handleEvent:theEvent];
|
||||
}
|
||||
|
||||
// OS X intentionally does not send us key-up information on cmd-key combinations.
|
||||
// This behaviour is not a bug, and only applies to cmd-combinations (no others).
|
||||
// Since SL assumes we receive those, we fake it here.
|
||||
if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
|
||||
{
|
||||
callKeyUp([theEvent keyCode], mModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent *)theEvent {
|
||||
mModifiers = [theEvent modifierFlags];
|
||||
callModifier([theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (BOOL) acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard *pboard;
|
||||
NSDragOperation sourceDragMask;
|
||||
|
||||
sourceDragMask = [sender draggingSourceOperationMask];
|
||||
|
||||
pboard = [sender draggingPasteboard];
|
||||
|
||||
if ([[pboard types] containsObject:NSURLPboardType])
|
||||
{
|
||||
if (sourceDragMask & NSDragOperationLink) {
|
||||
NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
|
||||
mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
|
||||
return NSDragOperationLink;
|
||||
}
|
||||
}
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
callHandleDragUpdated(mLastDraggedUrl);
|
||||
|
||||
return NSDragOperationLink;
|
||||
}
|
||||
|
||||
- (void) draggingExited:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
callHandleDragExited(mLastDraggedUrl);
|
||||
}
|
||||
|
||||
- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
|
||||
{
|
||||
callHandleDragDropped(mLastDraggedUrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
return mHasMarkedText;
|
||||
}
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
int range[2];
|
||||
getPreeditMarkedRange(&range[0], &range[1]);
|
||||
return NSMakeRange(range[0], range[1]);
|
||||
}
|
||||
|
||||
- (NSRange)selectedRange
|
||||
{
|
||||
int range[2];
|
||||
getPreeditSelectionRange(&range[0], &range[1]);
|
||||
return NSMakeRange(range[0], range[1]);
|
||||
}
|
||||
|
||||
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
|
||||
{
|
||||
if (mMarkedTextAllowed)
|
||||
{
|
||||
unsigned int selected[2] = {
|
||||
selectedRange.location,
|
||||
selectedRange.length
|
||||
};
|
||||
|
||||
unsigned int replacement[2] = {
|
||||
replacementRange.location,
|
||||
replacementRange.length
|
||||
};
|
||||
|
||||
unichar text[[aString length]];
|
||||
[[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
|
||||
attributedStringInfo segments = getSegments((NSAttributedString *)aString);
|
||||
setMarkedText(text, selected, replacement, [aString length], segments);
|
||||
mHasMarkedText = TRUE;
|
||||
mMarkedTextLength = [aString length];
|
||||
} else {
|
||||
if (mHasMarkedText)
|
||||
{
|
||||
[self unmarkText];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)commitCurrentPreedit
|
||||
{
|
||||
if (mHasMarkedText)
|
||||
{
|
||||
if ([[self inputContext] respondsToSelector:@selector(commitEditing)])
|
||||
{
|
||||
[[self inputContext] commitEditing];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
[[self inputContext] discardMarkedText];
|
||||
resetPreedit();
|
||||
mHasMarkedText = FALSE;
|
||||
}
|
||||
|
||||
// We don't support attributed strings.
|
||||
- (NSArray *)validAttributesForMarkedText
|
||||
{
|
||||
return [NSArray array];
|
||||
}
|
||||
|
||||
// See above.
|
||||
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)insertText:(id)insertString
|
||||
{
|
||||
if (insertString != nil)
|
||||
{
|
||||
[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
if (!mHasMarkedText)
|
||||
{
|
||||
for (NSInteger i = 0; i < [aString length]; i++)
|
||||
{
|
||||
callUnicodeCallback([aString characterAtIndex:i], mModifiers);
|
||||
}
|
||||
} else {
|
||||
resetPreedit();
|
||||
// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
|
||||
// But just in case...
|
||||
|
||||
for (NSInteger i = 0; i < [aString length]; i++)
|
||||
{
|
||||
handleUnicodeCharacter([aString characterAtIndex:i]);
|
||||
}
|
||||
mHasMarkedText = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) insertNewline:(id)sender
|
||||
{
|
||||
if (!(mModifiers & NSCommandKeyMask) &&
|
||||
!(mModifiers & NSShiftKeyMask) &&
|
||||
!(mModifiers & NSAlternateKeyMask))
|
||||
{
|
||||
callUnicodeCallback(13, 0);
|
||||
} else {
|
||||
callUnicodeCallback(13, mModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
|
||||
{
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||
{
|
||||
float pos[4] = {0, 0, 0, 0};
|
||||
getPreeditLocation(pos, mMarkedTextLength);
|
||||
return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)aSelector
|
||||
{
|
||||
if (aSelector == @selector(insertNewline:))
|
||||
{
|
||||
[self insertNewline:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) allowMarkedTextInput:(bool)allowed
|
||||
{
|
||||
mMarkedTextAllowed = allowed;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation LLUserInputWindow
|
||||
|
||||
- (void) close
|
||||
{
|
||||
[self orderOut:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation LLNonInlineTextView
|
||||
|
||||
- (void) setGLView:(LLOpenGLView *)view
|
||||
{
|
||||
glview = view;
|
||||
}
|
||||
|
||||
- (void) insertText:(id)insertString
|
||||
{
|
||||
[[self inputContext] discardMarkedText];
|
||||
[self setString:@""];
|
||||
[_window orderOut:_window];
|
||||
[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
|
||||
}
|
||||
|
||||
- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
[glview insertText:aString replacementRange:replacementRange];
|
||||
}
|
||||
|
||||
- (void) insertNewline:(id)sender
|
||||
{
|
||||
[[self textStorage] setValue:@""];
|
||||
[[self inputContext] discardMarkedText];
|
||||
[self setString:@""];
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)aSelector
|
||||
{
|
||||
if (aSelector == @selector(insertNewline:))
|
||||
{
|
||||
[self insertNewline:self];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation LLNSWindow
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
|
||||
{
|
||||
NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
|
||||
if(currentScreen)
|
||||
{
|
||||
NSPoint windowPoint = [view convertPoint:point toView:nil];
|
||||
NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
|
||||
NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint];
|
||||
flippedScreenPoint.y += [currentScreen frame].origin.y;
|
||||
|
||||
return flippedScreenPoint;
|
||||
}
|
||||
|
||||
return NSZeroPoint;
|
||||
}
|
||||
|
||||
- (NSPoint)flipPoint:(NSPoint)aPoint
|
||||
{
|
||||
return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
|
||||
}
|
||||
|
||||
- (BOOL) becomeFirstResponder
|
||||
{
|
||||
callFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
- (BOOL) resignFirstResponder
|
||||
{
|
||||
callFocusLost();
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void) close
|
||||
{
|
||||
callQuitHandler();
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -25,13 +25,121 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
typedef std::vector<std::pair<int, bool> > segment_t;
|
||||
|
||||
typedef std::vector<int> segment_lengths;
|
||||
typedef std::vector<int> segment_standouts;
|
||||
|
||||
struct attributedStringInfo {
|
||||
segment_lengths seg_lengths;
|
||||
segment_standouts seg_standouts;
|
||||
};
|
||||
|
||||
// This will actually hold an NSCursor*, but that type is only available in objective C.
|
||||
typedef void *CursorRef;
|
||||
typedef void *NSWindowRef;
|
||||
typedef void *GLViewRef;
|
||||
|
||||
// These are defined in llappviewermacosx.cpp.
|
||||
bool initViewer();
|
||||
void handleQuit();
|
||||
bool runMainLoop();
|
||||
void initMainLoop();
|
||||
void cleanupViewer();
|
||||
|
||||
/* Defined in llwindowmacosx-objc.mm: */
|
||||
int createNSApp(int argc, const char **argv);
|
||||
void setupCocoa();
|
||||
bool pasteBoardAvailable();
|
||||
bool copyToPBoard(const unsigned short *str, unsigned int len);
|
||||
const unsigned short *copyFromPBoard();
|
||||
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
|
||||
OSErr releaseImageCursor(CursorRef ref);
|
||||
OSErr setImageCursor(CursorRef ref);
|
||||
short releaseImageCursor(CursorRef ref);
|
||||
short setImageCursor(CursorRef ref);
|
||||
void setArrowCursor();
|
||||
void setIBeamCursor();
|
||||
void setPointingHandCursor();
|
||||
void setCopyCursor();
|
||||
void setCrossCursor();
|
||||
void setNotAllowedCursor();
|
||||
void hideNSCursor();
|
||||
void showNSCursor();
|
||||
void hideNSCursorTillMove(bool hide);
|
||||
void requestUserAttention();
|
||||
long showAlert(std::string title, std::string text, int type);
|
||||
|
||||
NSWindowRef createNSWindow(int x, int y, int width, int height);
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
|
||||
void glSwapBuffers(void* context);
|
||||
CGLContextObj getCGLContextObj(GLViewRef view);
|
||||
unsigned long getVramSize(GLViewRef view);
|
||||
void getContentViewBounds(NSWindowRef window, float* bounds);
|
||||
void getWindowSize(NSWindowRef window, float* size);
|
||||
void setWindowSize(NSWindowRef window, int width, int height);
|
||||
void getCursorPos(NSWindowRef window, float* pos);
|
||||
void makeWindowOrderFront(NSWindowRef window);
|
||||
void convertScreenToWindow(NSWindowRef window, float *coord);
|
||||
void convertWindowToScreen(NSWindowRef window, float *coord);
|
||||
void convertScreenToView(NSWindowRef window, float *coord);
|
||||
void convertRectToScreen(NSWindowRef window, float *coord);
|
||||
void convertRectFromScreen(NSWindowRef window, float *coord);
|
||||
void setWindowPos(NSWindowRef window, float* pos);
|
||||
void closeWindow(NSWindowRef window);
|
||||
void removeGLView(GLViewRef view);
|
||||
void makeFirstResponder(NSWindowRef window, GLViewRef view);
|
||||
void setupInputWindow(NSWindowRef window, GLViewRef view);
|
||||
|
||||
// These are all implemented in llwindowmacosx.cpp.
|
||||
// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
|
||||
bool callKeyUp(unsigned short key, unsigned int mask);
|
||||
bool callKeyDown(unsigned short key, unsigned int mask);
|
||||
void callResetKeys();
|
||||
bool callUnicodeCallback(wchar_t character, unsigned int mask);
|
||||
void callRightMouseDown(float *pos, unsigned int mask);
|
||||
void callRightMouseUp(float *pos, unsigned int mask);
|
||||
void callLeftMouseDown(float *pos, unsigned int mask);
|
||||
void callLeftMouseUp(float *pos, unsigned int mask);
|
||||
void callDoubleClick(float *pos, unsigned int mask);
|
||||
void callResize(unsigned int width, unsigned int height);
|
||||
void callMouseMoved(float *pos, unsigned int mask);
|
||||
void callScrollMoved(float delta);
|
||||
void callMouseExit();
|
||||
void callWindowFocus();
|
||||
void callWindowUnfocus();
|
||||
void callDeltaUpdate(float *delta, unsigned int mask);
|
||||
void callMiddleMouseDown(float *pos, unsigned int mask);
|
||||
void callMiddleMouseUp(float *pos, unsigned int mask);
|
||||
void callFocus();
|
||||
void callFocusLost();
|
||||
void callModifier(unsigned int mask);
|
||||
void callQuitHandler();
|
||||
void commitCurrentPreedit(GLViewRef glView);
|
||||
|
||||
#include <string>
|
||||
void callHandleDragEntered(std::string url);
|
||||
void callHandleDragExited(std::string url);
|
||||
void callHandleDragUpdated(std::string url);
|
||||
void callHandleDragDropped(std::string url);
|
||||
|
||||
// LLPreeditor C bindings.
|
||||
std::basic_string<wchar_t> getPreeditString();
|
||||
void getPreeditSelectionRange(int *position, int *length);
|
||||
void getPreeditMarkedRange(int *position, int *length);
|
||||
bool handleUnicodeCharacter(wchar_t c);
|
||||
void updatePreeditor(unsigned short *str);
|
||||
void setPreeditMarkedRange(int position, int length);
|
||||
void resetPreedit();
|
||||
int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
|
||||
void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
|
||||
void getPreeditLocation(float *location, unsigned int length);
|
||||
void allowDirectMarkedTextInput(bool allow, GLViewRef glView);
|
||||
|
||||
NSWindowRef getMainAppWindow();
|
||||
GLViewRef getGLView();
|
||||
|
||||
unsigned int getModifiers();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file llwindowmacosx-objc.mm
|
||||
* @brief Definition of functions shared between llwindowmacosx.cpp
|
||||
* and llwindowmacosx-objc.mm.
|
||||
|
|
@ -6,26 +6,30 @@
|
|||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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 <AppKit/AppKit.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include "llopenglview-objc.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#include "llappdelegate-objc.h"
|
||||
|
||||
/*
|
||||
* These functions are broken out into a separate file because the
|
||||
|
|
@ -34,7 +38,10 @@
|
|||
* linden headers with any objective-C++ source.
|
||||
*/
|
||||
|
||||
#include "llwindowmacosx-objc.h"
|
||||
int createNSApp(int argc, const char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
|
||||
void setupCocoa()
|
||||
{
|
||||
|
|
@ -45,44 +52,122 @@ void setupCocoa()
|
|||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
|
||||
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
|
||||
// when init'ing the Cocoa App window.
|
||||
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
|
||||
// when init'ing the Cocoa App window.
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||
|
||||
// This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
|
||||
// http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
|
||||
|
||||
// Needed for Carbon based applications which call into Cocoa
|
||||
NSApplicationLoad();
|
||||
|
||||
// Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
|
||||
[[[NSWindow alloc] init] release];
|
||||
|
||||
[pool release];
|
||||
|
||||
inited = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool copyToPBoard(const unsigned short *str, unsigned int len)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
|
||||
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
|
||||
[pboard clearContents];
|
||||
|
||||
NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
|
||||
[pool release];
|
||||
return [pboard writeObjects:contentsToPaste];
|
||||
}
|
||||
|
||||
bool pasteBoardAvailable()
|
||||
{
|
||||
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
|
||||
return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
|
||||
}
|
||||
|
||||
const unsigned short *copyFromPBoard()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
|
||||
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
|
||||
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
|
||||
NSString *str = NULL;
|
||||
BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
|
||||
if (ok)
|
||||
{
|
||||
NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
|
||||
str = [objToPaste objectAtIndex:0];
|
||||
}
|
||||
unichar* temp = (unichar*)calloc([str length], sizeof(unichar));
|
||||
[str getCharacters:temp];
|
||||
[pool release];
|
||||
return temp;
|
||||
}
|
||||
|
||||
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
|
||||
NSCursor *cursor =
|
||||
[[[NSCursor alloc]
|
||||
initWithImage:
|
||||
[[[NSImage alloc] initWithContentsOfFile:
|
||||
[NSString stringWithFormat:@"%s", fullpath]
|
||||
]autorelease]
|
||||
hotSpot:NSMakePoint(hotspotX, hotspotY)
|
||||
]retain];
|
||||
|
||||
[[[NSCursor alloc]
|
||||
initWithImage:
|
||||
[[[NSImage alloc] initWithContentsOfFile:
|
||||
[NSString stringWithFormat:@"%s", fullpath]
|
||||
]autorelease]
|
||||
hotSpot:NSMakePoint(hotspotX, hotspotY)
|
||||
]retain];
|
||||
|
||||
[pool release];
|
||||
|
||||
return (CursorRef)cursor;
|
||||
}
|
||||
|
||||
void setArrowCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor arrowCursor];
|
||||
[NSCursor unhide];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setIBeamCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor IBeamCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setPointingHandCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor pointingHandCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setCopyCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor dragCopyCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setCrossCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor crosshairCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void setNotAllowedCursor()
|
||||
{
|
||||
NSCursor *cursor = [NSCursor operationNotAllowedCursor];
|
||||
[cursor set];
|
||||
}
|
||||
|
||||
void hideNSCursor()
|
||||
{
|
||||
[NSCursor hide];
|
||||
}
|
||||
|
||||
void showNSCursor()
|
||||
{
|
||||
[NSCursor unhide];
|
||||
}
|
||||
|
||||
void hideNSCursorTillMove(bool hide)
|
||||
{
|
||||
[NSCursor setHiddenUntilMouseMoves:hide];
|
||||
}
|
||||
|
||||
// This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness.
|
||||
OSErr releaseImageCursor(CursorRef ref)
|
||||
{
|
||||
|
|
@ -118,3 +203,250 @@ OSErr setImageCursor(CursorRef ref)
|
|||
return noErr;
|
||||
}
|
||||
|
||||
// Now for some unholy juggling between generic pointers and casting them to Obj-C objects!
|
||||
// Note: things can get a bit hairy from here. This is not for the faint of heart.
|
||||
|
||||
NSWindowRef createNSWindow(int x, int y, int width, int height)
|
||||
{
|
||||
LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
|
||||
styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
[window setAcceptsMouseMovedEvents:TRUE];
|
||||
return window;
|
||||
}
|
||||
|
||||
GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
|
||||
{
|
||||
LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
|
||||
[(LLNSWindow*)window setContentView:glview];
|
||||
return glview;
|
||||
}
|
||||
|
||||
void glSwapBuffers(void* context)
|
||||
{
|
||||
[(NSOpenGLContext*)context flushBuffer];
|
||||
}
|
||||
|
||||
CGLContextObj getCGLContextObj(GLViewRef view)
|
||||
{
|
||||
return [(LLOpenGLView *)view getCGLContextObj];
|
||||
}
|
||||
|
||||
CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
|
||||
{
|
||||
LLOpenGLView *glview = [(LLNSWindow*)window contentView];
|
||||
return [glview getCGLPixelFormatObj];
|
||||
}
|
||||
|
||||
unsigned long getVramSize(GLViewRef view)
|
||||
{
|
||||
return [(LLOpenGLView *)view getVramSize];
|
||||
}
|
||||
|
||||
void getContentViewBounds(NSWindowRef window, float* bounds)
|
||||
{
|
||||
bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
|
||||
bounds[1] = [[(LLNSWindow*)window contentView] bounds].origin.y;
|
||||
bounds[2] = [[(LLNSWindow*)window contentView] bounds].size.width;
|
||||
bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
|
||||
}
|
||||
|
||||
void getWindowSize(NSWindowRef window, float* size)
|
||||
{
|
||||
NSRect frame = [(LLNSWindow*)window frame];
|
||||
size[0] = frame.origin.x;
|
||||
size[1] = frame.origin.y;
|
||||
size[2] = frame.size.width;
|
||||
size[3] = frame.size.height;
|
||||
}
|
||||
|
||||
void setWindowSize(NSWindowRef window, int width, int height)
|
||||
{
|
||||
NSRect frame = [(LLNSWindow*)window frame];
|
||||
frame.size.width = width;
|
||||
frame.size.height = height;
|
||||
[(LLNSWindow*)window setFrame:frame display:TRUE];
|
||||
}
|
||||
|
||||
void setWindowPos(NSWindowRef window, float* pos)
|
||||
{
|
||||
NSPoint point;
|
||||
point.x = pos[0];
|
||||
point.y = pos[1];
|
||||
[(LLNSWindow*)window setFrameOrigin:point];
|
||||
}
|
||||
|
||||
void getCursorPos(NSWindowRef window, float* pos)
|
||||
{
|
||||
NSPoint mLoc;
|
||||
mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
|
||||
pos[0] = mLoc.x;
|
||||
pos[1] = mLoc.y;
|
||||
}
|
||||
|
||||
void makeWindowOrderFront(NSWindowRef window)
|
||||
{
|
||||
[(LLNSWindow*)window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
void convertScreenToWindow(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSRect point;
|
||||
point.origin.x = coord[0];
|
||||
point.origin.y = coord[1];
|
||||
point = [(LLNSWindow*)window convertRectFromScreen:point];
|
||||
coord[0] = point.origin.x;
|
||||
coord[1] = point.origin.y;
|
||||
}
|
||||
|
||||
void convertRectToScreen(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSRect point;
|
||||
point.origin.x = coord[0];
|
||||
point.origin.y = coord[1];
|
||||
point.size.width = coord[2];
|
||||
point.size.height = coord[3];
|
||||
|
||||
point = [(LLNSWindow*)window convertRectToScreen:point];
|
||||
|
||||
coord[0] = point.origin.x;
|
||||
coord[1] = point.origin.y;
|
||||
coord[2] = point.size.width;
|
||||
coord[3] = point.size.height;
|
||||
}
|
||||
|
||||
void convertRectFromScreen(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSRect point;
|
||||
point.origin.x = coord[0];
|
||||
point.origin.y = coord[1];
|
||||
point.size.width = coord[2];
|
||||
point.size.height = coord[3];
|
||||
|
||||
point = [(LLNSWindow*)window convertRectFromScreen:point];
|
||||
|
||||
coord[0] = point.origin.x;
|
||||
coord[1] = point.origin.y;
|
||||
coord[2] = point.size.width;
|
||||
coord[3] = point.size.height;
|
||||
}
|
||||
|
||||
void convertScreenToView(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSRect point;
|
||||
point.origin.x = coord[0];
|
||||
point.origin.y = coord[1];
|
||||
point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin];
|
||||
point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil];
|
||||
}
|
||||
|
||||
void convertWindowToScreen(NSWindowRef window, float *coord)
|
||||
{
|
||||
NSPoint point;
|
||||
point.x = coord[0];
|
||||
point.y = coord[1];
|
||||
point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]];
|
||||
coord[0] = point.x;
|
||||
coord[1] = point.y;
|
||||
}
|
||||
|
||||
void closeWindow(NSWindowRef window)
|
||||
{
|
||||
[(LLNSWindow*)window close];
|
||||
[(LLNSWindow*)window release];
|
||||
}
|
||||
|
||||
void removeGLView(GLViewRef view)
|
||||
{
|
||||
[(LLOpenGLView*)view removeFromSuperview];
|
||||
[(LLOpenGLView*)view release];
|
||||
}
|
||||
|
||||
void setupInputWindow(NSWindowRef window, GLViewRef glview)
|
||||
{
|
||||
[[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
|
||||
}
|
||||
|
||||
void commitCurrentPreedit(GLViewRef glView)
|
||||
{
|
||||
[(LLOpenGLView*)glView commitCurrentPreedit];
|
||||
}
|
||||
|
||||
void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
|
||||
{
|
||||
[(LLOpenGLView*)glView allowMarkedTextInput:allow];
|
||||
}
|
||||
|
||||
NSWindowRef getMainAppWindow()
|
||||
{
|
||||
LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
|
||||
|
||||
[winRef setAcceptsMouseMovedEvents:TRUE];
|
||||
return winRef;
|
||||
}
|
||||
|
||||
void makeFirstResponder(NSWindowRef window, GLViewRef view)
|
||||
{
|
||||
[(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
|
||||
}
|
||||
|
||||
void requestUserAttention()
|
||||
{
|
||||
[[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
|
||||
}
|
||||
|
||||
long showAlert(std::string text, std::string title, int type)
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
|
||||
[alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
|
||||
[alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
|
||||
if (type == 0)
|
||||
{
|
||||
[alert addButtonWithTitle:@"Okay"];
|
||||
} else if (type == 1)
|
||||
{
|
||||
[alert addButtonWithTitle:@"Okay"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
} else if (type == 2)
|
||||
{
|
||||
[alert addButtonWithTitle:@"Yes"];
|
||||
[alert addButtonWithTitle:@"No"];
|
||||
}
|
||||
long ret = [alert runModal];
|
||||
[alert dealloc];
|
||||
|
||||
if (ret == NSAlertFirstButtonReturn)
|
||||
{
|
||||
if (type == 1)
|
||||
{
|
||||
ret = 3;
|
||||
} else if (type == 2)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
} else if (ret == NSAlertSecondButtonReturn)
|
||||
{
|
||||
if (type == 0 || type == 1)
|
||||
{
|
||||
ret = 2;
|
||||
} else if (type == 2)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
GLViewRef getGLView()
|
||||
{
|
||||
return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned int getModifiers()
|
||||
{
|
||||
return [NSEvent modifierFlags];
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -29,11 +29,12 @@
|
|||
|
||||
#include "llwindow.h"
|
||||
#include "llwindowcallbacks.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
|
||||
#include "lltimer.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AGL/agl.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
#include "fix_macros.h"
|
||||
|
|
@ -106,7 +107,6 @@ public:
|
|||
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
|
||||
|
||||
/*virtual*/ void *getPlatformWindow();
|
||||
/*virtual*/ void *getMediaWindow();
|
||||
/*virtual*/ void bringToFront() {};
|
||||
|
||||
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
|
||||
|
|
@ -117,7 +117,17 @@ public:
|
|||
|
||||
// Provide native key event data
|
||||
/*virtual*/ LLSD getNativeKeyData();
|
||||
|
||||
|
||||
void* getWindow() { return mWindow; }
|
||||
LLWindowCallbacks* getCallbacks() { return mCallbacks; }
|
||||
LLPreeditor* getPreeditor() { return mPreeditor; }
|
||||
|
||||
void updateMouseDeltas(float* deltas);
|
||||
void getMouseDeltas(float* delta);
|
||||
|
||||
void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
|
||||
|
||||
bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
|
||||
|
||||
protected:
|
||||
LLWindowMacOSX(LLWindowCallbacks* callbacks,
|
||||
|
|
@ -153,40 +163,33 @@ protected:
|
|||
BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync);
|
||||
void destroyContext();
|
||||
void setupFailure(const std::string& text, const std::string& caption, U32 type);
|
||||
static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
|
||||
static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
|
||||
OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
|
||||
void adjustCursorDecouple(bool warpingMouse = false);
|
||||
void stopDockTileBounce();
|
||||
static MASK modifiersToMask(SInt16 modifiers);
|
||||
static MASK modifiersToMask(S16 modifiers);
|
||||
|
||||
#if LL_OS_DRAGDROP_ENABLED
|
||||
static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
|
||||
void * handlerRefCon, DragRef theDrag);
|
||||
static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
|
||||
|
||||
//static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
//static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
|
||||
|
||||
|
||||
#endif // LL_OS_DRAGDROP_ENABLED
|
||||
|
||||
//
|
||||
// Platform specific variables
|
||||
//
|
||||
WindowRef mWindow;
|
||||
AGLContext mContext;
|
||||
AGLPixelFormat mPixelFormat;
|
||||
CGDirectDisplayID mDisplay;
|
||||
CFDictionaryRef mOldDisplayMode;
|
||||
EventLoopTimerRef mTimer;
|
||||
EventHandlerUPP mEventHandlerUPP;
|
||||
EventHandlerRef mGlobalHandlerRef;
|
||||
EventHandlerRef mWindowHandlerRef;
|
||||
EventComparatorUPP mMoveEventCampartorUPP;
|
||||
|
||||
Rect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
|
||||
Rect mPreviousWindowRect; // Save previous window for un-maximize event
|
||||
Str255 mWindowTitle;
|
||||
// Use generic pointers here. This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise.
|
||||
NSWindowRef mWindow;
|
||||
GLViewRef mGLView;
|
||||
CGLContextObj mContext;
|
||||
CGLPixelFormatObj mPixelFormat;
|
||||
CGDirectDisplayID mDisplay;
|
||||
|
||||
LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
|
||||
std::string mWindowTitle;
|
||||
double mOriginalAspectRatio;
|
||||
BOOL mSimulatedRightClick;
|
||||
UInt32 mLastModifiers;
|
||||
U32 mLastModifiers;
|
||||
BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing.
|
||||
// Used to allow event processing when putting up dialogs in fullscreen mode.
|
||||
BOOL mCursorDecoupled;
|
||||
|
|
@ -201,25 +204,16 @@ protected:
|
|||
U32 mFSAASamples;
|
||||
BOOL mForceRebuild;
|
||||
|
||||
S32 mDragOverrideCursor;
|
||||
|
||||
F32 mBounceTime;
|
||||
NMRec mBounceRec;
|
||||
LLTimer mBounceTimer;
|
||||
S32 mDragOverrideCursor;
|
||||
|
||||
// Input method management through Text Service Manager.
|
||||
TSMDocumentID mTSMDocument;
|
||||
BOOL mLanguageTextInputAllowed;
|
||||
ScriptCode mTSMScriptCode;
|
||||
LangCode mTSMLangCode;
|
||||
LLPreeditor* mPreeditor;
|
||||
|
||||
static BOOL sUseMultGL;
|
||||
|
||||
friend class LLWindowManager;
|
||||
static WindowRef sMediaWindow;
|
||||
EventRef mRawKeyEvent;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -232,12 +232,8 @@ private:
|
|||
mMovieHandle = NULL;
|
||||
};
|
||||
|
||||
if ( mGWorldHandle )
|
||||
{
|
||||
DisposeGWorld( mGWorldHandle );
|
||||
mGWorldHandle = NULL;
|
||||
};
|
||||
|
||||
mGWorldHandle = NULL;
|
||||
|
||||
setStatus(STATUS_NONE);
|
||||
|
||||
return true;
|
||||
|
|
@ -273,6 +269,7 @@ private:
|
|||
//std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sanitize destination size
|
||||
Rect dest_rect = rectFromSize(mWidth, mHeight);
|
||||
|
|
@ -281,12 +278,10 @@ private:
|
|||
int depth_bits = mDepth * 8;
|
||||
long rowbytes = mDepth * mTextureWidth;
|
||||
|
||||
GWorldPtr old_gworld_handle = mGWorldHandle;
|
||||
|
||||
if(mPixels != NULL)
|
||||
{
|
||||
// We have pixels. Set up a GWorld pointing at the texture.
|
||||
OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
|
||||
OSErr result = QTNewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
|
||||
if ( noErr != result )
|
||||
{
|
||||
// TODO: unrecoverable?? throw exception? return something?
|
||||
|
|
@ -297,7 +292,7 @@ private:
|
|||
{
|
||||
// We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
|
||||
Rect tempRect = rectFromSize(1, 1);
|
||||
OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
|
||||
OSErr result = QTNewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
|
||||
if ( noErr != result )
|
||||
{
|
||||
// TODO: unrecoverable?? throw exception? return something?
|
||||
|
|
@ -305,14 +300,8 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
|
||||
|
||||
// If the GWorld was already set up, delete it.
|
||||
if(old_gworld_handle != NULL)
|
||||
{
|
||||
DisposeGWorld( old_gworld_handle );
|
||||
}
|
||||
|
||||
SetMovieGWorld( mMovieHandle, mGWorldHandle, NULL );
|
||||
|
||||
// Set up the movie display matrix
|
||||
{
|
||||
// scale movie to fit rect and invert vertically to match opengl image format
|
||||
|
|
@ -579,28 +568,7 @@ private:
|
|||
}
|
||||
|
||||
};
|
||||
|
||||
int getDataWidth() const
|
||||
{
|
||||
if ( mGWorldHandle )
|
||||
{
|
||||
int depth = mDepth;
|
||||
|
||||
if (depth < 1)
|
||||
depth = 1;
|
||||
|
||||
// ALWAYS use the row bytes from the PixMap if we have a GWorld because
|
||||
// sometimes it's not the same as mMediaDepth * mMediaWidth !
|
||||
PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
|
||||
return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO : return LLMediaImplCommon::getaDataWidth();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void seek( F64 time )
|
||||
{
|
||||
if ( mMovieController )
|
||||
|
|
|
|||
|
|
@ -35,10 +35,13 @@
|
|||
|
||||
#include "volume_catcher.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <QuickTime/QuickTime.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
#if LL_DARWIN
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
struct VolumeCatcherStorage;
|
||||
|
||||
class VolumeCatcherImpl
|
||||
|
|
@ -266,3 +269,6 @@ void VolumeCatcher::pump()
|
|||
// No periodic tasks are necessary for this implementation.
|
||||
}
|
||||
|
||||
#if LL_DARWIN
|
||||
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1272,6 +1272,11 @@ set_source_files_properties(
|
|||
|
||||
if (DARWIN)
|
||||
LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp)
|
||||
LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm)
|
||||
LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h)
|
||||
|
||||
# This should be compiled with the viewer.
|
||||
LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
|
||||
|
||||
find_library(AGL_LIBRARY AGL)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
|
|
@ -1292,7 +1297,7 @@ if (DARWIN)
|
|||
macview.r
|
||||
gpu_table.txt
|
||||
Info-SecondLife.plist
|
||||
SecondLife.nib/
|
||||
SecondLife.xib/
|
||||
# CMake doesn't seem to support Xcode language variants well just yet
|
||||
English.lproj/InfoPlist.strings
|
||||
English.lproj/language.txt
|
||||
|
|
@ -1972,20 +1977,25 @@ if (LINUX)
|
|||
endif (LINUX)
|
||||
|
||||
if (DARWIN)
|
||||
# These all get set with PROPERTIES
|
||||
set(product "Second Life")
|
||||
|
||||
set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
|
||||
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
|
||||
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
|
||||
|
||||
set_target_properties(
|
||||
${VIEWER_BINARY_NAME}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "${product}"
|
||||
MACOSX_BUNDLE_INFO_STRING "Second Life Viewer"
|
||||
MACOSX_BUNDLE_ICON_FILE "secondlife.icns"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "Second Life"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}"
|
||||
MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007"
|
||||
MACOSX_BUNDLE_INFO_PLIST
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
|
||||
)
|
||||
|
||||
configure_file(
|
||||
|
|
|
|||
|
|
@ -5,19 +5,33 @@
|
|||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Second Life</string>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>secondlife.icns</string>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.secondlife.indra.viewer</string>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Second Life</string>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -59,9 +73,9 @@
|
|||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>${MACOSX_BUNDLE_NSPRINCIPAL_CLASS}</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>${MACOSX_BUNDLE_NSMAIN_NIB_FILE}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
IBClasses = ();
|
||||
IBVersion = 1;
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>85 13 356 240 0 0 1280 1002 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>29</key>
|
||||
<string>27 314 247 44 0 0 1280 1002 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>362.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>191</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>7D24</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCarbonFramework</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
<?xml version="1.0" standalone="yes"?>
|
||||
<object class="NSIBObjectData">
|
||||
<string name="targetFramework">IBCarbonFramework</string>
|
||||
<object name="rootObject" class="NSCustomObject" id="1">
|
||||
<string name="customClass">NSApplication</string>
|
||||
</object>
|
||||
<array count="31" name="allObjects">
|
||||
<object class="IBCarbonMenu" id="29">
|
||||
<string name="title">SecondLife</string>
|
||||
<array count="4" name="items">
|
||||
<object class="IBCarbonMenuItem" id="182">
|
||||
<string name="title">Second Life</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="181">
|
||||
<string name="title">Second Life</string>
|
||||
<array count="1" name="items">
|
||||
<object class="IBCarbonMenuItem" id="183">
|
||||
<boolean name="disabled">TRUE</boolean>
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">About Second Life</string>
|
||||
<int name="keyEquivalentModifier">0</int>
|
||||
<ostype name="command">abou</ostype>
|
||||
</object>
|
||||
</array>
|
||||
<string name="name">_NSAppleMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="127">
|
||||
<string name="title">File</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="131">
|
||||
<string name="title">File</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="152">
|
||||
<string name="title">Edit</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="147">
|
||||
<string name="title">Edit</string>
|
||||
<array count="10" name="items">
|
||||
<object class="IBCarbonMenuItem" id="141">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Undo</string>
|
||||
<string name="keyEquivalent">z</string>
|
||||
<ostype name="command">undo</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="146">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Redo</string>
|
||||
<string name="keyEquivalent">Z</string>
|
||||
<ostype name="command">redo</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="142">
|
||||
<boolean name="separator">TRUE</boolean>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="143">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Cut</string>
|
||||
<string name="keyEquivalent">x</string>
|
||||
<ostype name="command">cut </ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="149">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Copy</string>
|
||||
<string name="keyEquivalent">c</string>
|
||||
<ostype name="command">copy</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="144">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Paste</string>
|
||||
<string name="keyEquivalent">v</string>
|
||||
<ostype name="command">past</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="151">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Delete</string>
|
||||
<ostype name="command">clea</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="148">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Select All</string>
|
||||
<string name="keyEquivalent">a</string>
|
||||
<ostype name="command">sall</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="188">
|
||||
<boolean name="separator">TRUE</boolean>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="187">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Special Characters…</string>
|
||||
<ostype name="command">chrp</ostype>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="153">
|
||||
<string name="title">Window</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="154">
|
||||
<string name="title">Window</string>
|
||||
<array count="6" name="items">
|
||||
<object class="IBCarbonMenuItem" id="155">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Minimize Window</string>
|
||||
<string name="keyEquivalent">m</string>
|
||||
<ostype name="command">mini</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="184">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Minimize All Windows</string>
|
||||
<string name="keyEquivalent">m</string>
|
||||
<int name="keyEquivalentModifier">1572864</int>
|
||||
<ostype name="command">mina</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="186">
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Zoom</string>
|
||||
<ostype name="command">zoom</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="156">
|
||||
<boolean name="separator">TRUE</boolean>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="157">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Bring All to Front</string>
|
||||
<ostype name="command">bfrt</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="185">
|
||||
<boolean name="dynamic">TRUE</boolean>
|
||||
<boolean name="updateSingleItem">TRUE</boolean>
|
||||
<string name="title">Arrange in Front</string>
|
||||
<int name="keyEquivalentModifier">1572864</int>
|
||||
<ostype name="command">frnt</ostype>
|
||||
</object>
|
||||
</array>
|
||||
<string name="name">_NSWindowsMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
<string name="name">_NSMainMenu</string>
|
||||
</object>
|
||||
<reference idRef="127"/>
|
||||
<reference idRef="131"/>
|
||||
<reference idRef="141"/>
|
||||
<reference idRef="142"/>
|
||||
<reference idRef="143"/>
|
||||
<reference idRef="144"/>
|
||||
<reference idRef="146"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="148"/>
|
||||
<reference idRef="149"/>
|
||||
<reference idRef="151"/>
|
||||
<reference idRef="152"/>
|
||||
<reference idRef="153"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="155"/>
|
||||
<reference idRef="156"/>
|
||||
<reference idRef="157"/>
|
||||
<reference idRef="181"/>
|
||||
<reference idRef="182"/>
|
||||
<reference idRef="183"/>
|
||||
<reference idRef="184"/>
|
||||
<reference idRef="185"/>
|
||||
<reference idRef="186"/>
|
||||
<reference idRef="187"/>
|
||||
<reference idRef="188"/>
|
||||
<object class="IBCarbonRootControl" id="190">
|
||||
<string name="bounds">0 0 482 694 </string>
|
||||
<string name="viewFrame">0 0 694 482 </string>
|
||||
<array count="2" name="subviews">
|
||||
<object class="IBCarbonButton" id="192">
|
||||
<string name="bounds">442 604 462 674 </string>
|
||||
<string name="viewFrame">604 442 70 20 </string>
|
||||
<string name="title">OK</string>
|
||||
<ostype name="command">ok </ostype>
|
||||
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
|
||||
<int name="bindingBottomKind">2</int>
|
||||
<int name="bindingRightKind">2</int>
|
||||
</object>
|
||||
<int name="buttonType">1</int>
|
||||
</object>
|
||||
<object class="IBCarbonScrollView" id="201">
|
||||
<string name="bounds">20 20 422 674 </string>
|
||||
<string name="viewFrame">20 20 654 402 </string>
|
||||
<array count="1" name="subviews">
|
||||
<object class="IBCarbonTextView" id="200">
|
||||
<string name="bounds">20 20 422 659 </string>
|
||||
<string name="viewFrame">0 0 639 402 </string>
|
||||
<ostype name="controlSignature">text</ostype>
|
||||
<int name="fontStyle">5</int>
|
||||
<boolean name="readOnly">TRUE</boolean>
|
||||
</object>
|
||||
</array>
|
||||
<boolean name="scrollHorizontally">FALSE</boolean>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<object class="IBCarbonWindow" id="191">
|
||||
<string name="windowRect">84 72 566 766 </string>
|
||||
<string name="title">Release Notes</string>
|
||||
<reference name="rootControl" idRef="190"/>
|
||||
<boolean name="receiveUpdates">FALSE</boolean>
|
||||
<boolean name="hasCloseBox">FALSE</boolean>
|
||||
<boolean name="hasCollapseBox">FALSE</boolean>
|
||||
<boolean name="hasHorizontalZoom">FALSE</boolean>
|
||||
<boolean name="isResizable">FALSE</boolean>
|
||||
<boolean name="hasVerticalZoom">FALSE</boolean>
|
||||
<boolean name="liveResize">TRUE</boolean>
|
||||
<boolean name="compositing">TRUE</boolean>
|
||||
<int name="carbonWindowClass">4</int>
|
||||
<int name="windowPosition">1</int>
|
||||
<boolean name="isConstrained">FALSE</boolean>
|
||||
</object>
|
||||
<reference idRef="192"/>
|
||||
<reference idRef="200"/>
|
||||
<reference idRef="201"/>
|
||||
</array>
|
||||
<array count="31" name="allParents">
|
||||
<reference idRef="1"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="127"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="152"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="153"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="182"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="181"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="154"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="191"/>
|
||||
<reference idRef="1"/>
|
||||
<reference idRef="190"/>
|
||||
<reference idRef="201"/>
|
||||
<reference idRef="190"/>
|
||||
</array>
|
||||
<dictionary count="3" name="nameTable">
|
||||
<string>Files Owner</string>
|
||||
<reference idRef="1"/>
|
||||
<string>MenuBar</string>
|
||||
<reference idRef="29"/>
|
||||
<string>Release Notes</string>
|
||||
<reference idRef="191"/>
|
||||
</dictionary>
|
||||
<unsigned_int name="nextObjectID">202</unsigned_int>
|
||||
</object>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1 +1 @@
|
|||
3.6.5
|
||||
3.6.7
|
||||
|
|
|
|||
|
|
@ -3579,13 +3579,13 @@
|
|||
</map>
|
||||
<key>FilterItemsMaxTimePerFrameUnvisible</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<key>Comment</key>
|
||||
<string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FindLandArea</key>
|
||||
|
|
@ -8831,6 +8831,18 @@
|
|||
</array>
|
||||
</map>
|
||||
|
||||
<key>RenderSpecularPrecision</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force 32-bit floating point LUT</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
|
||||
<key>RenderSpecularResX</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9121,6 +9133,17 @@
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>RenderDeferredDisplayGamma</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Gamma ramp exponent for final correction before display gamma.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>2.2</real>
|
||||
</map>
|
||||
<key>RenderGLCoreProfile</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9848,6 +9871,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderWaterMaterials</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Water planar reflections include materials rendering.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderWaterMipNormal</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,26 @@ out vec4 frag_color;
|
|||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform float display_gamma;
|
||||
uniform vec4 gamma;
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform float haze_horizon;
|
||||
uniform float haze_density;
|
||||
uniform float cloud_shadow;
|
||||
uniform float density_multiplier;
|
||||
uniform float distance_multiplier;
|
||||
uniform float max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
#if HAS_SHADOW
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
|
|
@ -53,14 +73,8 @@ uniform float shadow_bias;
|
|||
uniform sampler2D diffuseMap;
|
||||
#endif
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_norm;
|
||||
|
||||
|
|
@ -68,12 +82,73 @@ VARYING vec3 vary_norm;
|
|||
VARYING vec4 vertex_color;
|
||||
#endif
|
||||
|
||||
vec3 vary_PositionEye;
|
||||
vec3 vary_SunlitColor;
|
||||
vec3 vary_AmblitColor;
|
||||
vec3 vary_AdditiveColor;
|
||||
vec3 vary_AtmosAttenuation;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
uniform vec2 screen_res;
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
|
|
@ -82,7 +157,7 @@ vec3 calcDirectionalLight(vec3 n, vec3 l)
|
|||
return vec3(a,a,a);
|
||||
}
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
|
@ -90,7 +165,9 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float
|
|||
//get distance
|
||||
float d = length(lv);
|
||||
|
||||
float da = 0.0;
|
||||
float da = 1.0;
|
||||
|
||||
vec3 col = vec3(0);
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
|
|
@ -99,20 +176,25 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float
|
|||
|
||||
//distance attenuation
|
||||
float dist = d/la;
|
||||
da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
da *= da;
|
||||
da *= 1.4;
|
||||
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
|
||||
float lit = max(da * dist_atten,0.0);
|
||||
|
||||
col = light_col * lit * diffuse;
|
||||
|
||||
// no spec for alpha shader...
|
||||
}
|
||||
|
||||
return vec3(da,da,da);
|
||||
return max(col, vec3(0.0,0.0,0.0));
|
||||
}
|
||||
|
||||
#if HAS_SHADOW
|
||||
|
|
@ -135,6 +217,237 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 getSunlitColor()
|
||||
{
|
||||
return vary_SunlitColor;
|
||||
}
|
||||
vec3 getAmblitColor()
|
||||
{
|
||||
return vary_AmblitColor;
|
||||
}
|
||||
vec3 getAdditiveColor()
|
||||
{
|
||||
return vary_AdditiveColor;
|
||||
}
|
||||
vec3 getAtmosAttenuation()
|
||||
{
|
||||
return vary_AtmosAttenuation;
|
||||
}
|
||||
|
||||
void setPositionEye(vec3 v)
|
||||
{
|
||||
vary_PositionEye = v;
|
||||
}
|
||||
|
||||
void setSunlitColor(vec3 v)
|
||||
{
|
||||
vary_SunlitColor = v;
|
||||
}
|
||||
|
||||
void setAmblitColor(vec3 v)
|
||||
{
|
||||
vary_AmblitColor = v;
|
||||
}
|
||||
|
||||
void setAdditiveColor(vec3 v)
|
||||
{
|
||||
vary_AdditiveColor = v;
|
||||
}
|
||||
|
||||
void setAtmosAttenuation(vec3 v)
|
||||
{
|
||||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
setPositionEye(P);
|
||||
|
||||
vec3 tmpLightnorm = lightnorm.xyz;
|
||||
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
vec4 temp1 = vec4(0);
|
||||
vec3 temp2 = vec3(0);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
//sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
//this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
//I had thought blue_density and haze_density should have equal weighting,
|
||||
//but attenuation due to haze_density tends to seem too strong
|
||||
|
||||
temp1 = blue_density + vec4(haze_density);
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = vec4(haze_density) / temp1;
|
||||
|
||||
//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
|
||||
temp2.y = max(0.0, tmpLightnorm.y);
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// main atmospheric scattering line integral
|
||||
temp2.z = Plen * density_multiplier;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z * distance_multiplier);
|
||||
|
||||
//final atmosphere attenuation factor
|
||||
setAtmosAttenuation(temp1.rgb);
|
||||
|
||||
//compute haze glow
|
||||
//(can use temp2.x as temp because we haven't used it yet)
|
||||
temp2.x = dot(Pn, tmpLightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
//temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .03); //was glow.y
|
||||
//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
//higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
//glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
//add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
|
||||
|
||||
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
|
||||
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
|
||||
* // The following line of code performs the equivalent of:
|
||||
* float ambAlpha = tmpAmbient.a;
|
||||
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
|
||||
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
|
||||
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
|
||||
*/
|
||||
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor();
|
||||
return (2.0 * light);
|
||||
}
|
||||
|
||||
vec3 atmosTransport(vec3 light) {
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
}
|
||||
|
||||
vec3 scaleDownLight(vec3 light)
|
||||
{
|
||||
return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
|
||||
}
|
||||
|
||||
vec3 scaleUpLight(vec3 light)
|
||||
{
|
||||
return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
|
||||
}
|
||||
|
||||
vec3 atmosAmbient(vec3 light)
|
||||
{
|
||||
return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity)
|
||||
{
|
||||
return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
|
||||
}
|
||||
|
||||
vec3 scaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
|
||||
vec3 ones = vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
light = ones - clamp(light, zeroes, ones);
|
||||
light = ones - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light) {
|
||||
float brightness = dot(light.rgb, vec3(0.33333));
|
||||
|
||||
return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -143,13 +456,15 @@ void main()
|
|||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
float shadow = 1.0;
|
||||
|
||||
#if HAS_SHADOW
|
||||
float shadow = 0.0;
|
||||
#if HAS_SHADOW
|
||||
vec4 spos = pos;
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
{
|
||||
shadow = 0.0;
|
||||
|
||||
vec4 lpos;
|
||||
|
||||
vec4 near_split = shadow_clip*-0.75;
|
||||
|
|
@ -215,40 +530,77 @@ void main()
|
|||
#else
|
||||
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
#endif
|
||||
vec4 gamma_diff = diff;
|
||||
|
||||
diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f));
|
||||
#ifdef FOR_IMPOSTOR
|
||||
vec4 color;
|
||||
color.rgb = diff.rgb;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
float vertex_color_alpha = vertex_color.a;
|
||||
float final_alpha = diff.a * vertex_color.a;
|
||||
diff.rgb *= vertex_color.rgb;
|
||||
#else
|
||||
float vertex_color_alpha = 1.0;
|
||||
#endif
|
||||
|
||||
vec3 normal = vary_norm;
|
||||
|
||||
vec3 l = light_position[0].xyz;
|
||||
vec3 dlight = calcDirectionalLight(normal, l);
|
||||
dlight = dlight * vary_directional.rgb * vary_pointlight_col;
|
||||
|
||||
#if HAS_SHADOW
|
||||
vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha);
|
||||
#else
|
||||
vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha);
|
||||
float final_alpha = diff.a;
|
||||
#endif
|
||||
|
||||
vec4 color = gamma_diff * col;
|
||||
|
||||
// Insure we don't pollute depth with invis pixels in impostor rendering
|
||||
//
|
||||
if (final_alpha < 0.01)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
float final_alpha = diff.a * vertex_color.a;
|
||||
diff.rgb *= vertex_color.rgb;
|
||||
#else
|
||||
float final_alpha = diff.a;
|
||||
#endif
|
||||
|
||||
|
||||
vec4 gamma_diff = diff;
|
||||
diff.rgb = srgb_to_linear(diff.rgb);
|
||||
|
||||
vec3 norm = vary_norm;
|
||||
|
||||
calcAtmospherics(pos.xyz, 1.0);
|
||||
|
||||
vec2 abnormal = encode_normal(norm.xyz);
|
||||
norm.xyz = decode_normal(abnormal.xy);
|
||||
|
||||
float da = dot(norm.xyz, sun_dir.xyz);
|
||||
|
||||
float final_da = da;
|
||||
final_da = min(final_da, shadow);
|
||||
final_da = max(final_da, 0.0f);
|
||||
final_da = min(final_da, 1.0f);
|
||||
final_da = pow(final_da, 1.0/1.3);
|
||||
|
||||
vec4 color = vec4(0,0,0,0);
|
||||
|
||||
color.rgb = atmosAmbient(color.rgb);
|
||||
color.a = final_alpha;
|
||||
|
||||
float ambient = abs(da);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
color.rgb *= ambient;
|
||||
color.rgb += atmosAffectDirectionalLight(final_da);
|
||||
color.rgb *= gamma_diff.rgb;
|
||||
|
||||
//color.rgb = mix(diff.rgb, color.rgb, final_alpha);
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(2.2));
|
||||
col = vec4(0,0,0,0);
|
||||
vec4 light = vec4(0,0,0,0);
|
||||
|
||||
|
||||
#define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
LIGHT_LOOP(3)
|
||||
|
|
@ -257,9 +609,19 @@ void main()
|
|||
LIGHT_LOOP(6)
|
||||
LIGHT_LOOP(7)
|
||||
|
||||
color.rgb += diff.rgb * pow(vary_pointlight_col, vec3(2.2)) * col.rgb;
|
||||
// keep it linear
|
||||
//
|
||||
color.rgb += light.rgb;
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(1.0/2.2));
|
||||
// straight to display gamma, we're post-deferred
|
||||
//
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
color = applyWaterFogDeferred(pos.xyz, color);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,67 +55,18 @@ mat4 getSkinnedTransform();
|
|||
#endif
|
||||
#endif
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
VARYING vec4 vertex_color;
|
||||
#endif
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
VARYING vec3 vary_norm;
|
||||
|
||||
uniform float near_clip;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return vec3(da,da,da);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos;
|
||||
|
|
@ -168,43 +119,10 @@ void main()
|
|||
vary_norm = norm;
|
||||
vary_position = pos.xyz;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
#ifndef USE_VERTEX_COLOR
|
||||
vec4 diffuse_color = vec4(1,1,1,1);
|
||||
#endif
|
||||
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
|
||||
|
||||
vec3 diff = diffuse_color.rgb;
|
||||
|
||||
|
||||
|
||||
vary_pointlight_col = diff;
|
||||
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(col.rgb);
|
||||
|
||||
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
col.rgb *= ambient;
|
||||
|
||||
vary_ambient = col.rgb*diff.rgb;
|
||||
|
||||
vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
|
||||
|
||||
col.rgb = col.rgb*diff.rgb;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
vertex_color = col;
|
||||
vertex_color = diffuse_color;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
|
||||
#else
|
||||
|
|
@ -219,4 +137,3 @@ void main()
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,22 +59,6 @@ vec4 getPosition(vec2 pos_screen)
|
|||
return pos;
|
||||
}
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -91,7 +75,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ void main()
|
|||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
|
|
|
|||
|
|
@ -35,29 +35,143 @@ out vec4 frag_color;
|
|||
uniform sampler2D diffuseMap;
|
||||
#endif
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransportDeferred(vec3 light)
|
||||
{
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClipDeferred(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
uniform float minimum_alpha;
|
||||
#endif
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#if HAS_DIFFUSE_LOOKUP
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy);
|
||||
#else
|
||||
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color;
|
||||
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
#endif
|
||||
|
||||
color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
|
||||
float final_alpha = color.a * vertex_color.a;
|
||||
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
if (color.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
color.rgb *= vertex_color.rgb;
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
|
||||
color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
|
||||
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
#ifdef WATER_FOG
|
||||
vec3 pos = vary_position;
|
||||
vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
|
||||
color.rgb = fogged.rgb;
|
||||
color.a = fogged.a;
|
||||
#else
|
||||
color.a = final_alpha;
|
||||
#endif
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(1.0/2.2));
|
||||
|
||||
frag_color = color;
|
||||
frag_color.rgb = color.rgb;
|
||||
frag_color.a = color.a;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
|
|||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
VARYING vec3 vary_position;
|
||||
#endif
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
|
@ -53,7 +56,11 @@ void main()
|
|||
passTextureIndex();
|
||||
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vary_position = pos.xyz;
|
||||
#endif
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,42 @@ uniform sampler2D specularMap;
|
|||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
|
|
@ -47,7 +83,12 @@ void main()
|
|||
discard;
|
||||
}
|
||||
|
||||
frag_data[0] = vec4(col.rgb, col.a * 0.005);
|
||||
frag_data[1] = texture2D(specularMap, vary_texcoord0.xy);
|
||||
frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
|
||||
vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
|
||||
vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
|
||||
|
||||
col.rgb = linear_to_srgb(col.rgb);
|
||||
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = spec;
|
||||
frag_data[2] = vec4(norm.xy,0,0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,44 @@
|
|||
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
|
||||
|
||||
uniform float emissive_brightness;
|
||||
uniform float display_gamma;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
||||
|
|
@ -114,6 +152,52 @@ uniform vec3 light_direction[8];
|
|||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
|
|
@ -142,7 +226,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
|
|||
float dist = d/la;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 1.4;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
|
|
@ -199,10 +283,13 @@ vec4 getPosition_d(vec2 pos_screen, float depth)
|
|||
return pos;
|
||||
}
|
||||
|
||||
#ifndef WATER_FOG
|
||||
vec3 getPositionEye()
|
||||
{
|
||||
return vary_PositionEye;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 getSunlitColor()
|
||||
{
|
||||
return vary_SunlitColor;
|
||||
|
|
@ -428,22 +515,6 @@ VARYING vec3 vary_normal;
|
|||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -460,7 +531,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -475,8 +545,8 @@ void main()
|
|||
#endif
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
vec3 old_diffcol = diffcol.rgb;
|
||||
diffcol.rgb = pow(diffcol.rgb, vec3(2.2));
|
||||
vec3 gamma_diff = diffcol.rgb;
|
||||
diffcol.rgb = srgb_to_linear(diffcol.rgb);
|
||||
#endif
|
||||
|
||||
#if HAS_SPECULAR_MAP
|
||||
|
|
@ -502,6 +572,9 @@ void main()
|
|||
norm.xyz = tnorm;
|
||||
norm.xyz = normalize(norm.xyz);
|
||||
|
||||
vec2 abnormal = encode_normal(norm.xyz);
|
||||
norm.xyz = decode_normal(abnormal.xy);
|
||||
|
||||
vec4 final_color = diffcol;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
|
||||
|
|
@ -597,7 +670,7 @@ void main()
|
|||
vec4 diffuse = final_color;
|
||||
float envIntensity = final_normal.z;
|
||||
|
||||
vec3 col = vec3(0.0f,0.0f,0.0f);
|
||||
vec3 col = vec3(0.0f,0.0f,0.0f);
|
||||
|
||||
float bloom = 0.0;
|
||||
calcAtmospherics(pos.xyz, 1.0);
|
||||
|
|
@ -605,23 +678,27 @@ void main()
|
|||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
float da =dot(norm.xyz, sun_dir.xyz);
|
||||
|
||||
float final_da = da;
|
||||
final_da = min(final_da, shadow);
|
||||
final_da = max(final_da, diffuse.a);
|
||||
//final_da = max(final_da, diffuse.a);
|
||||
final_da = max(final_da, 0.0f);
|
||||
final_da = min(final_da, 1.0f);
|
||||
final_da = pow(final_da, 1.0/1.3);
|
||||
|
||||
col.rgb = atmosAmbient(col);
|
||||
|
||||
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
|
||||
float ambient = min(abs(da), 1.0);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
col.rgb *= ambient;
|
||||
|
||||
col.rgb = col.rgb + atmosAffectDirectionalLight(pow(final_da, 1.0/1.3));
|
||||
col.rgb *= old_diffcol.rgb;
|
||||
|
||||
col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
|
||||
|
||||
col.rgb *= gamma_diff.rgb;
|
||||
|
||||
|
||||
float glare = 0.0;
|
||||
|
||||
|
|
@ -643,7 +720,8 @@ void main()
|
|||
col += spec_contrib;
|
||||
}
|
||||
|
||||
col = mix(col.rgb, old_diffcol.rgb, diffuse.a);
|
||||
|
||||
col = mix(col.rgb, diffcol.rgb, diffuse.a);
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
|
|
@ -661,16 +739,20 @@ void main()
|
|||
glare += cur_glare;
|
||||
}
|
||||
|
||||
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
|
||||
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
//col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
|
||||
//col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
|
||||
col = atmosLighting(col);
|
||||
col = scaleSoftClip(col);
|
||||
|
||||
//convert to linear space before adding local lights
|
||||
col = pow(col, vec3(2.2));
|
||||
|
||||
col = srgb_to_linear(col);
|
||||
|
||||
vec3 npos = normalize(-pos.xyz);
|
||||
|
||||
#define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
|
||||
vec3 light = vec3(0,0,0);
|
||||
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
|
|
@ -680,13 +762,22 @@ void main()
|
|||
LIGHT_LOOP(6)
|
||||
LIGHT_LOOP(7)
|
||||
|
||||
col.rgb += light.rgb;
|
||||
|
||||
glare = min(glare, 1.0);
|
||||
float al = max(diffcol.a,glare)*vertex_color.a;
|
||||
|
||||
//convert to gamma space for display on screen
|
||||
col.rgb = pow(col.rgb, vec3(1.0/2.2));
|
||||
col.rgb = linear_to_srgb(col.rgb);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
|
||||
col.rgb = temp.rgb;
|
||||
al = temp.a;
|
||||
#endif
|
||||
|
||||
frag_color.rgb = col.rgb;
|
||||
glare = min(glare, 1.0);
|
||||
frag_color.a = max(diffcol.a,glare)*vertex_color.a;
|
||||
frag_color.a = al;
|
||||
|
||||
#else
|
||||
frag_data[0] = final_color;
|
||||
|
|
@ -694,3 +785,4 @@ void main()
|
|||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,3 +142,4 @@ vary_normal = n;
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,9 +45,8 @@ uniform float sun_wash;
|
|||
|
||||
uniform int light_count;
|
||||
|
||||
#define MAX_LIGHT_COUNT 16
|
||||
uniform vec4 light[MAX_LIGHT_COUNT];
|
||||
uniform vec4 light_col[MAX_LIGHT_COUNT];
|
||||
uniform vec4 light[LIGHT_COUNT];
|
||||
uniform vec4 light_col[LIGHT_COUNT];
|
||||
|
||||
VARYING vec4 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
|
@ -56,22 +55,6 @@ uniform float far_z;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -88,7 +71,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
|
|
@ -117,78 +99,66 @@ void main()
|
|||
norm = normalize(norm);
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
vec3 out_col = vec3(0,0,0);
|
||||
vec3 npos = normalize(-pos);
|
||||
|
||||
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
|
||||
for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
|
||||
for (int i = 0; i < LIGHT_COUNT; ++i)
|
||||
{
|
||||
bool light_contrib = (i < light_count);
|
||||
|
||||
vec3 lv = light[i].xyz-pos;
|
||||
float dist = length(lv);
|
||||
dist /= light[i].w;
|
||||
if (dist > 1.0)
|
||||
if (dist <= 1.0)
|
||||
{
|
||||
light_contrib = false;
|
||||
}
|
||||
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
light_contrib = false;
|
||||
}
|
||||
|
||||
if (light_contrib)
|
||||
{
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
float fa = light_col[i].a+1.0;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
dist_atten *= noise;
|
||||
|
||||
float lit = da * dist_atten;
|
||||
|
||||
vec3 col = light_col[i].rgb*lit*diff;
|
||||
|
||||
//vec3 col = vec3(dist2, light_col[i].a, lit);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
float da = dot(norm, lv);
|
||||
if (da > 0.0)
|
||||
{
|
||||
lit = min(da*6.0, 1.0) * dist_atten;
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += lit*scol*light_col[i].rgb*spec.rgb;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
out_col += col;
|
||||
float fa = light_col[i].a+1.0;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
dist_atten *= noise;
|
||||
|
||||
float lit = da * dist_atten;
|
||||
|
||||
vec3 col = light_col[i].rgb*lit*diff;
|
||||
|
||||
//vec3 col = vec3(dist2, light_col[i].a, lit);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
lit = min(da*6.0, 1.0) * dist_atten;
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += lit*scol*light_col[i].rgb*spec.rgb;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
out_col += col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dot(out_col, out_col) <= 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
frag_color.rgb = out_col;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ out vec4 frag_color;
|
|||
//class 1 -- no shadows
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
|
|
@ -67,22 +68,6 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -99,17 +84,48 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(pow(col.rgb, vec3(2.2)), col.a);
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
ret.rgb = srgb_to_linear(ret.rgb);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
|
|
@ -125,7 +141,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
|||
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
ret.rgb = srgb_to_linear(ret.rgb);
|
||||
|
||||
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
|
||||
|
||||
|
|
@ -143,7 +159,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
|||
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
ret.rgb = srgb_to_linear(ret.rgb);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
|
|
@ -295,14 +311,11 @@ void main()
|
|||
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
|
||||
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
|
||||
|
||||
stc /= stc.w;
|
||||
if (stc.z > 0.0)
|
||||
{
|
||||
stc.xy /= stc.w;
|
||||
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
|
||||
|
||||
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
|
||||
if (stc.x < 1.0 &&
|
||||
|
|
@ -310,7 +323,7 @@ void main()
|
|||
stc.x > 0.0 &&
|
||||
stc.y > 0.0)
|
||||
{
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,22 +54,6 @@ uniform vec2 screen_res;
|
|||
uniform mat4 inv_proj;
|
||||
uniform vec4 viewport;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -86,7 +70,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,11 +36,32 @@ uniform sampler2DRect diffuseRect;
|
|||
uniform vec2 screen_res;
|
||||
VARYING vec2 vary_fragcoord;
|
||||
|
||||
uniform float texture_gamma;
|
||||
uniform float display_gamma;
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
|
||||
frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f));
|
||||
diff.rgb = linear_to_srgb(diff.rgb);
|
||||
frag_color = diff;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
|
|
@ -78,22 +79,43 @@ vec3 vary_AtmosAttenuation;
|
|||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
|
|
@ -104,7 +126,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition_d(vec2 pos_screen, float depth)
|
||||
{
|
||||
|
|
@ -170,6 +191,53 @@ void setAtmosAttenuation(vec3 v)
|
|||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
|
|
@ -324,13 +392,16 @@ void main()
|
|||
float envIntensity = norm.z;
|
||||
norm.xyz = decode_normal(norm.xy); // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
da = pow(da, 1.0/1.3);
|
||||
float da = dot(norm.xyz, sun_dir.xyz);
|
||||
|
||||
float final_da = max(0.0,da);
|
||||
final_da = min(final_da, 1.0f);
|
||||
final_da = pow(final_da, 1.0/1.3);
|
||||
|
||||
vec4 diffuse = texture2DRect(diffuseRect, tc);
|
||||
|
||||
//convert to gamma space
|
||||
diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
|
||||
diffuse.rgb = linear_to_srgb(diffuse.rgb);
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
|
||||
vec3 col;
|
||||
|
|
@ -346,7 +417,7 @@ void main()
|
|||
|
||||
col.rgb *= ambient;
|
||||
|
||||
col += atmosAffectDirectionalLight(max(min(da, 1.0), 0.0));
|
||||
col += atmosAffectDirectionalLight(final_da);
|
||||
|
||||
col *= diffuse.rgb;
|
||||
|
||||
|
|
@ -386,13 +457,19 @@ void main()
|
|||
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
}
|
||||
|
||||
col = pow(col, vec3(2.2));
|
||||
#ifdef WATER_FOG
|
||||
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
|
||||
col = fogged.rgb;
|
||||
bloom = fogged.a;
|
||||
#endif
|
||||
|
||||
col = srgb_to_linear(col);
|
||||
|
||||
//col = vec3(1,0,1);
|
||||
//col.g = envIntensity;
|
||||
}
|
||||
|
||||
frag_color.rgb = col;
|
||||
|
||||
frag_color.rgb = col.rgb;
|
||||
frag_color.a = bloom;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
|
|
@ -31,6 +32,8 @@ out vec4 frag_color;
|
|||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
//class 1 -- no shadows
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect depthMap;
|
||||
|
|
@ -65,22 +68,6 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -97,11 +84,47 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(pow(col.rgb, vec3(2.2)), col.a);
|
||||
return vec4(srgb_to_linear(col.rgb), col.a);
|
||||
}
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @file srgb.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
return mix(high_range, low_range, lte);
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
return mix(high_range, low_range, lt);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* @file srgb.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -49,22 +49,6 @@ VARYING vec2 vary_fragcoord;
|
|||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -81,7 +65,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* @file underWaterF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_data[3];
|
||||
#else
|
||||
#define frag_data gl_FragData
|
||||
#endif
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D bumpMap;
|
||||
uniform sampler2D screenTex;
|
||||
uniform sampler2D refTex;
|
||||
uniform sampler2D screenDepth;
|
||||
|
||||
uniform vec4 fogCol;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 specular;
|
||||
uniform float lightExp;
|
||||
uniform vec2 fbScale;
|
||||
uniform float refScale;
|
||||
uniform float znear;
|
||||
uniform float zfar;
|
||||
uniform float kd;
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec3 eyeVec;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
uniform vec2 screenRes;
|
||||
|
||||
//bigWave is (refCoord.w, view.w);
|
||||
VARYING vec4 refCoord;
|
||||
VARYING vec4 littleWave;
|
||||
VARYING vec4 view;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec4 applyWaterFog(vec4 color, vec3 viewVec)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(viewVec);
|
||||
float es = -view.z;
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(viewVec);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
//return vec4(1.0, 0.0, 1.0, 1.0);
|
||||
return color * D + kc * L;
|
||||
//depth /= 10.0;
|
||||
//return vec4(depth,depth,depth,0.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color;
|
||||
|
||||
//get detail normals
|
||||
vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
|
||||
vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
|
||||
vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
|
||||
vec3 wavef = normalize(wave1+wave2+wave3);
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
|
||||
distort = distort+wavef.xy*refScale;
|
||||
|
||||
vec4 fb = texture2D(screenTex, distort);
|
||||
|
||||
frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
|
||||
}
|
||||
|
|
@ -67,6 +67,43 @@ VARYING vec4 littleWave;
|
|||
VARYING vec4 view;
|
||||
VARYING vec4 vary_position;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -121,7 +158,7 @@ void main()
|
|||
refcol *= df1 * 0.333;
|
||||
|
||||
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
|
||||
//wavef.z *= max(-viewVec.z, 0.1);
|
||||
wavef.z *= max(-viewVec.z, 0.1);
|
||||
wavef = normalize(wavef);
|
||||
|
||||
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
|
||||
|
|
@ -131,13 +168,14 @@ void main()
|
|||
vec2 refvec4 = distort+refdistort4/dmod;
|
||||
float dweight = min(dist2*blurMultiplier, 1.0);
|
||||
vec4 baseCol = texture2D(refTex, refvec4);
|
||||
|
||||
refcol = mix(baseCol*df2, refcol, dweight);
|
||||
|
||||
//get specular component
|
||||
//float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
|
||||
//harden specular
|
||||
//spec = pow(spec, 128.0);
|
||||
spec = pow(spec, 128.0);
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
|
||||
|
|
@ -148,24 +186,17 @@ void main()
|
|||
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
|
||||
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
|
||||
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
|
||||
//vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
|
||||
vec4 spos = pos;
|
||||
|
||||
//spec *= shadow;
|
||||
//color.rgb += spec * specular;
|
||||
|
||||
color.rgb += spec * specular;
|
||||
|
||||
color.rgb = atmosTransport(color.rgb);
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
//color.a = spec * sunAngle2;
|
||||
color.a = spec * sunAngle2;
|
||||
|
||||
//wavef.z *= 0.1f;
|
||||
//wavef = normalize(wavef);
|
||||
vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz;
|
||||
vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
|
||||
|
||||
frag_data[0] = vec4(color.rgb, 0.5); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace
|
||||
frag_data[0] = vec4(color.rgb, color); // diffuse
|
||||
frag_data[1] = vec4(0); // speccolor, spec
|
||||
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void main()
|
|||
pos.w = 1.0;
|
||||
pos = modelview_matrix*pos;
|
||||
|
||||
calcAtmospherics(view.xyz);
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//pass wave parameters to pixel shader
|
||||
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ void default_lighting()
|
|||
{
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy);
|
||||
|
||||
color *= vertex_color;
|
||||
|
||||
if (color.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
color.rgb *= vertex_color.rgb;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
|
|
|||
|
|
@ -1,224 +0,0 @@
|
|||
/**
|
||||
* @file alphaV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, 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$
|
||||
*/
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
#ifdef USE_INDEXED_TEX
|
||||
void passTextureIndex();
|
||||
#endif
|
||||
|
||||
ATTRIBUTE vec3 normal;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
#endif
|
||||
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
#ifdef IS_AVATAR_SKIN
|
||||
mat4 getSkinnedTransform();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
vec3 calcDirectionalLight(vec3 n, vec3 l);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
VARYING vec4 vertex_color;
|
||||
#endif
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_norm;
|
||||
|
||||
uniform float near_clip;
|
||||
uniform float shadow_offset;
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
vec3 calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return vec3(a,a,a);
|
||||
}
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return vec3(da,da,da);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
//transform vertex
|
||||
#ifdef HAS_SKIN
|
||||
mat4 trans = getObjectSkinnedTransform();
|
||||
trans = modelview_matrix * trans;
|
||||
|
||||
pos = trans * vec4(position.xyz, 1.0);
|
||||
|
||||
norm = position.xyz + normal.xyz;
|
||||
norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
#else
|
||||
|
||||
#ifdef IS_AVATAR_SKIN
|
||||
mat4 trans = getSkinnedTransform();
|
||||
vec4 pos_in = vec4(position.xyz, 1.0);
|
||||
pos.x = dot(trans[0], pos_in);
|
||||
pos.y = dot(trans[1], pos_in);
|
||||
pos.z = dot(trans[2], pos_in);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, normal);
|
||||
norm.y = dot(trans[1].xyz, normal);
|
||||
norm.z = dot(trans[2].xyz, normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
#else
|
||||
norm = normalize(normal_matrix * normal);
|
||||
vec4 vert = vec4(position.xyz, 1.0);
|
||||
pos = (modelview_matrix * vert);
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_INDEXED_TEX
|
||||
passTextureIndex();
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
#else
|
||||
vary_texcoord0 = texcoord0;
|
||||
#endif
|
||||
|
||||
vary_norm = norm;
|
||||
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
|
||||
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
#ifndef USE_VERTEX_COLOR
|
||||
vec4 diffuse_color = vec4(1,1,1,1);
|
||||
#endif
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
|
||||
|
||||
vec3 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f));
|
||||
|
||||
vary_pointlight_col = dff;
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(col.rgb);
|
||||
|
||||
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
col.rgb *= ambient;
|
||||
|
||||
vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
|
||||
vary_ambient = col.rgb*dff;
|
||||
|
||||
col.rgb = col.rgb*dff;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
vertex_color = col;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
|
||||
#else
|
||||
|
||||
#ifdef IS_AVATAR_SKIN
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
#else
|
||||
pos = modelview_projection_matrix * vert;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
|
|
@ -68,22 +69,43 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -100,14 +122,12 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(pow(col.rgb, vec3(2.2)), col.a);
|
||||
return vec4(srgb_to_linear(col.rgb), col.a);
|
||||
}
|
||||
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
|
|
@ -314,14 +334,12 @@ void main()
|
|||
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
|
||||
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
|
||||
stc /= stc.w;
|
||||
|
||||
if (stc.z > 0.0)
|
||||
{
|
||||
stc.xy /= stc.w;
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
|
||||
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
|
||||
|
||||
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
|
||||
if (stc.x < 1.0 &&
|
||||
|
|
@ -329,12 +347,16 @@ void main()
|
|||
stc.x > 0.0 &&
|
||||
stc.y > 0.0)
|
||||
{
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//not sure why, but this line prevents MATBUG-194
|
||||
col = max(col, vec3(0.0));
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,22 +78,43 @@ vec3 vary_AtmosAttenuation;
|
|||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -110,7 +131,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition_d(vec2 pos_screen, float depth)
|
||||
{
|
||||
|
|
@ -263,6 +283,52 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
|||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
|
|
@ -343,7 +409,7 @@ void main()
|
|||
vec4 diffuse = texture2DRect(diffuseRect, tc);
|
||||
|
||||
//convert to gamma space
|
||||
diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
|
||||
diffuse.rgb = linear_to_srgb(diffuse.rgb);
|
||||
|
||||
vec3 col;
|
||||
float bloom = 0.0;
|
||||
|
|
@ -402,19 +468,25 @@ void main()
|
|||
envIntensity);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (norm.w < 0.5)
|
||||
{
|
||||
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
|
||||
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
}
|
||||
|
||||
col = pow(col, vec3(2.2));
|
||||
#ifdef WATER_FOG
|
||||
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
|
||||
col = fogged.rgb;
|
||||
bloom = fogged.a;
|
||||
#endif
|
||||
|
||||
col = srgb_to_linear(col);
|
||||
|
||||
//col = vec3(1,0,1);
|
||||
//col.g = envIntensity;
|
||||
}
|
||||
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.a = bloom;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
|
|
@ -68,22 +69,6 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -100,11 +85,47 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(pow(col.rgb, vec3(2.2)), col.a);
|
||||
return vec4(srgb_to_linear(col.rgb), col.a);
|
||||
}
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
|
|
@ -333,6 +354,9 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
//not sure why, but this line prevents MATBUG-194
|
||||
col = max(col, vec3(0.0));
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,22 +65,6 @@ uniform float shadow_offset;
|
|||
uniform float spot_shadow_bias;
|
||||
uniform float spot_shadow_offset;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -97,7 +81,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,22 +66,6 @@ uniform float shadow_offset;
|
|||
uniform float spot_shadow_bias;
|
||||
uniform float spot_shadow_offset;
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
|
|
@ -98,7 +82,6 @@ vec3 decode_normal (vec2 enc)
|
|||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -309,8 +309,8 @@ RenderVolumeLODFactor 1 2.0
|
|||
VertexShaderEnable 1 1
|
||||
WindLightUseAtmosShaders 1 1
|
||||
WLSkyDetail 1 128
|
||||
RenderDeferred 1 0
|
||||
RenderDeferredSSAO 1 0
|
||||
RenderDeferred 1 1
|
||||
RenderDeferredSSAO 1 1
|
||||
RenderShadowDetail 1 2
|
||||
RenderFSAASamples 1 2
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* @file llappdelegate-objc.mm
|
||||
* @brief Class implementation for the Mac version's application delegate.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#import "llappdelegate-objc.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
|
||||
|
||||
@implementation LLAppDelegate
|
||||
|
||||
@synthesize window;
|
||||
@synthesize inputWindow;
|
||||
@synthesize inputView;
|
||||
@synthesize currentInputLanguage;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
frameTimer = nil;
|
||||
|
||||
[self languageUpdated];
|
||||
|
||||
if (initViewer())
|
||||
{
|
||||
frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES];
|
||||
} else {
|
||||
handleQuit();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
|
||||
}
|
||||
|
||||
- (void) applicationDidBecomeActive:(NSNotification *)notification
|
||||
{
|
||||
callWindowFocus();
|
||||
}
|
||||
|
||||
- (void) applicationDidResignActive:(NSNotification *)notification
|
||||
{
|
||||
callWindowUnfocus();
|
||||
}
|
||||
|
||||
- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
if (!runMainLoop())
|
||||
{
|
||||
handleQuit();
|
||||
return NSTerminateCancel;
|
||||
} else {
|
||||
[frameTimer release];
|
||||
cleanupViewer();
|
||||
return NSTerminateNow;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mainLoop
|
||||
{
|
||||
bool appExiting = runMainLoop();
|
||||
if (appExiting)
|
||||
{
|
||||
[frameTimer release];
|
||||
[[NSApplication sharedApplication] terminate:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent
|
||||
{
|
||||
if (![self romanScript])
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
NSLog(@"Showing input window.");
|
||||
[inputWindow makeKeyAndOrderFront:inputWindow];
|
||||
if (textEvent != nil)
|
||||
{
|
||||
[[inputView inputContext] discardMarkedText];
|
||||
[[inputView inputContext] handleEvent:textEvent];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Hiding input window.");
|
||||
[inputWindow orderOut:inputWindow];
|
||||
[window makeKeyAndOrderFront:window];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will get called multiple times by NSNotificationCenter.
|
||||
// It will be called every time that the window focus changes, and every time that the input language gets changed.
|
||||
// The primary use case for this selector is to update our current input language when the user, for whatever reason, changes the input language.
|
||||
// This is the more elegant way of handling input language changes instead of checking every time we want to use the input window.
|
||||
|
||||
- (void) languageUpdated
|
||||
{
|
||||
TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource();
|
||||
CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages);
|
||||
|
||||
#if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:"
|
||||
NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages));
|
||||
#endif
|
||||
|
||||
// Typically the language we want is going to be the very first result in the array.
|
||||
currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0);
|
||||
}
|
||||
|
||||
- (bool) romanScript
|
||||
{
|
||||
// How to add support for new languages with the input window:
|
||||
// Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
|
||||
NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil];
|
||||
if ([nonRomanScript containsObject:currentInputLanguage])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -723,6 +723,11 @@ bool LLAppViewer::init()
|
|||
// we run the "program crashed last time" error handler below.
|
||||
//
|
||||
LLFastTimer::reset();
|
||||
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
mMainLoopInitialized = false;
|
||||
#endif
|
||||
|
||||
// initialize LLWearableType translation bridge.
|
||||
// Memory will be cleaned up in ::cleanupClass()
|
||||
|
|
@ -1253,40 +1258,57 @@ LLFastTimer::DeclareTimer FTM_FRAME("Frame", true);
|
|||
|
||||
bool LLAppViewer::mainLoop()
|
||||
{
|
||||
mMainloopTimeout = new LLWatchdogTimeout();
|
||||
#ifdef LL_DARWIN
|
||||
if (!mMainLoopInitialized)
|
||||
#endif
|
||||
{
|
||||
mMainloopTimeout = new LLWatchdogTimeout();
|
||||
|
||||
//-------------------------------------------
|
||||
// Run main loop until time to quit
|
||||
//-------------------------------------------
|
||||
|
||||
// Create IO Pump to use for HTTP Requests.
|
||||
gServicePump = new LLPumpIO(gAPRPoolp);
|
||||
LLHTTPClient::setPump(*gServicePump);
|
||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
||||
|
||||
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
|
||||
|
||||
LLVoiceChannel::initClass();
|
||||
LLVoiceClient::getInstance()->init(gServicePump);
|
||||
LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
|
||||
|
||||
joystick = LLViewerJoystick::getInstance();
|
||||
joystick->setNeedsReset(true);
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
// Ensure that this section of code never gets called again on OS X.
|
||||
mMainLoopInitialized = true;
|
||||
#endif
|
||||
}
|
||||
// As we do not (yet) send data on the mainloop LLEventPump that varies
|
||||
// with each frame, no need to instantiate a new LLSD event object each
|
||||
// time. Obviously, if that changes, just instantiate the LLSD at the
|
||||
// point of posting.
|
||||
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
|
||||
LLSD newFrame;
|
||||
|
||||
//-------------------------------------------
|
||||
// Run main loop until time to quit
|
||||
//-------------------------------------------
|
||||
|
||||
// Create IO Pump to use for HTTP Requests.
|
||||
gServicePump = new LLPumpIO(gAPRPoolp);
|
||||
LLHTTPClient::setPump(*gServicePump);
|
||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
||||
|
||||
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
|
||||
|
||||
LLVoiceChannel::initClass();
|
||||
LLVoiceClient::getInstance()->init(gServicePump);
|
||||
LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
|
||||
LLTimer frameTimer,idleTimer;
|
||||
LLTimer debugTime;
|
||||
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
|
||||
joystick->setNeedsReset(true);
|
||||
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
// As we do not (yet) send data on the mainloop LLEventPump that varies
|
||||
// with each frame, no need to instantiate a new LLSD event object each
|
||||
// time. Obviously, if that changes, just instantiate the LLSD at the
|
||||
// point of posting.
|
||||
LLSD newFrame;
|
||||
|
||||
|
||||
//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
|
||||
//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
|
||||
//LLPrivateMemoryPoolTester::destroy() ;
|
||||
|
||||
// Handle messages
|
||||
#ifdef LL_DARWIN
|
||||
if (!LLApp::isExiting())
|
||||
#else
|
||||
while (!LLApp::isExiting())
|
||||
#endif
|
||||
{
|
||||
LLFastTimer _(FTM_FRAME);
|
||||
LLFastTimer::nextFrame();
|
||||
|
|
@ -1562,34 +1584,37 @@ bool LLAppViewer::mainLoop()
|
|||
}
|
||||
}
|
||||
|
||||
// Save snapshot for next time, if we made it through initialization
|
||||
if (STATE_STARTED == LLStartUp::getStartupState())
|
||||
if (LLApp::isExiting())
|
||||
{
|
||||
try
|
||||
// Save snapshot for next time, if we made it through initialization
|
||||
if (STATE_STARTED == LLStartUp::getStartupState())
|
||||
{
|
||||
saveFinalSnapshot();
|
||||
}
|
||||
catch(std::bad_alloc)
|
||||
{
|
||||
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
|
||||
|
||||
//stop memory leaking simulation
|
||||
LLFloaterMemLeak* mem_leak_instance =
|
||||
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
|
||||
if(mem_leak_instance)
|
||||
try
|
||||
{
|
||||
mem_leak_instance->stop() ;
|
||||
}
|
||||
saveFinalSnapshot();
|
||||
}
|
||||
catch(std::bad_alloc)
|
||||
{
|
||||
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
|
||||
|
||||
//stop memory leaking simulation
|
||||
LLFloaterMemLeak* mem_leak_instance =
|
||||
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
|
||||
if(mem_leak_instance)
|
||||
{
|
||||
mem_leak_instance->stop() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete gServicePump;
|
||||
|
||||
destroyMainloopTimeout();
|
||||
|
||||
llinfos << "Exiting main_loop" << llendflush;
|
||||
}
|
||||
|
||||
delete gServicePump;
|
||||
|
||||
destroyMainloopTimeout();
|
||||
|
||||
llinfos << "Exiting main_loop" << llendflush;
|
||||
|
||||
return true;
|
||||
return LLApp::isExiting();
|
||||
}
|
||||
|
||||
void LLAppViewer::flushVFSIO()
|
||||
|
|
@ -2667,8 +2692,6 @@ bool LLAppViewer::initConfiguration()
|
|||
//}
|
||||
|
||||
#if LL_DARWIN
|
||||
// Initialize apple menubar and various callbacks
|
||||
init_apple_menu(LLTrans::getString("APP_NAME").c_str());
|
||||
|
||||
#if __ppc__
|
||||
// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class LLImageDecodeThread;
|
|||
class LLTextureFetch;
|
||||
class LLWatchdogTimeout;
|
||||
class LLUpdaterService;
|
||||
class LLViewerJoystick;
|
||||
|
||||
extern LLFastTimer::DeclareTimer FTM_FRAME;
|
||||
|
||||
|
|
@ -255,6 +256,8 @@ private:
|
|||
std::string mSerialNumber;
|
||||
bool mPurgeCache;
|
||||
bool mPurgeOnExit;
|
||||
bool mMainLoopInitialized;
|
||||
LLViewerJoystick* joystick;
|
||||
|
||||
bool mSavedFinalSnapshot;
|
||||
bool mSavePerAccountSettings; // only save per account settings if login succeeded
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@
|
|||
#error "Use only with Mac OS X"
|
||||
#endif
|
||||
|
||||
#define LL_CARBON_CRASH_HANDLER 1
|
||||
|
||||
#include "llappviewermacosx.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#include "llcommandlineparser.h"
|
||||
|
||||
#include "llviewernetwork.h"
|
||||
|
|
@ -38,7 +41,10 @@
|
|||
#include "llmd5.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llurldispatcher.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#ifdef LL_CARBON_CRASH_HANDLER
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
#include "lldir.h"
|
||||
#include <signal.h>
|
||||
#include <CoreAudio/CoreAudio.h> // for systemwide mute
|
||||
|
|
@ -50,9 +56,9 @@ namespace
|
|||
// They are not used immediately by the app.
|
||||
int gArgC;
|
||||
char** gArgV;
|
||||
|
||||
bool sCrashReporterIsRunning = false;
|
||||
|
||||
LLAppViewerMacOSX* gViewerAppPtr;
|
||||
#ifdef LL_CARBON_CRASH_HANDLER
|
||||
OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
|
||||
{
|
||||
OSErr result = noErr;
|
||||
|
|
@ -61,9 +67,10 @@ namespace
|
|||
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
bool initViewer()
|
||||
{
|
||||
#if LL_SOLARIS && defined(__sparc)
|
||||
asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
|
||||
|
|
@ -73,43 +80,60 @@ int main( int argc, char **argv )
|
|||
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
|
||||
{
|
||||
llwarns << "Could not change directory to "
|
||||
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
|
||||
<< llendl;
|
||||
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
|
||||
<< llendl;
|
||||
}
|
||||
|
||||
LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX();
|
||||
|
||||
viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
|
||||
|
||||
// Store off the command line args for use later.
|
||||
gArgC = argc;
|
||||
gArgV = argv;
|
||||
|
||||
bool ok = viewer_app_ptr->init();
|
||||
gViewerAppPtr = new LLAppViewerMacOSX();
|
||||
|
||||
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
|
||||
|
||||
|
||||
|
||||
bool ok = gViewerAppPtr->init();
|
||||
if(!ok)
|
||||
{
|
||||
llwarns << "Application init failed." << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Run the application main loop
|
||||
if(!LLApp::isQuitting())
|
||||
{
|
||||
viewer_app_ptr->mainLoop();
|
||||
}
|
||||
void handleQuit()
|
||||
{
|
||||
LLAppViewer::instance()->userQuit();
|
||||
}
|
||||
|
||||
if (!LLApp::isError())
|
||||
bool runMainLoop()
|
||||
{
|
||||
bool ret = LLApp::isQuitting();
|
||||
if (!ret && gViewerAppPtr != NULL)
|
||||
{
|
||||
//
|
||||
// We don't want to do cleanup here if the error handler got called -
|
||||
// the assumption is that the error handler is responsible for doing
|
||||
// app cleanup if there was a problem.
|
||||
//
|
||||
viewer_app_ptr->cleanup();
|
||||
ret = gViewerAppPtr->mainLoop();
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
delete viewer_app_ptr;
|
||||
viewer_app_ptr = NULL;
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cleanupViewer()
|
||||
{
|
||||
if(!LLApp::isError())
|
||||
{
|
||||
gViewerAppPtr->cleanup();
|
||||
}
|
||||
|
||||
delete gViewerAppPtr;
|
||||
gViewerAppPtr = NULL;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
// Store off the command line args for use later.
|
||||
gArgC = argc;
|
||||
gArgV = argv;
|
||||
return createNSApp(argc, (const char**)argv);
|
||||
}
|
||||
|
||||
LLAppViewerMacOSX::LLAppViewerMacOSX()
|
||||
|
|
@ -239,23 +263,24 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
|
|||
return reset_count == 0;
|
||||
}
|
||||
|
||||
static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
|
||||
EventRef inEvent,
|
||||
#ifdef LL_CARBON_CRASH_HANDLER
|
||||
static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
|
||||
EventRef inEvent,
|
||||
void* inUserData)
|
||||
{
|
||||
ProcessSerialNumber psn;
|
||||
|
||||
GetEventParameter(inEvent,
|
||||
kEventParamProcessID,
|
||||
typeProcessSerialNumber,
|
||||
NULL,
|
||||
sizeof(psn),
|
||||
NULL,
|
||||
GetEventParameter(inEvent,
|
||||
kEventParamProcessID,
|
||||
typeProcessSerialNumber,
|
||||
NULL,
|
||||
sizeof(psn),
|
||||
NULL,
|
||||
&psn);
|
||||
|
||||
if( GetEventKind(inEvent) == kEventAppTerminated )
|
||||
if( GetEventKind(inEvent) == kEventAppTerminated )
|
||||
{
|
||||
Boolean matching_psn = FALSE;
|
||||
Boolean matching_psn = FALSE;
|
||||
OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn);
|
||||
if(os_result >= 0 && matching_psn)
|
||||
{
|
||||
|
|
@ -265,48 +290,58 @@ static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
|
|||
}
|
||||
return noErr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
|
||||
{
|
||||
// This used to use fork&exec, but is switched to LSOpenApplication to
|
||||
#ifdef LL_CARBON_CRASH_HANDLER
|
||||
// This used to use fork&exec, but is switched to LSOpenApplication to
|
||||
// Make sure the crash reporter launches in front of the SL window.
|
||||
|
||||
std::string command_str;
|
||||
//command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app";
|
||||
command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger";
|
||||
|
||||
CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE);
|
||||
|
||||
// FSRef apparently isn't deprecated.
|
||||
// There's other funcitonality that depends on it existing as well that isn't deprecated.
|
||||
// There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated.
|
||||
// We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar.
|
||||
|
||||
FSRef appRef;
|
||||
Boolean isDir = 0;
|
||||
OSStatus os_result = FSPathMakeRef((UInt8*)command_str.c_str(),
|
||||
&appRef,
|
||||
&isDir);
|
||||
if(os_result >= 0)
|
||||
Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef);
|
||||
|
||||
OSStatus os_result = noErr;
|
||||
|
||||
if(pathstatus == true)
|
||||
{
|
||||
LSApplicationParameters appParams;
|
||||
memset(&appParams, 0, sizeof(appParams));
|
||||
appParams.version = 0;
|
||||
appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic;
|
||||
|
||||
appParams.application = &appRef;
|
||||
|
||||
if(reportFreeze)
|
||||
{
|
||||
// Make sure freeze reporting launches the crash logger synchronously, lest
|
||||
// Make sure freeze reporting launches the crash logger synchronously, lest
|
||||
// Log files get changed by SL while the logger is running.
|
||||
|
||||
|
||||
// *NOTE:Mani A better way - make a copy of the data that the crash reporter will send
|
||||
// and let SL go about its business. This way makes the mac work like windows and linux
|
||||
// and is the smallest patch for the issue.
|
||||
// and is the smallest patch for the issue.
|
||||
sCrashReporterIsRunning = false;
|
||||
ProcessSerialNumber o_psn;
|
||||
|
||||
|
||||
static EventHandlerRef sCarbonEventsRef = NULL;
|
||||
static const EventTypeSpec kEvents[] =
|
||||
static const EventTypeSpec kEvents[] =
|
||||
{
|
||||
{ kEventClassApplication, kEventAppTerminated }
|
||||
};
|
||||
|
||||
// Install the handler to detect crash logger termination
|
||||
InstallEventHandler(GetApplicationEventTarget(),
|
||||
InstallEventHandler(GetApplicationEventTarget(),
|
||||
(EventHandlerUPP) CarbonEventHandler,
|
||||
GetEventTypeCount(kEvents),
|
||||
kEvents,
|
||||
|
|
@ -314,31 +349,31 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
|
|||
&sCarbonEventsRef
|
||||
);
|
||||
|
||||
// Remove, temporarily the quit handler - which has *crash* behavior before
|
||||
// Remove, temporarily the quit handler - which has *crash* behavior before
|
||||
// the mainloop gets running!
|
||||
AERemoveEventHandler(kCoreEventClass,
|
||||
kAEQuitApplication,
|
||||
AERemoveEventHandler(kCoreEventClass,
|
||||
kAEQuitApplication,
|
||||
NewAEEventHandlerUPP(AEQuitHandler),
|
||||
false);
|
||||
|
||||
|
||||
// Launch the crash reporter.
|
||||
os_result = LSOpenApplication(&appParams, &o_psn);
|
||||
|
||||
if(os_result >= 0)
|
||||
{
|
||||
{
|
||||
sCrashReporterIsRunning = true;
|
||||
}
|
||||
|
||||
|
||||
while(sCrashReporterIsRunning)
|
||||
{
|
||||
RunApplicationEventLoop();
|
||||
}
|
||||
|
||||
|
||||
// Re-install the apps quit handler.
|
||||
AEInstallEventHandler(kCoreEventClass,
|
||||
kAEQuitApplication,
|
||||
AEInstallEventHandler(kCoreEventClass,
|
||||
kAEQuitApplication,
|
||||
NewAEEventHandlerUPP(AEQuitHandler),
|
||||
0,
|
||||
0,
|
||||
false);
|
||||
|
||||
// Remove the crash reporter quit handler.
|
||||
|
|
@ -348,12 +383,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
|
|||
{
|
||||
appParams.flags |= kLSLaunchAsync;
|
||||
clear_signals();
|
||||
|
||||
|
||||
ProcessSerialNumber o_psn;
|
||||
os_result = LSOpenApplication(&appParams, &o_psn);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string LLAppViewerMacOSX::generateSerialNumber()
|
||||
|
|
@ -486,73 +521,3 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
|
|||
|
||||
return(result);
|
||||
}
|
||||
|
||||
OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
|
||||
{
|
||||
OSStatus result = eventNotHandledErr;
|
||||
OSStatus err;
|
||||
UInt32 evtClass = GetEventClass(event);
|
||||
UInt32 evtKind = GetEventKind(event);
|
||||
WindowRef window = (WindowRef)userdata;
|
||||
|
||||
if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
|
||||
{
|
||||
HICommand cmd;
|
||||
err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
|
||||
|
||||
if(err == noErr)
|
||||
{
|
||||
switch(cmd.commandID)
|
||||
{
|
||||
case kHICommandOK:
|
||||
QuitAppModalLoopForWindow(window);
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kHICommandCancel:
|
||||
QuitAppModalLoopForWindow(window);
|
||||
result = userCanceledErr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
void init_apple_menu(const char* product)
|
||||
{
|
||||
// Load up a proper menu bar.
|
||||
{
|
||||
OSStatus err;
|
||||
IBNibRef nib = NULL;
|
||||
// NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly.
|
||||
err = CreateNibReference(CFSTR("SecondLife"), &nib);
|
||||
|
||||
if(err == noErr)
|
||||
{
|
||||
// NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly.
|
||||
SetMenuBarFromNib(nib, CFSTR("MenuBar"));
|
||||
}
|
||||
|
||||
if(nib != NULL)
|
||||
{
|
||||
DisposeNibReference(nib);
|
||||
}
|
||||
}
|
||||
|
||||
// Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer.
|
||||
|
||||
if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr)
|
||||
{
|
||||
// Couldn't install AppleEvent handler. This error shouldn't be fatal.
|
||||
llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl;
|
||||
}
|
||||
|
||||
// Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work.
|
||||
if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr)
|
||||
{
|
||||
// Couldn't install AppleEvent handler. This error shouldn't be fatal.
|
||||
llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "llwindow.h" // beforeDialog()
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
#if LL_LINUX || LL_SOLARIS || LL_DARWIN
|
||||
# include "llfilepicker.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -147,152 +147,36 @@ std::string LLDirPicker::getDirName()
|
|||
#elif LL_DARWIN
|
||||
|
||||
LLDirPicker::LLDirPicker() :
|
||||
mFileName(NULL),
|
||||
mLocked(false)
|
||||
mFileName(NULL),
|
||||
mLocked(false)
|
||||
{
|
||||
mFilePicker = new LLFilePicker();
|
||||
reset();
|
||||
|
||||
memset(&mNavOptions, 0, sizeof(mNavOptions));
|
||||
OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
|
||||
if (error == noErr)
|
||||
{
|
||||
mNavOptions.modality = kWindowModalityAppModal;
|
||||
}
|
||||
}
|
||||
|
||||
LLDirPicker::~LLDirPicker()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
//static
|
||||
pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
|
||||
NavCBRecPtr callBackParms, void* callBackUD)
|
||||
{
|
||||
switch(callBackSelector)
|
||||
{
|
||||
case kNavCBStart:
|
||||
{
|
||||
if (!sInstance.mFileName) break;
|
||||
|
||||
OSStatus error = noErr;
|
||||
AEDesc theLocation = {typeNull, NULL};
|
||||
FSSpec outFSSpec;
|
||||
|
||||
//Convert string to a FSSpec
|
||||
FSRef myFSRef;
|
||||
|
||||
const char* filename=sInstance.mFileName->c_str();
|
||||
|
||||
error = FSPathMakeRef ((UInt8*)filename, &myFSRef, NULL);
|
||||
|
||||
if (error != noErr) break;
|
||||
|
||||
error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL);
|
||||
|
||||
if (error != noErr) break;
|
||||
|
||||
error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation);
|
||||
|
||||
if (error != noErr) break;
|
||||
|
||||
error = NavCustomControl(callBackParms->context,
|
||||
kNavCtlSetLocation, (void*)&theLocation);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus LLDirPicker::doNavChooseDialog()
|
||||
{
|
||||
OSStatus error = noErr;
|
||||
NavDialogRef navRef = NULL;
|
||||
NavReplyRecord navReply;
|
||||
|
||||
memset(&navReply, 0, sizeof(navReply));
|
||||
|
||||
// NOTE: we are passing the address of a local variable here.
|
||||
// This is fine, because the object this call creates will exist for less than the lifetime of this function.
|
||||
// (It is destroyed by NavDialogDispose() below.)
|
||||
|
||||
error = NavCreateChooseFolderDialog(&mNavOptions, &doNavCallbackEvent, NULL, NULL, &navRef);
|
||||
|
||||
gViewerWindow->getWindow()->beforeDialog();
|
||||
|
||||
if (error == noErr)
|
||||
error = NavDialogRun(navRef);
|
||||
|
||||
gViewerWindow->getWindow()->afterDialog();
|
||||
|
||||
if (error == noErr)
|
||||
error = NavDialogGetReply(navRef, &navReply);
|
||||
|
||||
if (navRef)
|
||||
NavDialogDispose(navRef);
|
||||
|
||||
if (error == noErr && navReply.validRecord)
|
||||
{
|
||||
FSRef fsRef;
|
||||
AEKeyword theAEKeyword;
|
||||
DescType typeCode;
|
||||
Size actualSize = 0;
|
||||
char path[LL_MAX_PATH]; /*Flawfinder: ignore*/
|
||||
|
||||
memset(&fsRef, 0, sizeof(fsRef));
|
||||
error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
|
||||
|
||||
if (error == noErr)
|
||||
error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
|
||||
|
||||
if (error == noErr)
|
||||
mDir = path;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
BOOL LLDirPicker::getDir(std::string* filename)
|
||||
{
|
||||
if( mLocked ) return FALSE;
|
||||
BOOL success = FALSE;
|
||||
OSStatus error = noErr;
|
||||
|
||||
// if local file browsing is turned off, return without opening dialog
|
||||
if ( check_local_file_access_enabled() == false )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mFileName = filename;
|
||||
|
||||
// mNavOptions.saveFileName
|
||||
|
||||
// Modal, so pause agent
|
||||
send_agent_pause();
|
||||
{
|
||||
error = doNavChooseDialog();
|
||||
}
|
||||
send_agent_resume();
|
||||
if (error == noErr)
|
||||
{
|
||||
if (mDir.length() > 0)
|
||||
success = true;
|
||||
}
|
||||
|
||||
// Account for the fact that the app has been stalled.
|
||||
LLFrameTimer::updateFrameTime();
|
||||
return success;
|
||||
}
|
||||
|
||||
std::string LLDirPicker::getDirName()
|
||||
{
|
||||
return mDir;
|
||||
delete mFilePicker;
|
||||
}
|
||||
|
||||
void LLDirPicker::reset()
|
||||
{
|
||||
mLocked = false;
|
||||
mDir.clear();
|
||||
if (mFilePicker)
|
||||
mFilePicker->reset();
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
BOOL LLDirPicker::getDir(std::string* filename)
|
||||
{
|
||||
LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
|
||||
|
||||
return mFilePicker->getOpenFile(filter, true);
|
||||
}
|
||||
|
||||
std::string LLDirPicker::getDirName()
|
||||
{
|
||||
return mFilePicker->getFirstFile();
|
||||
}
|
||||
|
||||
#elif LL_LINUX || LL_SOLARIS
|
||||
|
|
|
|||
|
|
@ -34,11 +34,10 @@
|
|||
#include "stdtypes.h"
|
||||
|
||||
#if LL_DARWIN
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
#include "fix_macros.h"
|
||||
#undef verify
|
||||
#undef check
|
||||
#undef require
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -77,15 +76,7 @@ private:
|
|||
void buildDirname( void );
|
||||
bool check_local_file_access_enabled();
|
||||
|
||||
#if LL_DARWIN
|
||||
NavDialogCreationOptions mNavOptions;
|
||||
static pascal void doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
|
||||
NavCBRecPtr callBackParms, void* callBackUD);
|
||||
OSStatus doNavChooseDialog();
|
||||
|
||||
#endif
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
#if LL_LINUX || LL_SOLARIS || LL_DARWIN
|
||||
// On Linux we just implement LLDirPicker on top of LLFilePicker
|
||||
LLFilePicker *mFilePicker;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -132,10 +132,16 @@ void LLDrawable::destroy()
|
|||
sNumZombieDrawables--;
|
||||
}
|
||||
|
||||
// Attempt to catch violations of this in debug,
|
||||
// knowing that some false alarms may result
|
||||
//
|
||||
llassert(!LLSpatialGroup::sNoDelete);
|
||||
|
||||
/* cannot be guaranteed and causes crashes on false alarms
|
||||
if (LLSpatialGroup::sNoDelete)
|
||||
{
|
||||
llerrs << "Illegal deletion of LLDrawable!" << llendl;
|
||||
}
|
||||
}*/
|
||||
|
||||
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
|
||||
mFaces.clear();
|
||||
|
|
@ -527,6 +533,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
|
|||
}
|
||||
updatePartition();
|
||||
}
|
||||
|
||||
llassert(isAvatar() || isRoot() || mParent->isStatic());
|
||||
}
|
||||
|
||||
// Returns "distance" between target destination and resulting xfrom
|
||||
|
|
|
|||
|
|
@ -93,15 +93,35 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
|
|||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
simple_shader = &gDeferredAlphaImpostorProgram;
|
||||
fullbright_shader = &gDeferredFullbrightProgram;
|
||||
}
|
||||
else if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gDeferredAlphaWaterProgram;
|
||||
fullbright_shader = &gDeferredFullbrightWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_shader = &gDeferredAlphaProgram;
|
||||
fullbright_shader = &gObjectFullbrightProgram;
|
||||
fullbright_shader = &gDeferredFullbrightProgram;
|
||||
}
|
||||
|
||||
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
|
||||
fullbright_shader->bind();
|
||||
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
fullbright_shader->unbind();
|
||||
|
||||
//prime simple shader (loads shadow relevant uniforms)
|
||||
gPipeline.bindDeferredShader(*simple_shader);
|
||||
|
||||
simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
else
|
||||
else if (!LLPipeline::sImpostorRender)
|
||||
{
|
||||
//update depth buffer sampler
|
||||
gPipeline.mScreen.flush();
|
||||
|
|
@ -113,6 +133,23 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
|
|||
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
|
||||
}
|
||||
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
emissive_shader = &gDeferredEmissiveProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
emissive_shader = &gObjectEmissiveWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
emissive_shader = &gObjectEmissiveProgram;
|
||||
}
|
||||
}
|
||||
|
||||
deferred_render = TRUE;
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
|
|
@ -124,7 +161,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
|
|||
|
||||
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
|
||||
{
|
||||
if (pass == 1)
|
||||
if (pass == 1 && !LLPipeline::sImpostorRender)
|
||||
{
|
||||
gPipeline.mDeferredDepth.flush();
|
||||
gPipeline.mScreen.bindTarget();
|
||||
|
|
@ -144,7 +181,13 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
|
|||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleImpostorProgram;
|
||||
fullbright_shader = &gObjectFullbrightProgram;
|
||||
emissive_shader = &gObjectEmissiveProgram;
|
||||
}
|
||||
else if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleWaterProgram;
|
||||
fullbright_shader = &gObjectFullbrightWaterProgram;
|
||||
|
|
@ -192,8 +235,13 @@ void LLDrawPoolAlpha::render(S32 pass)
|
|||
gGL.setColorMask(true, true);
|
||||
}
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
|
||||
(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
|
||||
bool write_depth = LLDrawPoolWater::sSkipScreenCopy
|
||||
|| (deferred_render && pass == 1)
|
||||
// we want depth written so that rendered alpha will
|
||||
// contribute to the alpha mask used for impostors
|
||||
|| LLPipeline::sImpostorRenderAlphaDepthPass;
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
|
||||
|
||||
if (deferred_render && pass == 1)
|
||||
{
|
||||
|
|
@ -239,11 +287,11 @@ void LLDrawPoolAlpha::render(S32 pass)
|
|||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
|
||||
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderAlpha(getVertexDataMask());
|
||||
renderAlpha(getVertexDataMask(), pass);
|
||||
}
|
||||
|
||||
gGL.setColorMask(true, false);
|
||||
|
|
@ -315,7 +363,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
|||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
||||
{
|
||||
BOOL initialized_lighting = FALSE;
|
||||
BOOL light_enabled = TRUE;
|
||||
|
|
@ -348,11 +396,28 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
|||
continue;
|
||||
}
|
||||
|
||||
// Fix for bug - NORSPEC-271
|
||||
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
|
||||
// We don't want the nearly invisible objects to cause of DoF effects
|
||||
if(pass == 1 && !LLPipeline::sImpostorRender)
|
||||
{
|
||||
LLFace* face = params.mFace;
|
||||
if(face)
|
||||
{
|
||||
const LLTextureEntry* tep = face->getTextureEntry();
|
||||
if(tep)
|
||||
{
|
||||
if(tep->getColor().mV[3] < 0.1f)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLRenderPass::applyModelMatrix(params);
|
||||
|
||||
LLMaterial* mat = NULL;
|
||||
|
||||
if (deferred_render && !LLPipeline::sUnderWaterRender)
|
||||
if (deferred_render)
|
||||
{
|
||||
mat = params.mMaterial;
|
||||
}
|
||||
|
|
@ -396,6 +461,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
|||
llassert(mask < LLMaterial::SHADER_COUNT);
|
||||
target_shader = &(gDeferredMaterialProgram[mask]);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
target_shader = &(gDeferredMaterialWaterProgram[mask]);
|
||||
}
|
||||
|
||||
if (current_shader != target_shader)
|
||||
{
|
||||
gPipeline.bindDeferredShader(*target_shader);
|
||||
|
|
@ -500,7 +570,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
|||
}
|
||||
}
|
||||
|
||||
params.mVertexBuffer->setBuffer(mask);
|
||||
params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
|
||||
|
||||
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
|
||||
|
||||
|
|
@ -515,7 +586,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
|||
|
||||
emissive_shader->bind();
|
||||
|
||||
// glow doesn't use vertex colors from the mesh data
|
||||
params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
|
||||
|
||||
// do the actual drawing, again
|
||||
|
|
@ -545,3 +615,4 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
|||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public:
|
|||
/*virtual*/ void prerender();
|
||||
|
||||
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
|
||||
void renderAlpha(U32 mask);
|
||||
void renderAlpha(U32 mask, S32 pass);
|
||||
void renderAlphaHighlight(U32 mask);
|
||||
|
||||
static BOOL sShowDebugAlpha;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "llappviewer.h"
|
||||
#include "llrendersphere.h"
|
||||
#include "llviewerpartsim.h"
|
||||
#include "llviewercontrol.h" // for gSavedSettings
|
||||
|
||||
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
|
||||
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
|
||||
|
|
@ -309,6 +310,11 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
|
|||
|
||||
sVertexProgram = &gDeferredMaterialProgram[pass];
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
sVertexProgram = &(gDeferredMaterialWaterProgram[pass]);
|
||||
}
|
||||
|
||||
gPipeline.bindDeferredShader(*sVertexProgram);
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
|
||||
|
|
@ -501,7 +507,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
|
|||
{
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
return 3;
|
||||
return 19;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -687,12 +693,10 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
|
|||
}
|
||||
|
||||
sVertexProgram = &gDeferredImpostorProgram;
|
||||
|
||||
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
|
||||
sVertexProgram->bind();
|
||||
gPipeline.bindDeferredShader(*sVertexProgram);
|
||||
sVertexProgram->setMinimumAlpha(0.01f);
|
||||
}
|
||||
|
||||
|
|
@ -702,8 +706,9 @@ void LLDrawPoolAvatar::endDeferredImpostor()
|
|||
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
sVertexProgram->unbind();
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gPipeline.unbindDeferredShader(*sVertexProgram);
|
||||
sVertexProgram = NULL;
|
||||
sDiffuseChannel = 0;
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredRigid()
|
||||
|
|
@ -891,6 +896,8 @@ void LLDrawPoolAvatar::beginRiggedGlow()
|
|||
sVertexProgram->bind();
|
||||
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
|
||||
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -943,6 +950,9 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
|
|||
else
|
||||
{
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
|
||||
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1044,6 +1054,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
|
|||
else
|
||||
{
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1103,6 +1115,12 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
|
|||
return;
|
||||
}
|
||||
sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT];
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]);
|
||||
}
|
||||
|
||||
sVertexProgram->bind();
|
||||
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
|
||||
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
|
|
@ -1445,63 +1463,63 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
|
||||
void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
|
||||
{
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
{
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
|
||||
//rigged faces do not batch textures
|
||||
face->setTextureIndex(255);
|
||||
//rigged faces do not batch textures
|
||||
face->setTextureIndex(255);
|
||||
|
||||
if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
|
||||
{ //make a new buffer
|
||||
if (sShaderLevel > 0)
|
||||
if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
|
||||
{ //make a new buffer
|
||||
if (sShaderLevel > 0)
|
||||
{
|
||||
buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
|
||||
}
|
||||
buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
|
||||
}
|
||||
else
|
||||
{ //resize existing buffer
|
||||
buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
|
||||
}
|
||||
|
||||
face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
|
||||
face->setVertexBuffer(buffer);
|
||||
|
||||
U16 offset = 0;
|
||||
|
||||
LLMatrix4 mat_vert = skin->mBindShapeMatrix;
|
||||
glh::matrix4f m((F32*) mat_vert.mMatrix);
|
||||
m = m.inverse().transpose();
|
||||
|
||||
F32 mat3[] =
|
||||
{ m.m[0], m.m[1], m.m[2],
|
||||
m.m[4], m.m[5], m.m[6],
|
||||
m.m[8], m.m[9], m.m[10] };
|
||||
|
||||
LLMatrix3 mat_normal(mat3);
|
||||
|
||||
//let getGeometryVolume know if alpha should override shiny
|
||||
U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
|
||||
|
||||
if (type == LLDrawPool::POOL_ALPHA)
|
||||
{
|
||||
buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
|
||||
face->setPoolType(LLDrawPool::POOL_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
|
||||
face->setPoolType(LLDrawPool::POOL_AVATAR);
|
||||
}
|
||||
buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
|
||||
}
|
||||
else
|
||||
{ //resize existing buffer
|
||||
buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
|
||||
}
|
||||
|
||||
face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
|
||||
face->setVertexBuffer(buffer);
|
||||
|
||||
U16 offset = 0;
|
||||
|
||||
LLMatrix4 mat_vert = skin->mBindShapeMatrix;
|
||||
glh::matrix4f m((F32*) mat_vert.mMatrix);
|
||||
m = m.inverse().transpose();
|
||||
|
||||
F32 mat3[] =
|
||||
{ m.m[0], m.m[1], m.m[2],
|
||||
m.m[4], m.m[5], m.m[6],
|
||||
m.m[8], m.m[9], m.m[10] };
|
||||
|
||||
LLMatrix3 mat_normal(mat3);
|
||||
|
||||
//let getGeometryVolume know if alpha should override shiny
|
||||
U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
|
||||
|
||||
if (type == LLDrawPool::POOL_ALPHA)
|
||||
{
|
||||
face->setPoolType(LLDrawPool::POOL_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
face->setPoolType(LLDrawPool::POOL_AVATAR);
|
||||
}
|
||||
|
||||
//llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl;
|
||||
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
|
||||
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
|
||||
|
||||
buffer->flush();
|
||||
}
|
||||
buffer->flush();
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -72,6 +72,12 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
|
|||
};
|
||||
|
||||
mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
|
||||
}
|
||||
|
||||
mShader->bind();
|
||||
|
||||
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
|
||||
|
|
@ -215,3 +221,4 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
|
|||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llviewershadermgr.h"
|
||||
#include "llrender.h"
|
||||
|
||||
#define GE_FORCE_WORKAROUND LL_DARWIN
|
||||
|
||||
static LLGLSLShader* simple_shader = NULL;
|
||||
static LLGLSLShader* fullbright_shader = NULL;
|
||||
|
|
@ -111,7 +112,14 @@ void LLDrawPoolGlow::render(S32 pass)
|
|||
|
||||
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
|
||||
shader->bind();
|
||||
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
|
||||
}
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
gGL.setColorMask(false, true);
|
||||
|
|
@ -148,7 +156,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
|
|||
{
|
||||
LLFastTimer t(FTM_RENDER_SIMPLE);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleImpostorProgram;
|
||||
}
|
||||
else if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleWaterProgram;
|
||||
}
|
||||
|
|
@ -536,7 +548,15 @@ void LLDrawPoolFullbright::prerender()
|
|||
|
||||
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
|
||||
{
|
||||
gDeferredFullbrightProgram.bind();
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightWaterProgram.bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightProgram.bind();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
|
||||
|
|
@ -550,7 +570,14 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
|
|||
|
||||
void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
|
||||
{
|
||||
gDeferredFullbrightProgram.unbind();
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightWaterProgram.unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightProgram.unbind();
|
||||
}
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
}
|
||||
|
||||
|
|
@ -625,15 +652,35 @@ S32 LLDrawPoolFullbright::getNumPasses()
|
|||
|
||||
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
|
||||
{
|
||||
gObjectFullbrightAlphaMaskProgram.bind();
|
||||
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
gObjectFullbrightAlphaMaskProgram.bind();
|
||||
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
|
||||
// Work-around until we can figure out why the right shader causes
|
||||
// the GeForce driver to go tango uniform on OS X 10.6.8 only
|
||||
//
|
||||
#if GE_FORCE_WORKAROUND
|
||||
gObjectFullbrightAlphaMaskProgram.bind();
|
||||
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
#else
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskWaterProgram.bind();
|
||||
gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskProgram.bind();
|
||||
gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
|
||||
|
|
@ -646,7 +693,30 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
|
|||
|
||||
void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
|
||||
{
|
||||
gObjectFullbrightAlphaMaskProgram.unbind();
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
gObjectFullbrightAlphaMaskProgram.unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Work-around until we can figure out why the right shader causes
|
||||
// the GeForce driver to go tango uniform on OS X 10.6.8 only
|
||||
//
|
||||
#if GE_FORCE_WORKAROUND
|
||||
gObjectFullbrightAlphaMaskProgram.unbind();
|
||||
#else
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskWaterProgram.unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskProgram.unbind();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)
|
|||
void LLDrawPoolSky::endRenderPass( S32 pass )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -522,14 +522,21 @@ void LLDrawPoolWater::shade()
|
|||
|
||||
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
|
||||
|
||||
if (deferred_render)
|
||||
if (eyedepth < 0.f && LLPipeline::sWaterReflections)
|
||||
{
|
||||
if (deferred_render)
|
||||
{
|
||||
shader = &gDeferredUnderWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gUnderWaterProgram;
|
||||
}
|
||||
}
|
||||
else if (deferred_render)
|
||||
{
|
||||
shader = &gDeferredWaterProgram;
|
||||
}
|
||||
else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
|
||||
{
|
||||
shader = &gUnderWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gWaterProgram;
|
||||
|
|
|
|||
|
|
@ -420,3 +420,4 @@ void LLDrawPoolWLSky::restoreGL()
|
|||
sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -821,21 +821,21 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
|||
{
|
||||
v[i].setSelectWithMask(mask[i], min, max);
|
||||
}
|
||||
|
||||
|
||||
LLVector4a tv[8];
|
||||
|
||||
|
||||
//transform bounding box into drawable space
|
||||
for (U32 i = 0; i < 8; ++i)
|
||||
{
|
||||
mat_vert.affineTransform(v[i], tv[i]);
|
||||
}
|
||||
|
||||
|
||||
//find bounding box
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
|
||||
|
||||
newMin = newMax = tv[0];
|
||||
|
||||
|
||||
for (U32 i = 1; i < 8; ++i)
|
||||
{
|
||||
newMin.setMin(newMin, tv[i]);
|
||||
|
|
@ -851,11 +851,11 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
|||
}
|
||||
|
||||
LLVector4a t;
|
||||
t.setAdd(newMin,newMax);
|
||||
t.setAdd(newMin, newMax);
|
||||
t.mul(0.5f);
|
||||
|
||||
mCenterLocal.set(t.getF32ptr());
|
||||
|
||||
|
||||
t.setSub(newMax,newMin);
|
||||
mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
|
||||
|
||||
|
|
|
|||
|
|
@ -194,8 +194,7 @@ public:
|
|||
|
||||
void setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
|
||||
|
||||
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
const LLMatrix4& mat, BOOL global_volume = FALSE);
|
||||
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE);
|
||||
|
||||
void init(LLDrawable* drawablep, LLViewerObject* objp);
|
||||
void destroy();
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ LLFilePicker LLFilePicker::sInstance;
|
|||
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
|
||||
#endif
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
#include "llfilepicker_mac.h"
|
||||
//#include <boost/algorithm/string/predicate.hpp>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
|
@ -94,14 +99,6 @@ LLFilePicker::LLFilePicker()
|
|||
mFilesW[0] = '\0';
|
||||
#endif
|
||||
|
||||
#if LL_DARWIN
|
||||
memset(&mNavOptions, 0, sizeof(mNavOptions));
|
||||
OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
|
||||
if (error == noErr)
|
||||
{
|
||||
mNavOptions.modality = kWindowModalityAppModal;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
LLFilePicker::~LLFilePicker()
|
||||
|
|
@ -546,369 +543,197 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
|
|||
|
||||
#elif LL_DARWIN
|
||||
|
||||
Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
|
||||
std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
|
||||
{
|
||||
Boolean result = true;
|
||||
ELoadFilter filter = *((ELoadFilter*) callBackUD);
|
||||
OSStatus error = noErr;
|
||||
|
||||
if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS))
|
||||
{
|
||||
// navInfo is only valid for typeFSRef and typeFSS
|
||||
NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info;
|
||||
if (!navInfo->isFolder)
|
||||
{
|
||||
AEDesc desc;
|
||||
error = AECoerceDesc(theItem, typeFSRef, &desc);
|
||||
if (error == noErr)
|
||||
{
|
||||
FSRef fileRef;
|
||||
error = AEGetDescData(&desc, &fileRef, sizeof(fileRef));
|
||||
if (error == noErr)
|
||||
{
|
||||
LSItemInfoRecord fileInfo;
|
||||
error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo);
|
||||
if (error == noErr)
|
||||
{
|
||||
if (filter == FFLOAD_IMAGE)
|
||||
{
|
||||
if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' &&
|
||||
fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' &&
|
||||
fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' &&
|
||||
fileInfo.filetype != 'PNG ' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
|
||||
CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
|
||||
CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
|
||||
CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
|
||||
CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
|
||||
)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (filter == FFLOAD_WAV)
|
||||
{
|
||||
if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
|
||||
CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
|
||||
)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (filter == FFLOAD_ANIM)
|
||||
{
|
||||
if (fileInfo.filetype != 'BVH ' &&
|
||||
fileInfo.filetype != 'ANIM' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
|
||||
fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("anim"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
|
||||
)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (filter == FFLOAD_COLLADA)
|
||||
{
|
||||
if (fileInfo.filetype != 'DAE ' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
|
||||
)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
std::vector<std::string> *allowedv = new std::vector< std::string >;
|
||||
switch(filter)
|
||||
{
|
||||
case FFLOAD_ALL:
|
||||
allowedv->push_back("wav");
|
||||
allowedv->push_back("bvh");
|
||||
allowedv->push_back("anim");
|
||||
allowedv->push_back("dae");
|
||||
allowedv->push_back("raw");
|
||||
allowedv->push_back("lsl");
|
||||
allowedv->push_back("dic");
|
||||
allowedv->push_back("xcu");
|
||||
case FFLOAD_IMAGE:
|
||||
allowedv->push_back("jpg");
|
||||
allowedv->push_back("jpeg");
|
||||
allowedv->push_back("bmp");
|
||||
allowedv->push_back("tga");
|
||||
allowedv->push_back("bmpf");
|
||||
allowedv->push_back("tpic");
|
||||
allowedv->push_back("png");
|
||||
break;
|
||||
case FFLOAD_WAV:
|
||||
allowedv->push_back("wav");
|
||||
break;
|
||||
case FFLOAD_ANIM:
|
||||
allowedv->push_back("bvh");
|
||||
allowedv->push_back("anim");
|
||||
break;
|
||||
case FFLOAD_COLLADA:
|
||||
allowedv->push_back("dae");
|
||||
break;
|
||||
#ifdef _CORY_TESTING
|
||||
else if (filter == FFLOAD_GEOMETRY)
|
||||
{
|
||||
if (fileInfo.filetype != 'SLG ' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
|
||||
)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
case FFLOAD_GEOMETRY:
|
||||
allowedv->push_back("slg");
|
||||
break;
|
||||
#endif
|
||||
else if (filter == FFLOAD_SLOBJECT)
|
||||
{
|
||||
llwarns << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << llendl;
|
||||
}
|
||||
else if (filter == FFLOAD_RAW)
|
||||
{
|
||||
if (fileInfo.filetype != '\?\?\?\?' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
|
||||
)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (filter == FFLOAD_SCRIPT)
|
||||
{
|
||||
if (fileInfo.filetype != 'LSL ' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) )
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (filter == FFLOAD_DICTIONARY)
|
||||
{
|
||||
if (fileInfo.filetype != 'DIC ' &&
|
||||
fileInfo.filetype != 'XCU ' &&
|
||||
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
|
||||
fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fileInfo.extension)
|
||||
{
|
||||
CFRelease(fileInfo.extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
AEDisposeDesc(&desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
case FFLOAD_RAW:
|
||||
allowedv->push_back("raw");
|
||||
break;
|
||||
case FFLOAD_SCRIPT:
|
||||
allowedv->push_back("lsl");
|
||||
break;
|
||||
case FFLOAD_DICTIONARY:
|
||||
allowedv->push_back("dic");
|
||||
allowedv->push_back("xcu");
|
||||
break;
|
||||
case FFLOAD_DIRECTORY:
|
||||
break;
|
||||
default:
|
||||
llwarns << "Unsupported format." << llendl;
|
||||
}
|
||||
|
||||
return allowedv;
|
||||
}
|
||||
|
||||
OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
|
||||
bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
|
||||
{
|
||||
OSStatus error = noErr;
|
||||
NavDialogRef navRef = NULL;
|
||||
NavReplyRecord navReply;
|
||||
|
||||
// if local file browsing is turned off, return without opening dialog
|
||||
if ( check_local_file_access_enabled() == false )
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&navReply, 0, sizeof(navReply));
|
||||
|
||||
// NOTE: we are passing the address of a local variable here.
|
||||
// This is fine, because the object this call creates will exist for less than the lifetime of this function.
|
||||
// (It is destroyed by NavDialogDispose() below.)
|
||||
error = NavCreateChooseFileDialog(&mNavOptions, NULL, NULL, NULL, navOpenFilterProc, (void*)(&filter), &navRef);
|
||||
|
||||
|
||||
gViewerWindow->getWindow()->beforeDialog();
|
||||
|
||||
if (error == noErr)
|
||||
error = NavDialogRun(navRef);
|
||||
|
||||
std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
|
||||
|
||||
std::vector<std::string> *filev = doLoadDialog(allowed_types,
|
||||
mPickOptions);
|
||||
|
||||
gViewerWindow->getWindow()->afterDialog();
|
||||
|
||||
if (error == noErr)
|
||||
error = NavDialogGetReply(navRef, &navReply);
|
||||
|
||||
if (navRef)
|
||||
NavDialogDispose(navRef);
|
||||
|
||||
if (error == noErr && navReply.validRecord)
|
||||
{
|
||||
SInt32 count = 0;
|
||||
SInt32 index;
|
||||
|
||||
// AE indexes are 1 based...
|
||||
error = AECountItems(&navReply.selection, &count);
|
||||
for (index = 1; index <= count; index++)
|
||||
{
|
||||
FSRef fsRef;
|
||||
AEKeyword theAEKeyword;
|
||||
DescType typeCode;
|
||||
Size actualSize = 0;
|
||||
char path[MAX_PATH]; /*Flawfinder: ignore*/
|
||||
|
||||
memset(&fsRef, 0, sizeof(fsRef));
|
||||
error = AEGetNthPtr(&navReply.selection, index, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
|
||||
|
||||
if (error == noErr)
|
||||
error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
|
||||
|
||||
if (error == noErr)
|
||||
mFiles.push_back(std::string(path));
|
||||
}
|
||||
}
|
||||
if (filev && filev->size() > 0)
|
||||
{
|
||||
mFiles.insert(mFiles.end(), filev->begin(), filev->end());
|
||||
return true;
|
||||
}
|
||||
|
||||
return error;
|
||||
return false;
|
||||
}
|
||||
|
||||
OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
|
||||
bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
|
||||
{
|
||||
OSStatus error = noErr;
|
||||
NavDialogRef navRef = NULL;
|
||||
NavReplyRecord navReply;
|
||||
|
||||
memset(&navReply, 0, sizeof(navReply));
|
||||
|
||||
// Setup the type, creator, and extension
|
||||
OSType type, creator;
|
||||
CFStringRef extension = NULL;
|
||||
std::string extension, type, creator;
|
||||
|
||||
switch (filter)
|
||||
{
|
||||
case FFSAVE_WAV:
|
||||
type = 'WAVE';
|
||||
creator = 'TVOD';
|
||||
extension = CFSTR(".wav");
|
||||
type = "WAVE";
|
||||
creator = "TVOD";
|
||||
extension = "wav";
|
||||
break;
|
||||
|
||||
case FFSAVE_TGA:
|
||||
type = 'TPIC';
|
||||
creator = 'prvw';
|
||||
extension = CFSTR(".tga");
|
||||
type = "TPIC";
|
||||
creator = "prvw";
|
||||
extension = "tga";
|
||||
break;
|
||||
|
||||
case FFSAVE_BMP:
|
||||
type = 'BMPf';
|
||||
creator = 'prvw';
|
||||
extension = CFSTR(".bmp");
|
||||
type = "BMPf";
|
||||
creator = "prvw";
|
||||
extension = "bmp";
|
||||
break;
|
||||
case FFSAVE_JPEG:
|
||||
type = 'JPEG';
|
||||
creator = 'prvw';
|
||||
extension = CFSTR(".jpeg");
|
||||
type = "JPEG";
|
||||
creator = "prvw";
|
||||
extension = "jpeg";
|
||||
break;
|
||||
case FFSAVE_PNG:
|
||||
type = 'PNG ';
|
||||
creator = 'prvw';
|
||||
extension = CFSTR(".png");
|
||||
type = "PNG ";
|
||||
creator = "prvw";
|
||||
extension = "png";
|
||||
break;
|
||||
case FFSAVE_AVI:
|
||||
type = '\?\?\?\?';
|
||||
creator = '\?\?\?\?';
|
||||
extension = CFSTR(".mov");
|
||||
type = "\?\?\?\?";
|
||||
creator = "\?\?\?\?";
|
||||
extension = "mov";
|
||||
break;
|
||||
|
||||
case FFSAVE_ANIM:
|
||||
type = '\?\?\?\?';
|
||||
creator = '\?\?\?\?';
|
||||
extension = CFSTR(".xaf");
|
||||
type = "\?\?\?\?";
|
||||
creator = "\?\?\?\?";
|
||||
extension = "xaf";
|
||||
break;
|
||||
|
||||
#ifdef _CORY_TESTING
|
||||
case FFSAVE_GEOMETRY:
|
||||
type = '\?\?\?\?';
|
||||
creator = '\?\?\?\?';
|
||||
extension = CFSTR(".slg");
|
||||
type = "\?\?\?\?";
|
||||
creator = "\?\?\?\?";
|
||||
extension = "slg";
|
||||
break;
|
||||
#endif
|
||||
case FFSAVE_RAW:
|
||||
type = '\?\?\?\?';
|
||||
creator = '\?\?\?\?';
|
||||
extension = CFSTR(".raw");
|
||||
type = "\?\?\?\?";
|
||||
creator = "\?\?\?\?";
|
||||
extension = "raw";
|
||||
break;
|
||||
|
||||
case FFSAVE_J2C:
|
||||
type = '\?\?\?\?';
|
||||
creator = 'prvw';
|
||||
extension = CFSTR(".j2c");
|
||||
type = "\?\?\?\?";
|
||||
creator = "prvw";
|
||||
extension = "j2c";
|
||||
break;
|
||||
|
||||
case FFSAVE_SCRIPT:
|
||||
type = 'LSL ';
|
||||
creator = '\?\?\?\?';
|
||||
extension = CFSTR(".lsl");
|
||||
type = "LSL ";
|
||||
creator = "\?\?\?\?";
|
||||
extension = "lsl";
|
||||
break;
|
||||
|
||||
case FFSAVE_ALL:
|
||||
default:
|
||||
type = '\?\?\?\?';
|
||||
creator = '\?\?\?\?';
|
||||
extension = CFSTR("");
|
||||
type = "\?\?\?\?";
|
||||
creator = "\?\?\?\?";
|
||||
extension = "";
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the dialog
|
||||
error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef);
|
||||
if (error == noErr)
|
||||
{
|
||||
CFStringRef nameString = NULL;
|
||||
bool hasExtension = true;
|
||||
|
||||
// Create a CFString of the initial file name
|
||||
if (!filename.empty())
|
||||
nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
|
||||
else
|
||||
nameString = CFSTR("Untitled");
|
||||
|
||||
// Add the extension if one was not provided
|
||||
if (nameString && !CFStringHasSuffix(nameString, extension))
|
||||
{
|
||||
CFStringRef tempString = nameString;
|
||||
hasExtension = false;
|
||||
nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension);
|
||||
CFRelease(tempString);
|
||||
}
|
||||
|
||||
// Set the name in the dialog
|
||||
if (nameString)
|
||||
{
|
||||
error = NavDialogSetSaveFileName(navRef, nameString);
|
||||
CFRelease(nameString);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = paramErr;
|
||||
}
|
||||
}
|
||||
|
||||
std::string namestring = filename;
|
||||
if (namestring.empty()) namestring="Untitled";
|
||||
|
||||
// if (! boost::algorithm::ends_with(namestring, extension) )
|
||||
// {
|
||||
// namestring = namestring + "." + extension;
|
||||
//
|
||||
// }
|
||||
|
||||
gViewerWindow->getWindow()->beforeDialog();
|
||||
|
||||
// Run the dialog
|
||||
if (error == noErr)
|
||||
error = NavDialogRun(navRef);
|
||||
std::string* filev = doSaveDialog(&namestring,
|
||||
&type,
|
||||
&creator,
|
||||
&extension,
|
||||
mPickOptions);
|
||||
|
||||
gViewerWindow->getWindow()->afterDialog();
|
||||
|
||||
if (error == noErr)
|
||||
error = NavDialogGetReply(navRef, &navReply);
|
||||
|
||||
if (navRef)
|
||||
NavDialogDispose(navRef);
|
||||
|
||||
if (error == noErr && navReply.validRecord)
|
||||
if ( filev && !filev->empty() )
|
||||
{
|
||||
SInt32 count = 0;
|
||||
|
||||
// AE indexes are 1 based...
|
||||
error = AECountItems(&navReply.selection, &count);
|
||||
if (count > 0)
|
||||
{
|
||||
// Get the FSRef to the containing folder
|
||||
FSRef fsRef;
|
||||
AEKeyword theAEKeyword;
|
||||
DescType typeCode;
|
||||
Size actualSize = 0;
|
||||
|
||||
memset(&fsRef, 0, sizeof(fsRef));
|
||||
error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
|
||||
|
||||
if (error == noErr)
|
||||
{
|
||||
char path[PATH_MAX]; /*Flawfinder: ignore*/
|
||||
char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/
|
||||
|
||||
error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX);
|
||||
if (error == noErr)
|
||||
{
|
||||
if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8))
|
||||
{
|
||||
mFiles.push_back(std::string(path) + "/" + std::string(newFileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
error = paramErr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = paramErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mFiles.push_back(*filev);
|
||||
return true;
|
||||
}
|
||||
|
||||
return error;
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
|
||||
|
|
@ -924,16 +749,21 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
OSStatus error = noErr;
|
||||
|
||||
reset();
|
||||
|
||||
mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
|
||||
mPickOptions &= ~F_MULTIPLE;
|
||||
mPickOptions |= F_FILE;
|
||||
|
||||
if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
|
||||
{
|
||||
|
||||
mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY );
|
||||
mPickOptions &= ~F_FILE;
|
||||
}
|
||||
|
||||
if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
|
||||
{
|
||||
// mNavOptions.optionFlags |= kNavAllowOpenPackages;
|
||||
mNavOptions.optionFlags |= kNavSupportPackages;
|
||||
mPickOptions &= F_NAV_SUPPORT;
|
||||
}
|
||||
|
||||
if (blocking)
|
||||
|
|
@ -942,14 +772,13 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
|
|||
send_agent_pause();
|
||||
}
|
||||
|
||||
|
||||
success = doNavChooseDialog(filter);
|
||||
|
||||
if (success)
|
||||
{
|
||||
error = doNavChooseDialog(filter);
|
||||
}
|
||||
|
||||
if (error == noErr)
|
||||
{
|
||||
if (getFileCount())
|
||||
success = true;
|
||||
if (!getFileCount())
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (blocking)
|
||||
|
|
@ -975,21 +804,22 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
OSStatus error = noErr;
|
||||
|
||||
reset();
|
||||
|
||||
mNavOptions.optionFlags |= kNavAllowMultipleFiles;
|
||||
|
||||
mPickOptions |= F_FILE;
|
||||
|
||||
mPickOptions |= F_MULTIPLE;
|
||||
// Modal, so pause agent
|
||||
send_agent_pause();
|
||||
|
||||
success = doNavChooseDialog(filter);
|
||||
|
||||
send_agent_resume();
|
||||
|
||||
if (success)
|
||||
{
|
||||
error = doNavChooseDialog(filter);
|
||||
}
|
||||
send_agent_resume();
|
||||
if (error == noErr)
|
||||
{
|
||||
if (getFileCount())
|
||||
success = true;
|
||||
if (!getFileCount())
|
||||
success = false;
|
||||
if (getFileCount() > 1)
|
||||
mLocked = true;
|
||||
}
|
||||
|
|
@ -1001,37 +831,37 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
|
|||
|
||||
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
|
||||
{
|
||||
|
||||
if( mLocked )
|
||||
return FALSE;
|
||||
BOOL success = FALSE;
|
||||
OSStatus error = noErr;
|
||||
return false;
|
||||
BOOL success = false;
|
||||
|
||||
// if local file browsing is turned off, return without opening dialog
|
||||
if ( check_local_file_access_enabled() == false )
|
||||
{
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
reset();
|
||||
|
||||
mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
|
||||
mPickOptions &= ~F_MULTIPLE;
|
||||
|
||||
// Modal, so pause agent
|
||||
send_agent_pause();
|
||||
|
||||
success = doNavSaveDialog(filter, filename);
|
||||
|
||||
if (success)
|
||||
{
|
||||
error = doNavSaveDialog(filter, filename);
|
||||
}
|
||||
send_agent_resume();
|
||||
if (error == noErr)
|
||||
{
|
||||
if (getFileCount())
|
||||
success = true;
|
||||
if (!getFileCount())
|
||||
success = false;
|
||||
}
|
||||
|
||||
// Account for the fact that the app has been stalled.
|
||||
LLFrameTimer::updateFrameTime();
|
||||
return success;
|
||||
}
|
||||
//END LL_DARWIN
|
||||
|
||||
#elif LL_LINUX || LL_SOLARIS
|
||||
|
||||
|
|
@ -1537,4 +1367,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // LL_LINUX || LL_SOLARIS
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
#include <Carbon/Carbon.h>
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
#include "fix_macros.h"
|
||||
#undef verify
|
||||
#undef check
|
||||
#undef require
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -85,7 +85,8 @@ public:
|
|||
FFLOAD_MODEL = 9,
|
||||
FFLOAD_COLLADA = 10,
|
||||
FFLOAD_SCRIPT = 11,
|
||||
FFLOAD_DICTIONARY = 12
|
||||
FFLOAD_DICTIONARY = 12,
|
||||
FFLOAD_DIRECTORY = 13 //To call from lldirpicker.
|
||||
};
|
||||
|
||||
enum ESaveFilter
|
||||
|
|
@ -158,15 +159,14 @@ private:
|
|||
#endif
|
||||
|
||||
#if LL_DARWIN
|
||||
NavDialogCreationOptions mNavOptions;
|
||||
S32 mPickOptions;
|
||||
std::vector<std::string> mFileVector;
|
||||
UInt32 mFileIndex;
|
||||
|
||||
OSStatus doNavChooseDialog(ELoadFilter filter);
|
||||
OSStatus doNavSaveDialog(ESaveFilter filter, const std::string& filename);
|
||||
void getFilePath(SInt32 index);
|
||||
void getFileName(SInt32 index);
|
||||
static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
|
||||
bool doNavChooseDialog(ELoadFilter filter);
|
||||
bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
|
||||
//static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
|
||||
std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
|
||||
#endif
|
||||
|
||||
#if LL_GTK
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file llfilepicker_mac.h
|
||||
* @brief OS-specific file picker
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
// OS specific file selection dialog. This is implemented as a
|
||||
// singleton class, so call the instance() method to get the working
|
||||
// instance. When you call getMultipleOpenFile(), it locks the picker
|
||||
// until you iterate to the end of the list of selected files with
|
||||
// getNextFile() or call reset().
|
||||
|
||||
#ifndef LL_LLFILEPICKER_MAC_H
|
||||
#define LL_LLFILEPICKER_MAC_H
|
||||
|
||||
#if LL_DARWIN
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//void modelessPicker();
|
||||
std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
|
||||
unsigned int flags);
|
||||
std::string* doSaveDialog(const std::string* file,
|
||||
const std::string* type,
|
||||
const std::string* creator,
|
||||
const std::string* extension,
|
||||
unsigned int flags);
|
||||
enum {
|
||||
F_FILE = 0x00000001,
|
||||
F_DIRECTORY = 0x00000002,
|
||||
F_MULTIPLE = 0x00000004,
|
||||
F_NAV_SUPPORT=0x00000008
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* @file llfilepicker_mac.cpp
|
||||
* @brief OS-specific file picker
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <iostream>
|
||||
#include "llfilepicker_mac.h"
|
||||
|
||||
std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
|
||||
unsigned int flags)
|
||||
{
|
||||
int i, result;
|
||||
|
||||
//Aura TODO: We could init a small window and release it at the end of this routine
|
||||
//for a modeless interface.
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
//NSString *fileName = nil;
|
||||
NSMutableArray *fileTypes = nil;
|
||||
|
||||
|
||||
if ( allowed_types && !allowed_types->empty())
|
||||
{
|
||||
fileTypes = [[NSMutableArray alloc] init];
|
||||
|
||||
for (i=0;i<allowed_types->size();++i)
|
||||
{
|
||||
[fileTypes addObject:
|
||||
[NSString stringWithCString:(*allowed_types)[i].c_str()
|
||||
encoding:[NSString defaultCStringEncoding]]];
|
||||
}
|
||||
}
|
||||
|
||||
//[panel setMessage:@"Import one or more files or directories."];
|
||||
[panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
|
||||
[panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
|
||||
[panel setCanCreateDirectories: true];
|
||||
[panel setResolvesAliases: true];
|
||||
[panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
|
||||
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
|
||||
|
||||
std::vector<std::string>* outfiles = NULL;
|
||||
|
||||
if (fileTypes)
|
||||
{
|
||||
[panel setAllowedFileTypes:fileTypes];
|
||||
result = [panel runModal];
|
||||
}
|
||||
else
|
||||
{
|
||||
// I suggest it's better to open the last path and let this default to home dir as necessary
|
||||
// for consistency with other OS X apps
|
||||
//
|
||||
//[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
|
||||
result = [panel runModal];
|
||||
}
|
||||
|
||||
if (result == NSOKButton)
|
||||
{
|
||||
NSArray *filesToOpen = [panel URLs];
|
||||
int i, count = [filesToOpen count];
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
outfiles = new std::vector<std::string>;
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
NSString *aFile = [[filesToOpen objectAtIndex:i] path];
|
||||
std::string *afilestr = new std::string([aFile UTF8String]);
|
||||
outfiles->push_back(*afilestr);
|
||||
}
|
||||
}
|
||||
return outfiles;
|
||||
}
|
||||
|
||||
|
||||
std::string* doSaveDialog(const std::string* file,
|
||||
const std::string* type,
|
||||
const std::string* creator,
|
||||
const std::string* extension,
|
||||
unsigned int flags)
|
||||
{
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
|
||||
NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
NSArray *fileType = [[NSArray alloc] initWithObjects:extensionns,nil];
|
||||
|
||||
//[panel setMessage:@"Save Image File"];
|
||||
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
|
||||
[panel setCanSelectHiddenExtension:true];
|
||||
[panel setAllowedFileTypes:fileType];
|
||||
NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
|
||||
std::string *outfile = NULL;
|
||||
NSURL* url = [NSURL fileURLWithPath:fileName];
|
||||
[panel setDirectoryURL: url];
|
||||
if([panel runModal] ==
|
||||
NSFileHandlingPanelOKButton)
|
||||
{
|
||||
NSURL* url = [panel URL];
|
||||
NSString* p = [url path];
|
||||
outfile = new std::string( [p UTF8String] );
|
||||
// write the file
|
||||
}
|
||||
return outfile;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -89,8 +89,10 @@ void LLFloaterHardwareSettings::refresh()
|
|||
|
||||
void LLFloaterHardwareSettings::refreshEnabledState()
|
||||
{
|
||||
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
|
||||
|
||||
S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
|
||||
S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting();
|
||||
S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem);
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem);
|
||||
|
||||
|
|
@ -149,12 +151,17 @@ BOOL LLFloaterHardwareSettings::postBuild()
|
|||
{
|
||||
childSetAction("OK", onBtnOK, this);
|
||||
|
||||
// Don't do this on Mac as their braindead GL versioning
|
||||
// sets this when 8x and 16x are indeed available
|
||||
//
|
||||
#if !LL_DARWIN
|
||||
if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
|
||||
{ //remove FSAA settings above "4x"
|
||||
LLComboBox* combo = getChild<LLComboBox>("fsaa");
|
||||
combo->remove("8x");
|
||||
combo->remove("16x");
|
||||
}
|
||||
#endif
|
||||
|
||||
refresh();
|
||||
center();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue