diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/llwindow/llgl.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2 meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz |
Second Life viewer sources 1.19.1.0
Diffstat (limited to 'linden/indra/llwindow/llgl.cpp')
-rw-r--r-- | linden/indra/llwindow/llgl.cpp | 269 |
1 files changed, 246 insertions, 23 deletions
diff --git a/linden/indra/llwindow/llgl.cpp b/linden/indra/llwindow/llgl.cpp index 6978fb9..07840c1 100644 --- a/linden/indra/llwindow/llgl.cpp +++ b/linden/indra/llwindow/llgl.cpp | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "llsys.h" | 41 | #include "llsys.h" |
42 | 42 | ||
43 | #include "llgl.h" | 43 | #include "llgl.h" |
44 | #include "llglimmediate.h" | ||
44 | 45 | ||
45 | #include "llerror.h" | 46 | #include "llerror.h" |
46 | #include "llquaternion.h" | 47 | #include "llquaternion.h" |
@@ -50,33 +51,15 @@ | |||
50 | 51 | ||
51 | #include "llglheaders.h" | 52 | #include "llglheaders.h" |
52 | 53 | ||
53 | #if LL_LINUX && !LL_MESA_HEADLESS | ||
54 | // The __APPLE__ hack is to make glh_extensions.h not symbol-clash horribly | ||
55 | # define __APPLE__ | ||
56 | # include "GL/glh_extensions.h" | ||
57 | # undef __APPLE__ | ||
58 | |||
59 | /* Although SDL very likely ends up calling glXGetProcAddress() itself, | ||
60 | if we do it ourselves then we avoid getting bogus addresses back on | ||
61 | some systems. Weird. */ | ||
62 | /*# include "SDL/SDL.h" | ||
63 | # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ | ||
64 | #define GLX_GLXEXT_PROTOTYPES 1 | ||
65 | # include "GL/glx.h" | ||
66 | # include "GL/glxext.h" | ||
67 | // Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol | ||
68 | // is considered 'legacy' but works on more machines. | ||
69 | # define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p)) | ||
70 | #endif // LL_LINUX && !LL_MESA_HEADLESS | ||
71 | |||
72 | |||
73 | #ifdef _DEBUG | 54 | #ifdef _DEBUG |
74 | //#define GL_STATE_VERIFY | 55 | //#define GL_STATE_VERIFY |
75 | #endif | 56 | #endif |
76 | 57 | ||
77 | BOOL gClothRipple = FALSE; | 58 | BOOL gClothRipple = FALSE; |
78 | BOOL gNoRender = FALSE; | 59 | BOOL gNoRender = FALSE; |
60 | LLMatrix4 gGLObliqueProjectionInverse; | ||
79 | 61 | ||
62 | LLGLNamePool::pool_list_t LLGLNamePool::sInstances; | ||
80 | 63 | ||
81 | #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS | 64 | #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS |
82 | // ATI prototypes | 65 | // ATI prototypes |
@@ -312,6 +295,8 @@ LLGLManager::LLGLManager() | |||
312 | mVRAM = 0; | 295 | mVRAM = 0; |
313 | mGLMaxVertexRange = 0; | 296 | mGLMaxVertexRange = 0; |
314 | mGLMaxIndexRange = 0; | 297 | mGLMaxIndexRange = 0; |
298 | |||
299 | mHasRequirements = TRUE; | ||
315 | } | 300 | } |
316 | 301 | ||
317 | //--------------------------------------------------------------------- | 302 | //--------------------------------------------------------------------- |
@@ -426,7 +411,13 @@ bool LLGLManager::initGL() | |||
426 | } | 411 | } |
427 | 412 | ||
428 | } | 413 | } |
429 | else if (mGLVendor.find("INTEL") != LLString::npos) | 414 | else if (mGLVendor.find("INTEL") != LLString::npos |
415 | #if LL_LINUX | ||
416 | // The Mesa-based drivers put this in the Renderer string, | ||
417 | // not the Vendor string. | ||
418 | || mGLRenderer.find("INTEL") != LLString::npos | ||
419 | #endif //LL_LINUX | ||
420 | ) | ||
430 | { | 421 | { |
431 | mGLVendorShort = "INTEL"; | 422 | mGLVendorShort = "INTEL"; |
432 | mIsIntel = TRUE; | 423 | mIsIntel = TRUE; |
@@ -451,6 +442,8 @@ bool LLGLManager::initGL() | |||
451 | } | 442 | } |
452 | else | 443 | else |
453 | { | 444 | { |
445 | mHasRequirements = FALSE; | ||
446 | |||
454 | // We don't support cards that don't support the GL_ARB_multitexture extension | 447 | // We don't support cards that don't support the GL_ARB_multitexture extension |
455 | llwarns << "GL Drivers do not support GL_ARB_multitexture" << llendl; | 448 | llwarns << "GL Drivers do not support GL_ARB_multitexture" << llendl; |
456 | return false; | 449 | return false; |
@@ -509,6 +502,7 @@ void LLGLManager::shutdownGL() | |||
509 | { | 502 | { |
510 | if (mInited) | 503 | if (mInited) |
511 | { | 504 | { |
505 | glFinish(); | ||
512 | stop_glerror(); | 506 | stop_glerror(); |
513 | mInited = FALSE; | 507 | mInited = FALSE; |
514 | } | 508 | } |
@@ -959,7 +953,17 @@ void assert_glerror() | |||
959 | if (error) | 953 | if (error) |
960 | { | 954 | { |
961 | #ifndef LL_LINUX // *FIX: ! This should be an error for linux as well. | 955 | #ifndef LL_LINUX // *FIX: ! This should be an error for linux as well. |
962 | llerrs << "GL Error:" << gluErrorString(error) << llendl; | 956 | GLubyte const * gl_error_msg = gluErrorString(error); |
957 | if (NULL != gl_error_msg) | ||
958 | { | ||
959 | llerrs << "GL Error:" << gl_error_msg << llendl; | ||
960 | } | ||
961 | else | ||
962 | { | ||
963 | // gluErrorString returns NULL for some extensions' error codes. | ||
964 | // you'll probably have to grep for the number in glext.h. | ||
965 | llerrs << "GL Error: UNKNOWN 0x" << std::hex << error << llendl; | ||
966 | } | ||
963 | #endif | 967 | #endif |
964 | } | 968 | } |
965 | } | 969 | } |
@@ -988,6 +992,7 @@ GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default | |||
988 | void LLGLState::initClass() | 992 | void LLGLState::initClass() |
989 | { | 993 | { |
990 | sStateMap[GL_DITHER] = GL_TRUE; | 994 | sStateMap[GL_DITHER] = GL_TRUE; |
995 | sStateMap[GL_TEXTURE_2D] = GL_TRUE; | ||
991 | } | 996 | } |
992 | 997 | ||
993 | //static | 998 | //static |
@@ -1001,7 +1006,9 @@ void LLGLState::restoreGL() | |||
1001 | // Really shouldn't be needed, but seems we sometimes do. | 1006 | // Really shouldn't be needed, but seems we sometimes do. |
1002 | void LLGLState::resetTextureStates() | 1007 | void LLGLState::resetTextureStates() |
1003 | { | 1008 | { |
1009 | gGL.flush(); | ||
1004 | GLint maxTextureUnits; | 1010 | GLint maxTextureUnits; |
1011 | |||
1005 | glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); | 1012 | glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); |
1006 | for (S32 j = maxTextureUnits-1; j >=0; j--) | 1013 | for (S32 j = maxTextureUnits-1; j >=0; j--) |
1007 | { | 1014 | { |
@@ -1074,7 +1081,23 @@ void LLGLState::checkTextureChannels() | |||
1074 | error = TRUE; | 1081 | error = TRUE; |
1075 | llwarns << "Active texture channel corrupted. " << llendl; | 1082 | llwarns << "Active texture channel corrupted. " << llendl; |
1076 | } | 1083 | } |
1077 | 1084 | else if (!glIsEnabled(GL_TEXTURE_2D)) | |
1085 | { | ||
1086 | error = TRUE; | ||
1087 | llwarns << "GL_TEXTURE_2D not enabled on texture channel 0." << llendl; | ||
1088 | } | ||
1089 | else | ||
1090 | { | ||
1091 | GLint tex_env_mode = 0; | ||
1092 | |||
1093 | glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode); | ||
1094 | if (tex_env_mode != GL_MODULATE) | ||
1095 | { | ||
1096 | error = TRUE; | ||
1097 | llwarns << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << llendl; | ||
1098 | } | ||
1099 | } | ||
1100 | |||
1078 | GLint maxTextureUnits; | 1101 | GLint maxTextureUnits; |
1079 | glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); | 1102 | glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); |
1080 | 1103 | ||
@@ -1270,11 +1293,13 @@ void LLGLState::setEnabled(S32 enabled) | |||
1270 | } | 1293 | } |
1271 | else if (enabled == TRUE && sStateMap[mState] != GL_TRUE) | 1294 | else if (enabled == TRUE && sStateMap[mState] != GL_TRUE) |
1272 | { | 1295 | { |
1296 | gGL.flush(); | ||
1273 | glEnable(mState); | 1297 | glEnable(mState); |
1274 | sStateMap[mState] = GL_TRUE; | 1298 | sStateMap[mState] = GL_TRUE; |
1275 | } | 1299 | } |
1276 | else if (enabled == FALSE && sStateMap[mState] != GL_FALSE) | 1300 | else if (enabled == FALSE && sStateMap[mState] != GL_FALSE) |
1277 | { | 1301 | { |
1302 | gGL.flush(); | ||
1278 | glDisable(mState); | 1303 | glDisable(mState); |
1279 | sStateMap[mState] = GL_FALSE; | 1304 | sStateMap[mState] = GL_FALSE; |
1280 | } | 1305 | } |
@@ -1291,6 +1316,7 @@ LLGLState::~LLGLState() | |||
1291 | #endif | 1316 | #endif |
1292 | if (mIsEnabled != mWasEnabled) | 1317 | if (mIsEnabled != mWasEnabled) |
1293 | { | 1318 | { |
1319 | gGL.flush(); | ||
1294 | if (mWasEnabled) | 1320 | if (mWasEnabled) |
1295 | { | 1321 | { |
1296 | glEnable(mState); | 1322 | glEnable(mState); |
@@ -1478,3 +1504,200 @@ void parse_gl_version( S32* major, S32* minor, S32* release, LLString* vendor_sp | |||
1478 | vendor_specific->assign( version + i ); | 1504 | vendor_specific->assign( version + i ); |
1479 | } | 1505 | } |
1480 | } | 1506 | } |
1507 | |||
1508 | LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection) | ||
1509 | { | ||
1510 | mModelview = modelview; | ||
1511 | mProjection = projection; | ||
1512 | |||
1513 | setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]); | ||
1514 | } | ||
1515 | |||
1516 | void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) | ||
1517 | { | ||
1518 | glh::matrix4f& P = mProjection; | ||
1519 | glh::matrix4f& M = mModelview; | ||
1520 | |||
1521 | glh::matrix4f invtrans_MVP = (P * M).inverse().transpose(); | ||
1522 | glh::vec4f oplane(a,b,c,d); | ||
1523 | glh::vec4f cplane; | ||
1524 | invtrans_MVP.mult_matrix_vec(oplane, cplane); | ||
1525 | |||
1526 | cplane /= fabs(cplane[2]); // normalize such that depth is not scaled | ||
1527 | cplane[3] -= 1; | ||
1528 | |||
1529 | if(cplane[2] < 0) | ||
1530 | cplane *= -1; | ||
1531 | |||
1532 | glh::matrix4f suffix; | ||
1533 | suffix.set_row(2, cplane); | ||
1534 | glh::matrix4f newP = suffix * P; | ||
1535 | glMatrixMode(GL_PROJECTION); | ||
1536 | glPushMatrix(); | ||
1537 | glLoadMatrixf(newP.m); | ||
1538 | gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m); | ||
1539 | glMatrixMode(GL_MODELVIEW); | ||
1540 | } | ||
1541 | |||
1542 | LLGLUserClipPlane::~LLGLUserClipPlane() | ||
1543 | { | ||
1544 | glMatrixMode(GL_PROJECTION); | ||
1545 | glPopMatrix(); | ||
1546 | glMatrixMode(GL_MODELVIEW); | ||
1547 | } | ||
1548 | |||
1549 | LLGLNamePool::LLGLNamePool() | ||
1550 | { | ||
1551 | } | ||
1552 | |||
1553 | void LLGLNamePool::registerPool(LLGLNamePool* pool) | ||
1554 | { | ||
1555 | pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool); | ||
1556 | if (iter == sInstances.end()) | ||
1557 | { | ||
1558 | sInstances.push_back(pool); | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | LLGLNamePool::~LLGLNamePool() | ||
1563 | { | ||
1564 | pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this); | ||
1565 | if (iter != sInstances.end()) | ||
1566 | { | ||
1567 | sInstances.erase(iter); | ||
1568 | } | ||
1569 | } | ||
1570 | |||
1571 | void LLGLNamePool::upkeep() | ||
1572 | { | ||
1573 | std::sort(mNameList.begin(), mNameList.end(), CompareUsed()); | ||
1574 | } | ||
1575 | |||
1576 | void LLGLNamePool::cleanup() | ||
1577 | { | ||
1578 | for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) | ||
1579 | { | ||
1580 | releaseName(iter->name); | ||
1581 | } | ||
1582 | |||
1583 | mNameList.clear(); | ||
1584 | } | ||
1585 | |||
1586 | GLuint LLGLNamePool::allocate() | ||
1587 | { | ||
1588 | for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) | ||
1589 | { | ||
1590 | if (!iter->used) | ||
1591 | { | ||
1592 | iter->used = TRUE; | ||
1593 | return iter->name; | ||
1594 | } | ||
1595 | } | ||
1596 | |||
1597 | NameEntry entry; | ||
1598 | entry.name = allocateName(); | ||
1599 | entry.used = TRUE; | ||
1600 | mNameList.push_back(entry); | ||
1601 | |||
1602 | return entry.name; | ||
1603 | } | ||
1604 | |||
1605 | void LLGLNamePool::release(GLuint name) | ||
1606 | { | ||
1607 | for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) | ||
1608 | { | ||
1609 | if (iter->name == name) | ||
1610 | { | ||
1611 | iter->used = FALSE; | ||
1612 | return; | ||
1613 | } | ||
1614 | } | ||
1615 | } | ||
1616 | |||
1617 | //static | ||
1618 | void LLGLNamePool::upkeepPools() | ||
1619 | { | ||
1620 | for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) | ||
1621 | { | ||
1622 | LLGLNamePool* pool = *iter; | ||
1623 | pool->upkeep(); | ||
1624 | } | ||
1625 | } | ||
1626 | |||
1627 | //static | ||
1628 | void LLGLNamePool::cleanupPools() | ||
1629 | { | ||
1630 | for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) | ||
1631 | { | ||
1632 | LLGLNamePool* pool = *iter; | ||
1633 | pool->cleanup(); | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func) | ||
1638 | : mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled) | ||
1639 | { | ||
1640 | if (depth_enabled != sDepthEnabled) | ||
1641 | { | ||
1642 | gGL.flush(); | ||
1643 | if (depth_enabled) glEnable(GL_DEPTH_TEST); | ||
1644 | else glDisable(GL_DEPTH_TEST); | ||
1645 | sDepthEnabled = depth_enabled; | ||
1646 | } | ||
1647 | if (depth_func != sDepthFunc) | ||
1648 | { | ||
1649 | gGL.flush(); | ||
1650 | glDepthFunc(depth_func); | ||
1651 | sDepthFunc = depth_func; | ||
1652 | } | ||
1653 | if (write_enabled != sWriteEnabled) | ||
1654 | { | ||
1655 | gGL.flush(); | ||
1656 | glDepthMask(write_enabled); | ||
1657 | sWriteEnabled = write_enabled; | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | LLGLDepthTest::~LLGLDepthTest() | ||
1662 | { | ||
1663 | if (sDepthEnabled != mPrevDepthEnabled ) | ||
1664 | { | ||
1665 | gGL.flush(); | ||
1666 | if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST); | ||
1667 | else glDisable(GL_DEPTH_TEST); | ||
1668 | sDepthEnabled = mPrevDepthEnabled; | ||
1669 | } | ||
1670 | if (sDepthFunc != mPrevDepthFunc) | ||
1671 | { | ||
1672 | gGL.flush(); | ||
1673 | glDepthFunc(mPrevDepthFunc); | ||
1674 | sDepthFunc = mPrevDepthFunc; | ||
1675 | } | ||
1676 | if (sWriteEnabled != mPrevWriteEnabled ) | ||
1677 | { | ||
1678 | gGL.flush(); | ||
1679 | glDepthMask(mPrevWriteEnabled); | ||
1680 | sWriteEnabled = mPrevWriteEnabled; | ||
1681 | } | ||
1682 | } | ||
1683 | |||
1684 | LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P) | ||
1685 | { | ||
1686 | for (U32 i = 0; i < 4; i++) | ||
1687 | { | ||
1688 | P.element(2, i) = P.element(3, i) * 0.99999f; | ||
1689 | } | ||
1690 | |||
1691 | glMatrixMode(GL_PROJECTION); | ||
1692 | glPushMatrix(); | ||
1693 | glLoadMatrixf(P.m); | ||
1694 | glMatrixMode(GL_MODELVIEW); | ||
1695 | } | ||
1696 | |||
1697 | LLGLClampToFarClip::~LLGLClampToFarClip() | ||
1698 | { | ||
1699 | glMatrixMode(GL_PROJECTION); | ||
1700 | glPopMatrix(); | ||
1701 | glMatrixMode(GL_MODELVIEW); | ||
1702 | } | ||
1703 | |||