/** * Sets a specified texture's OpenGL <code>Texture</code> parameters. * * @param dc the current draw context. * @param texture the texture whose parameters to set. */ protected void setTextureParameters(DrawContext dc, Texture texture) { // Enable the appropriate mip-mapping texture filters if the caller has specified that // mip-mapping should be // enabled, and the texture itself supports mip-mapping. boolean useMipMapFilter = this.useMipMaps && (this.getTextureData().getMipmapData() != null || texture.isUsingAutoMipmapGeneration()); GL gl = dc.getGL(); gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, useMipMapFilter ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); if (this.isUseAnisotropy() && useMipMapFilter) { double maxAnisotropy = dc.getGLRuntimeCapabilities().getMaxTextureAnisotropy(); if (dc.getGLRuntimeCapabilities().isUseAnisotropicTextureFilter() && maxAnisotropy >= 2.0) { gl.glTexParameterf( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, (float) maxAnisotropy); } } }
/** * Sets the OpenGL floating-point texture parameter for the texture's target. This gives control * over parameters such as GL_TEXTURE_MAX_ANISOTROPY_EXT. Causes this texture to be bound to the * current texture state. * * @throws GLException if no OpenGL context was current or if any OpenGL-related errors occurred */ public void setTexParameterf(int parameterName, float value) { bind(); GL gl = GLU.getCurrentGL(); gl.glTexParameterf(target, parameterName, value); }
/** * Loads a TGA file into memory * * @param gl * @param texture * @param filename * @throws IOException */ private void loadTGA(GL gl, TextureImage texture, String filename) throws IOException { // Used To Compare TGA Header ByteBuffer TGAcompare = GLBuffers.newDirectByteBuffer(12); // Uncompressed TGA Header byte[] TGAheader = new byte[] {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ByteBuffer header = GLBuffers.newDirectByteBuffer(6); // First 6 Useful // Bytes // From The // Header int bytesPerPixel, // Holds Number Of Bytes Per Pixel Used In The TGA // File imageSize, // Used To Store The Image Size When Setting Aside Ram type = GL.GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP) ReadableByteChannel file = null; try { file = Channels.newChannel(ResourceRetriever.getResourceAsStream(filename)); readBuffer(file, TGAcompare); readBuffer(file, header); for (int i = 0; i < TGAcompare.capacity(); i++) // Does The Header Match What We Want? if (TGAcompare.get(i) != TGAheader[i]) { throw new IOException("Invalid TGA header"); } texture.width = header.get(1) << 8 | header.get(0); // Determine The // TGA // Width(highbyte*256+lowbyte) texture.height = header.get(3) << 8 | header.get(2); // Determine // The TGA // Height(highbyte*256+lowbyte) if (texture.width <= 0) { // Is The Width Less Than Or Equal To Zero throw new IOException("Image has negative width"); } if (texture.height <= 0) { // Is The Height Less Than Or Equal To // Zero throw new IOException("Image has negative height"); } if (header.get(4) != 24 && header.get(4) != 32) { // Is The TGA 24 // or 32 Bit? throw new IOException("Image is not 24 or 32-bit"); } texture.bpp = header.get(4); // Grab The TGA's Bits Per Pixel (24 or // 32) bytesPerPixel = texture.bpp / 8; // Divide By 8 To Get The Bytes Per // Pixel // Calculate the memory required for the TGA Data imageSize = texture.width * texture.height * bytesPerPixel; // Reserve memory to hold the TGA Data texture.imageData = GLBuffers.newDirectByteBuffer(imageSize); readBuffer(file, texture.imageData); // Loop Through The Image Data for (int i = 0; i < imageSize; i += bytesPerPixel) { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) // Temporarily Store The Value At Image Data 'i' byte temp = texture.imageData.get(i); // Set the 1st Byte to the value Of the 3rd Byte texture.imageData.put(i, texture.imageData.get(i + 2)); // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) texture.imageData.put(i + 2, temp); } // Build A Texture From The Data gl.glGenTextures(1, texture.texID, 0); // Generate OpenGL texture // IDs gl.glBindTexture(GL.GL_TEXTURE_2D, texture.texID[0]); // Bind Our // Texture gl.glTexParameterf( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); // Linear Filtered gl.glTexParameterf( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); // Linear Filtered if (texture.bpp == 24) // Was The TGA 24 Bits type = GL.GL_RGB; // If So Set The 'type' To GL_RGB gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, type, texture.width, texture.height, 0, type, GL.GL_UNSIGNED_BYTE, texture.imageData); } finally { if (file != null) { try { file.close(); } catch (IOException n) { } } } }
/** * Issue ogl commands needed for this component * * @param gl The gl context to draw with */ public void render(GL gl) { if (numSources == 0) return; Integer t_id = textureIdMap.get(gl); if (t_id == null) { int[] tex_id_tmp = new int[1]; gl.glGenTextures(1, tex_id_tmp, 0); textureIdMap.put(gl, new Integer(tex_id_tmp[0])); gl.glBindTexture(textureType, tex_id_tmp[0]); // Set the flag so that we update later in the method imageChanged.put(gl, true); stateChanged.put(gl, true); updateManagers[0].addContext(gl); } else { gl.glBindTexture(textureType, t_id.intValue()); } if (stateChanged.getState(gl)) { stateChanged.put(gl, false); gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_S, boundaryModeS); gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_T, boundaryModeT); gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_R, boundaryModeR); int mode = 0; switch (magFilter) { case MAGFILTER_FASTEST: case MAGFILTER_BASE_LEVEL_POINT: mode = GL.GL_NEAREST; break; case MAGFILTER_NICEST: case MAGFILTER_BASE_LEVEL_LINEAR: mode = GL.GL_LINEAR; break; default: System.out.println("Unknown mode in MagFilter: " + magFilter); } gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAG_FILTER, mode); switch (minFilter) { case MINFILTER_FASTEST: case MINFILTER_BASE_LEVEL_POINT: mode = GL.GL_NEAREST; break; case MINFILTER_BASE_LEVEL_LINEAR: mode = GL.GL_LINEAR; break; case MINFILTER_MULTI_LEVEL_LINEAR: mode = GL.GL_LINEAR_MIPMAP_LINEAR; break; case MINFILTER_MULTI_LEVEL_POINT: mode = GL.GL_NEAREST_MIPMAP_NEAREST; break; case MINFILTER_NICEST: mode = (numSources > 1) ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR; break; default: System.out.println("Unknown mode in MinFilter: " + minFilter); } gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MIN_FILTER, mode); if (anisotropicMode != ANISOTROPIC_MODE_NONE) { gl.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropicDegree); } if (priority >= 0) { gl.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_PRIORITY, priority); } if (borderColor != null) { gl.glTexParameterfv(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_BORDER_COLOR, borderColor, 0); } if (format == FORMAT_DEPTH_COMPONENT) { gl.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_DEPTH_TEXTURE_MODE, depthComponentMode); gl.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_COMPARE_MODE, compareMode); gl.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_COMPARE_FUNC, compareFunction); } } if (imageChanged.getState(gl)) { imageChanged.put(gl, false); TextureComponent3D img = (TextureComponent3D) sources[0]; int width = img.getWidth(); int height = img.getHeight(); int depth = img.getDepth(); int num_levels = (mipMapMode == MODE_BASE_LEVEL) ? 1 : img.getNumLevels(); for (int i = 0; i < num_levels; i++) { ByteBuffer pixels = img.getData(i); pixels.rewind(); int comp_format = img.getFormat(i); int int_format = GL.GL_RGB; int ext_format = GL.GL_RGB; switch (comp_format) { case TextureComponent.FORMAT_RGB: int_format = GL.GL_RGB; ext_format = GL.GL_RGB; break; case TextureComponent.FORMAT_RGBA: int_format = GL.GL_RGBA; ext_format = GL.GL_RGBA; break; case TextureComponent.FORMAT_BGR: int_format = GL.GL_BGR; ext_format = GL.GL_BGR; break; case TextureComponent.FORMAT_BGRA: int_format = GL.GL_BGRA; ext_format = GL.GL_BGRA; break; case TextureComponent.FORMAT_INTENSITY_ALPHA: int_format = GL.GL_LUMINANCE_ALPHA; ext_format = GL.GL_LUMINANCE_ALPHA; break; case TextureComponent.FORMAT_SINGLE_COMPONENT: switch (format) { case FORMAT_INTENSITY: int_format = GL.GL_INTENSITY; ext_format = GL.GL_LUMINANCE; break; case FORMAT_LUMINANCE: int_format = GL.GL_LUMINANCE; ext_format = GL.GL_LUMINANCE; break; case FORMAT_ALPHA: int_format = GL.GL_ALPHA; ext_format = GL.GL_ALPHA; } break; } gl.glTexImage3D( GL.GL_TEXTURE_3D, i, int_format, width, height, depth, 0, ext_format, GL.GL_UNSIGNED_BYTE, pixels); pixels.clear(); pixels = null; // TODO: Do we want this? We lose caching but it saves one copy of the texture // sources[0].clearData(i); if (width > 1) width = width >> 1; if (height > 1) height = height >> 1; if (depth > 1) depth = depth >> 1; } } // Any updates? Do those now int num_updates = updateManagers[0].getNumUpdatesPending(gl); if (num_updates != 0) { TextureUpdateData[] tud = updateManagers[0].getUpdatesAndClear(gl); for (int i = 0; i < num_updates; i++) { tud[i].pixels.rewind(); gl.glTexSubImage3D( GL.GL_TEXTURE_3D, tud[i].level, tud[i].x, tud[i].y, tud[i].z, tud[i].width, tud[i].height, tud[i].depth, tud[i].format, GL.GL_UNSIGNED_BYTE, tud[i].pixels); } } }