📄 image.java
字号:
/* * Image.java * Copyright (C) 2003 * * $Id: Image.java,v 1.3 2005/05/07 17:31:37 cawe Exp $ *//*Copyright (C) 1997-2001 Id Software, Inc.This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/package jake2.render.lwjgl;import jake2.Defines;import jake2.client.VID;import jake2.client.particle_t;import jake2.game.cvar_t;import jake2.qcommon.*;import jake2.render.image_t;import jake2.util.Lib;import jake2.util.Vargs;import java.awt.Dimension;import java.awt.geom.AffineTransform;import java.awt.image.AffineTransformOp;import java.awt.image.BufferedImage;import java.nio.*;import java.util.Arrays;import org.lwjgl.BufferUtils;import org.lwjgl.opengl.EXTSharedTexturePalette;import org.lwjgl.opengl.GL11;/** * Image * * @author cwei */public abstract class Image extends Main { image_t draw_chars; image_t[] gltextures = new image_t[MAX_GLTEXTURES]; //Map gltextures = new Hashtable(MAX_GLTEXTURES); // image_t int numgltextures; int base_textureid; // gltextures[i] = base_textureid+i byte[] intensitytable = new byte[256]; byte[] gammatable = new byte[256]; cvar_t intensity; // // qboolean GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean is_sky ); // qboolean GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap); // int gl_solid_format = 3; int gl_alpha_format = 4; int gl_tex_solid_format = 3; int gl_tex_alpha_format = 4; int gl_filter_min = GL11.GL_LINEAR_MIPMAP_NEAREST; int gl_filter_max = GL11.GL_LINEAR; Image() { // init the texture cache for (int i = 0; i < gltextures.length; i++) { gltextures[i] = new image_t(i); } numgltextures = 0; } void GL_SetTexturePalette(int[] palette) { assert(palette != null && palette.length == 256) : "int palette[256] bug"; int i; //byte[] temptable = new byte[768]; if (qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f) { ByteBuffer temptable=BufferUtils.createByteBuffer(768); for (i = 0; i < 256; i++) { temptable.put(i * 3 + 0, (byte) ((palette[i] >> 0) & 0xff)); temptable.put(i * 3 + 1, (byte) ((palette[i] >> 8) & 0xff)); temptable.put(i * 3 + 2, (byte) ((palette[i] >> 16) & 0xff)); } gl.glColorTable(EXTSharedTexturePalette.GL_SHARED_TEXTURE_PALETTE_EXT, GL11.GL_RGB, 256, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, temptable); } } void GL_EnableMultitexture(boolean enable) { if (enable) { GL_SelectTexture(GL_TEXTURE1); gl.glEnable(GL11.GL_TEXTURE_2D); GL_TexEnv(GL11.GL_REPLACE); } else { GL_SelectTexture(GL_TEXTURE1); gl.glDisable(GL11.GL_TEXTURE_2D); GL_TexEnv(GL11.GL_REPLACE); } GL_SelectTexture(GL_TEXTURE0); GL_TexEnv(GL11.GL_REPLACE); } void GL_SelectTexture(int texture /* GLenum */) { int tmu; tmu = (texture == GL_TEXTURE0) ? 0 : 1; if (tmu == gl_state.currenttmu) { return; } gl_state.currenttmu = tmu; gl.glActiveTextureARB(texture); gl.glClientActiveTextureARB(texture); } int[] lastmodes = { -1, -1 }; void GL_TexEnv(int mode /* GLenum */ ) { if (mode != lastmodes[gl_state.currenttmu]) { gl.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode); lastmodes[gl_state.currenttmu] = mode; } } void GL_Bind(int texnum) { if ((gl_nobind.value != 0) && (draw_chars != null)) { // performance evaluation option texnum = draw_chars.texnum; } if (gl_state.currenttextures[gl_state.currenttmu] == texnum) return; gl_state.currenttextures[gl_state.currenttmu] = texnum; gl.glBindTexture(GL11.GL_TEXTURE_2D, texnum); } void GL_MBind(int target /* GLenum */, int texnum) { GL_SelectTexture(target); if (target == GL_TEXTURE0) { if (gl_state.currenttextures[0] == texnum) return; } else { if (gl_state.currenttextures[1] == texnum) return; } GL_Bind(texnum); } // glmode_t static class glmode_t { String name; int minimize, maximize; glmode_t(String name, int minimize, int maximze) { this.name = name; this.minimize = minimize; this.maximize = maximze; } } static final glmode_t modes[] = { new glmode_t("GL_NEAREST", GL11.GL_NEAREST, GL11.GL_NEAREST), new glmode_t("GL_LINEAR", GL11.GL_LINEAR, GL11.GL_LINEAR), new glmode_t("GL_NEAREST_MIPMAP_NEAREST", GL11.GL_NEAREST_MIPMAP_NEAREST, GL11.GL_NEAREST), new glmode_t("GL_LINEAR_MIPMAP_NEAREST", GL11.GL_LINEAR_MIPMAP_NEAREST, GL11.GL_LINEAR), new glmode_t("GL_NEAREST_MIPMAP_LINEAR", GL11.GL_NEAREST_MIPMAP_LINEAR, GL11.GL_NEAREST), new glmode_t("GL_LINEAR_MIPMAP_LINEAR", GL11.GL_LINEAR_MIPMAP_LINEAR, GL11.GL_LINEAR)}; static final int NUM_GL_MODES = modes.length; // gltmode_t static class gltmode_t { String name; int mode; gltmode_t(String name, int mode) { this.name = name; this.mode = mode; } } static final gltmode_t[] gl_alpha_modes = { new gltmode_t("default", 4), new gltmode_t("GL_RGBA", GL11.GL_RGBA), new gltmode_t("GL_RGBA8", GL11.GL_RGBA8), new gltmode_t("GL_RGB5_A1", GL11.GL_RGB5_A1), new gltmode_t("GL_RGBA4", GL11.GL_RGBA4), new gltmode_t("GL_RGBA2", GL11.GL_RGBA2), }; static final int NUM_GL_ALPHA_MODES = gl_alpha_modes.length; static final gltmode_t[] gl_solid_modes = { new gltmode_t("default", 3), new gltmode_t("GL_RGB", GL11.GL_RGB), new gltmode_t("GL_RGB8", GL11.GL_RGB8), new gltmode_t("GL_RGB5", GL11.GL_RGB5), new gltmode_t("GL_RGB4", GL11.GL_RGB4), new gltmode_t("GL_R3_G3_B2", GL11.GL_R3_G3_B2), // #ifdef GL_RGB2_EXT //new gltmode_t("GL_RGB2", GL.GL_RGB2_EXT) // #endif }; static final int NUM_GL_SOLID_MODES = gl_solid_modes.length; /* =============== GL_TextureMode =============== */ void GL_TextureMode(String string) { int i; for (i = 0; i < NUM_GL_MODES; i++) { if (modes[i].name.equalsIgnoreCase(string)) break; } if (i == NUM_GL_MODES) { VID.Printf(Defines.PRINT_ALL, "bad filter name: [" + string + "]\n"); return; } gl_filter_min = modes[i].minimize; gl_filter_max = modes[i].maximize; image_t glt; // change all the existing mipmap texture objects for (i = 0; i < numgltextures; i++) { glt = gltextures[i]; if (glt.type != it_pic && glt.type != it_sky) { GL_Bind(glt.texnum); gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, gl_filter_min); gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, gl_filter_max); } } } /* =============== GL_TextureAlphaMode =============== */ void GL_TextureAlphaMode(String string) { int i; for (i = 0; i < NUM_GL_ALPHA_MODES; i++) { if (gl_alpha_modes[i].name.equalsIgnoreCase(string)) break; } if (i == NUM_GL_ALPHA_MODES) { VID.Printf(Defines.PRINT_ALL, "bad alpha texture mode name: [" + string + "]\n"); return; } gl_tex_alpha_format = gl_alpha_modes[i].mode; } /* =============== GL_TextureSolidMode =============== */ void GL_TextureSolidMode(String string) { int i; for (i = 0; i < NUM_GL_SOLID_MODES; i++) { if (gl_solid_modes[i].name.equalsIgnoreCase(string)) break; } if (i == NUM_GL_SOLID_MODES) { VID.Printf(Defines.PRINT_ALL, "bad solid texture mode name: [" + string + "]\n"); return; } gl_tex_solid_format = gl_solid_modes[i].mode; } /* =============== GL_ImageList_f =============== */ void GL_ImageList_f() { image_t image; int texels; final String[] palstrings = { "RGB", "PAL" }; VID.Printf(Defines.PRINT_ALL, "------------------\n"); texels = 0; for (int i = 0; i < numgltextures; i++) { image = gltextures[i]; if (image.texnum <= 0) continue; texels += image.upload_width * image.upload_height; switch (image.type) { case it_skin : VID.Printf(Defines.PRINT_ALL, "M"); break; case it_sprite : VID.Printf(Defines.PRINT_ALL, "S"); break; case it_wall : VID.Printf(Defines.PRINT_ALL, "W"); break; case it_pic : VID.Printf(Defines.PRINT_ALL, "P"); break; default : VID.Printf(Defines.PRINT_ALL, " "); break; } VID.Printf( Defines.PRINT_ALL, " %3i %3i %s: %s\n", new Vargs(4).add(image.upload_width).add(image.upload_height).add(palstrings[(image.paletted) ? 1 : 0]).add( image.name)); } VID.Printf(Defines.PRINT_ALL, "Total texel count (not counting mipmaps): " + texels + '\n'); } /* ============================================================================= scrap allocation Allocate all the little status bar objects into a single texture to crutch up inefficient hardware / drivers ============================================================================= */ static final int MAX_SCRAPS = 1; static final int BLOCK_WIDTH = 256; static final int BLOCK_HEIGHT = 256; int[][] scrap_allocated = new int[MAX_SCRAPS][BLOCK_WIDTH]; byte[][] scrap_texels = new byte[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT]; boolean scrap_dirty; static class pos_t { int x, y; pos_t(int x, int y) { this.x = x; this.y = y; } } // returns a texture number and the position inside it int Scrap_AllocBlock(int w, int h, pos_t pos) { int i, j; int best, best2; int texnum; for (texnum = 0; texnum < MAX_SCRAPS; texnum++) { best = BLOCK_HEIGHT; for (i = 0; i < BLOCK_WIDTH - w; i++) { best2 = 0; for (j = 0; j < w; j++) { if (scrap_allocated[texnum][i + j] >= best) break; if (scrap_allocated[texnum][i + j] > best2) best2 = scrap_allocated[texnum][i + j]; } if (j == w) { // this is a valid spot pos.x = i; pos.y = best = best2; } } if (best + h > BLOCK_HEIGHT) continue; for (i = 0; i < w; i++) scrap_allocated[texnum][pos.x + i] = best + h; return texnum; } return -1; // Sys_Error ("Scrap_AllocBlock: full"); } int scrap_uploads = 0; void Scrap_Upload() { scrap_uploads++; GL_Bind(TEXNUM_SCRAPS); GL_Upload8(scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, false); scrap_dirty = false; } /* ================================================================= PCX LOADING ================================================================= */ /* ============== LoadPCX ============== */ byte[] LoadPCX(String filename, byte[][] palette, Dimension dim) { qfiles.pcx_t pcx; // // load the file // byte[] raw = FS.LoadFile(filename); if (raw == null) { VID.Printf(Defines.PRINT_DEVELOPER, "Bad pcx file " + filename + '\n'); return null; } // // parse the PCX file // pcx = new qfiles.pcx_t(raw); if (pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1 || pcx.bits_per_pixel != 8 || pcx.xmax >= 640 || pcx.ymax >= 480) { VID.Printf(Defines.PRINT_ALL, "Bad pcx file " + filename + '\n'); return null; } int width = pcx.xmax - pcx.xmin + 1; int height = pcx.ymax - pcx.ymin + 1; byte[] pix = new byte[width * height]; if (palette != null) { palette[0] = new byte[768]; System.arraycopy(raw, raw.length - 768, palette[0], 0, 768); } if (dim != null) { dim.width = width; dim.height = height; } // // decode pcx // int count = 0; byte dataByte = 0; int runLength = 0; int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width;) { dataByte = pcx.data.get(); if ((dataByte & 0xC0) == 0xC0) { runLength = dataByte & 0x3F; dataByte = pcx.data.get(); // write runLength pixel while (runLength-- > 0) { pix[count++] = dataByte; x++; } } else { // write one pixel pix[count++] = dataByte; x++; } } } return pix; } private Throwable gotoBreakOut = new Throwable(); private Throwable gotoDone = gotoBreakOut; // /* // ========================================================= // // TARGA LOADING // // ========================================================= // */ /* ============= LoadTGA ============= */ byte[] LoadTGA(String name, Dimension dim) { int columns, rows, numPixels; int pixbuf; // index into pic int row, column; byte[] raw; ByteBuffer buf_p; int length; qfiles.tga_t targa_header; byte[] pic = null; // // load the file // raw = FS.LoadFile(name); if (raw == null) { VID.Printf(Defines.PRINT_DEVELOPER, "Bad tga file "+ name +'\n'); return null; } targa_header = new qfiles.tga_t(raw); if (targa_header.image_type != 2 && targa_header.image_type != 10) Com.Error(Defines.ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n"); if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24)) Com.Error (Defines.ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -