lwjgltexturestate.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 1,400 行 · 第 1/5 页
JAVA
1,400 行
// Create the texture
if (texture.getTextureKey() != null) {
Texture cached = TextureManager.findCachedTexture(texture
.getTextureKey());
if (cached == null) {
TextureManager.addToCache(texture);
} else if (cached.getTextureId() != 0) {
texture.setTextureId(cached.getTextureId());
GL11.glBindTexture(getGLType(type), cached.getTextureId());
if (Debug.stats) {
StatCollector.addStat(StatType.STAT_TEXTURE_BINDS, 1);
}
if (record != null)
record.units[unit].boundTexture = texture.getTextureId();
return;
}
}
IntBuffer id = BufferUtils.createIntBuffer(1);
id.clear();
GL11.glGenTextures(id);
texture.setTextureId(id.get(0));
GL11.glBindTexture(getGLType(type), texture.getTextureId());
if (Debug.stats) {
StatCollector.addStat(StatType.STAT_TEXTURE_BINDS, 1);
}
if (record != null)
record.units[unit].boundTexture = texture.getTextureId();
TextureManager.registerForCleanup(texture.getTextureKey(), texture
.getTextureId());
// pass image data to OpenGL
Image image = texture.getImage();
boolean hasBorder = texture.hasBorder();
if (image == null) {
logger.warning("Image data for texture is null.");
}
// set alignment to support images with width % 4 != 0, as images are
// not aligned
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
// Get texture image data. Not all textures have image data.
// For example, ApplyMode.Combine modes can use primary colors,
// texture output, and constants to modify fragments via the
// texture units.
if (image != null) {
if (!supportsNonPowerTwo
&& (!FastMath.isPowerOfTwo(image.getWidth()) || !FastMath
.isPowerOfTwo(image.getHeight()))) {
logger
.warning("(card unsupported) Attempted to apply texture with size that is not power of 2: "
+ image.getWidth() + " x " + image.getHeight());
final int maxSize = LWJGLMipMap
.glGetIntegerv(GL11.GL_MAX_TEXTURE_SIZE);
int actualWidth = image.getWidth();
int w = LWJGLMipMap.nearestPower(actualWidth);
if (w > maxSize) {
w = maxSize;
}
int actualHeight = image.getHeight();
int h = LWJGLMipMap.nearestPower(actualHeight);
if (h > maxSize) {
h = maxSize;
}
logger.warning("Rescaling image to " + w + " x " + h + " !!!");
// must rescale image to get "top" mipmap texture image
int format = TextureStateRecord.getGLPixelFormat(image
.getFormat());
int dType = GL11.GL_UNSIGNED_BYTE;
int bpp = LWJGLMipMap.bytesPerPixel(format, dType);
ByteBuffer scaledImage = BufferUtils.createByteBuffer((w + 4)
* h * bpp);
int error = MipMap.gluScaleImage(format, actualWidth,
actualHeight, dType, image.getData(0), w, h, dType,
scaledImage);
if (error != 0) {
Util.checkGLError();
}
image.setWidth(w);
image.setHeight(h);
image.setData(scaledImage);
}
if (!texture.getMinificationFilter().usesMipMapLevels()
&& !TextureStateRecord.isCompressedType(image.getFormat())) {
// Load textures which do not need mipmap auto-generating and
// which aren't using compressed images.
switch (texture.getType()) {
case TwoDimensional:
// ensure the buffer is ready for reading
image.getData(0).rewind();
// send top level to card
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0,
TextureStateRecord.getGLDataFormat(image
.getFormat()), image.getWidth(), image
.getHeight(), hasBorder ? 1 : 0,
TextureStateRecord.getGLPixelFormat(image
.getFormat()), GL11.GL_UNSIGNED_BYTE,
image.getData(0));
break;
case OneDimensional:
// ensure the buffer is ready for reading
image.getData(0).rewind();
// send top level to card
GL11.glTexImage1D(GL11.GL_TEXTURE_1D, 0,
TextureStateRecord.getGLDataFormat(image
.getFormat()), image.getWidth(),
hasBorder ? 1 : 0, TextureStateRecord
.getGLPixelFormat(image.getFormat()),
GL11.GL_UNSIGNED_BYTE, image.getData(0));
break;
case ThreeDimensional:
if (supportsTexture3D) {
// concat data into single buffer:
int dSize = 0;
int count = 0;
ByteBuffer data = null;
for (int x = 0; x < image.getData().size(); x++) {
if (image.getData(x) != null) {
data = image.getData(x);
dSize += data.limit();
count++;
}
}
// reuse buffer if we can.
if (count != 1) {
data = BufferUtils.createByteBuffer(dSize);
for (int x = 0; x < image.getData().size(); x++) {
if (image.getData(x) != null) {
data.put(image.getData(x));
}
}
// ensure the buffer is ready for reading
data.flip();
}
// send top level to card
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0,
TextureStateRecord.getGLDataFormat(image
.getFormat()), image.getWidth(),
image.getHeight(), image.getDepth(),
hasBorder ? 1 : 0,
TextureStateRecord.getGLPixelFormat(image
.getFormat()),
GL11.GL_UNSIGNED_BYTE, data);
} else {
logger
.warning("This card does not support Texture3D.");
}
break;
case CubeMap:
// NOTE: Cubemaps MUST be square, so height is ignored
// on purpose.
if (supportsTextureCubeMap) {
for (TextureCubeMap.Face face : TextureCubeMap.Face
.values()) {
// ensure the buffer is ready for reading
image.getData(face.ordinal()).rewind();
// send top level to card
GL11.glTexImage2D(getGLCubeMapFace(face), 0,
TextureStateRecord
.getGLDataFormat(image
.getFormat()), image
.getWidth(), image.getWidth(),
hasBorder ? 1 : 0, TextureStateRecord
.getGLPixelFormat(image
.getFormat()),
GL11.GL_UNSIGNED_BYTE, image
.getData(face.ordinal()));
}
} else {
logger
.warning("This card does not support Cubemaps.");
}
break;
}
} else if (texture.getMinificationFilter().usesMipMapLevels()
&& !image.hasMipmaps()
&& !TextureStateRecord.isCompressedType(image.getFormat())) {
// For textures which need mipmaps auto-generating and which
// aren't using compressed images, generate the mipmaps.
// A new mipmap builder may be needed to build mipmaps for
// compressed textures.
if (automaticMipMaps) {
// Flag the card to generate mipmaps
GL11.glTexParameteri(getGLType(type),
SGISGenerateMipmap.GL_GENERATE_MIPMAP_SGIS,
GL11.GL_TRUE);
}
switch (type) {
case TwoDimensional:
// ensure the buffer is ready for reading
image.getData(0).rewind();
if (automaticMipMaps) {
// send top level to card
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0,
TextureStateRecord.getGLDataFormat(image
.getFormat()), image.getWidth(),
image.getHeight(), hasBorder ? 1 : 0,
TextureStateRecord.getGLPixelFormat(image
.getFormat()),
GL11.GL_UNSIGNED_BYTE, image.getData(0));
} else {
// send to card
GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D,
TextureStateRecord.getGLDataFormat(image
.getFormat()), image.getWidth(),
image.getHeight(),
TextureStateRecord.getGLPixelFormat(image
.getFormat()),
GL11.GL_UNSIGNED_BYTE, image.getData(0));
}
break;
case OneDimensional:
// ensure the buffer is ready for reading
image.getData(0).rewind();
if (automaticMipMaps) {
// send top level to card
GL11.glTexImage1D(GL11.GL_TEXTURE_1D, 0,
TextureStateRecord.getGLDataFormat(image
.getFormat()), image.getWidth(),
hasBorder ? 1 : 0,
TextureStateRecord.getGLPixelFormat(image
.getFormat()),
GL11.GL_UNSIGNED_BYTE, image.getData(0));
} else {
// Note: LWJGL's GLU class does not support
// gluBuild1DMipmaps.
logger
.warning("non-fbo 1d mipmap generation is not currently supported. Use DDS or a non-mipmap minification filter.");
return;
}
break;
case ThreeDimensional:
if (supportsTexture3D) {
if (automaticMipMaps) {
// concat data into single buffer:
int dSize = 0;
int count = 0;
ByteBuffer data = null;
for (int x = 0; x < image.getData().size(); x++) {
if (image.getData(x) != null) {
data = image.getData(x);
dSize += data.limit();
count++;
}
}
// reuse buffer if we can.
if (count != 1) {
data = BufferUtils.createByteBuffer(dSize);
for (int x = 0; x < image.getData().size(); x++) {
if (image.getData(x) != null) {
data.put(image.getData(x));
}
}
// ensure the buffer is ready for reading
data.flip();
}
// send top level to card
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0,
TextureStateRecord
.getGLDataFormat(image
.getFormat()), image
.getWidth(), image.getHeight(),
image.getDepth(), hasBorder ? 1 : 0,
TextureStateRecord
.getGLPixelFormat(image
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?