123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /**
- * Copyright (c) 2006-2012 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
- #include <vector>
- #include "OpenGL.h"
- #include "common/Exception.h"
- namespace love
- {
- namespace graphics
- {
- namespace opengl
- {
- static bool contextInitialized = false;
- static int curTextureUnitIndex = 0;
- static std::vector<GLuint> textureUnits;
- void initializeContext()
- {
- if (contextInitialized)
- return;
-
- contextInitialized = true;
-
- textureUnits.clear();
-
- // initialize multiple texture unit support, if available
- if (GLEE_ARB_multitexture || GLEE_VERSION_1_3)
- {
- GLint maxtextureunits;
- glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxtextureunits);
-
- // shaders/GL2.0 added "Texture Image Units." Total max texture units is the greater of the two
- if (GLEE_VERSION_2_0 || GLEE_ARB_vertex_shader)
- {
- GLint maxtextureimageunits;
- glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtextureimageunits);
-
- if (maxtextureimageunits > maxtextureunits)
- maxtextureunits = maxtextureimageunits;
- }
-
- textureUnits.resize(maxtextureunits, 0);
-
- GLenum activetextureunit;
- glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&activetextureunit);
-
- curTextureUnitIndex = activetextureunit - GL_TEXTURE0;
-
- for (size_t i = 0; i < textureUnits.size(); ++i)
- {
- if (GLEE_VERSION_1_3)
- glActiveTexture(GL_TEXTURE0 + i);
- else
- glActiveTextureARB(GL_TEXTURE0 + i);
-
- glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &textureUnits[i]);
- }
-
- if (GLEE_VERSION_1_3)
- glActiveTexture(activetextureunit);
- else
- glActiveTextureARB(activetextureunit);
- }
- else
- {
- // multitexturing not supported, so we only have 1 texture unit
- textureUnits.resize(1, 0);
- curTextureUnitIndex = 0;
-
- glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &textureUnits[0]);
- }
- }
- void uninitializeContext()
- {
- contextInitialized = false;
- }
- void setActiveTextureUnit(GLenum textureunit)
- {
- initializeContext();
-
- int textureunitindex = textureunit - GL_TEXTURE0;
-
- if (textureunitindex < 0 || (size_t) textureunitindex >= textureUnits.size())
- throw love::Exception("Invalid texture unit index.");
-
- if (textureunitindex != curTextureUnitIndex)
- {
- if (GLEE_VERSION_1_3)
- glActiveTexture(textureunit);
- else if (GLEE_ARB_multitexture)
- glActiveTextureARB(textureunit);
- else
- throw love::Exception("Multitexturing not supported.");
- }
-
- curTextureUnitIndex = textureunitindex;
- }
- void bindTexture(GLuint texture)
- {
- initializeContext();
-
- if (texture != textureUnits[curTextureUnitIndex])
- {
- textureUnits[curTextureUnitIndex] = texture;
- glBindTexture(GL_TEXTURE_2D, texture);
- }
- }
- void bindTextureToUnit(GLuint texture, GLenum textureunit, bool restoreprev)
- {
- initializeContext();
-
- int textureunitindex = textureunit - GL_TEXTURE0;
-
- if (textureunitindex < 0 || (size_t) textureunitindex >= textureUnits.size())
- throw love::Exception("Invalid texture unit index.");
-
- if (texture != textureUnits[textureunitindex])
- {
- int oldtexunitindex = curTextureUnitIndex;
- setActiveTextureUnit(textureunit);
-
- textureUnits[textureunitindex] = texture;
- glBindTexture(GL_TEXTURE_2D, texture);
-
- if (restoreprev)
- setActiveTextureUnit(GL_TEXTURE0 + oldtexunitindex);
- }
- }
- void deleteTexture(GLuint texture)
- {
- initializeContext();
-
- std::vector<GLuint>::iterator it;
- for (it = textureUnits.begin(); it != textureUnits.end(); ++it)
- {
- if (*it == texture)
- *it = 0;
- }
- glDeleteTextures(1, &texture);
- }
- } // opengl
- } // graphics
- } // love
|