/** * Constructor. * * @param gl the used OpenGl context. */ public UniqueColor(GL gl) { this.gl = gl; int[] colorBits = new int[3]; gl.glGetIntegerv(GL.GL_RED_BITS, colorBits, 0); gl.glGetIntegerv(GL.GL_GREEN_BITS, colorBits, 1); gl.glGetIntegerv(GL.GL_BLUE_BITS, colorBits, 2); redSize = 1 << colorBits[0]; greenSize = 1 << colorBits[1]; blueSize = 1 << colorBits[2]; }
public GLState(GL gl) { if (INSTANCES_COUNT == 0) { GLState.gl = gl; glTextureObjects = new HashSet<Integer>(); glVertexBuffers = new HashSet<Integer>(); glFrameBuffers = new HashSet<Integer>(); glRenderBuffers = new HashSet<Integer>(); glslPrograms = new HashSet<Integer>(); glslShaders = new HashSet<Integer>(); cgContexts = new HashSet<Object>(); cgPrograms = new HashSet<Object>(); cgEffects = new HashSet<Object>(); getVersionNumbers(); getAvailableExtensions(); int[] val = {0}; gl.glGetIntegerv(GL.GL_MAX_COLOR_ATTACHMENTS_EXT, val, 0); glMaxColorAttach = val[0]; glu = new GLU(); FBO = new GLFramebufferObject(gl); fboStack = new Stack<GLFramebufferObject>(); destTexStack = new Stack<GLTexture[]>(); screenFBO = new GLFramebufferObject(gl, true); currentFBO = screenFBO; emptyDestTex = new GLTexture[0]; currentDestTex = emptyDestTex; singleFBO = false; } INSTANCES_COUNT++; }
protected void initializeTexture(DrawContext dc) { Texture iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath()); if (iconTexture != null) return; try { InputStream iconStream = this.getClass().getResourceAsStream("/" + this.getIconFilePath()); if (iconStream == null) { File iconFile = new File(this.iconFilePath); if (iconFile.exists()) { iconStream = new FileInputStream(iconFile); } } iconTexture = TextureIO.newTexture(iconStream, false, null); iconTexture.bind(); this.iconWidth = iconTexture.getWidth(); this.iconHeight = iconTexture.getHeight(); dc.getTextureCache().put(this.getIconFilePath(), iconTexture); } catch (IOException e) { String msg = Logging.getMessage("layers.IOExceptionDuringInitialization"); Logging.logger().severe(msg); throw new WWRuntimeException(msg, e); } GL gl = dc.getGL(); gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); // _MIPMAP_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); // Enable texture anisotropy, improves "tilted" world map quality. int[] maxAnisotropy = new int[1]; gl.glGetIntegerv(GL.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy, 0); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy[0]); }
public void displayInit(Point pickPoint) { gl.glShadeModel(GL.GL_SMOOTH); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); if (pickPoint != null) { int[] vp = new int[4]; gl.glGetIntegerv(GL.GL_VIEWPORT, vp, 0); GLU glu = new GLU(); int px = (int) pickPoint.getX(); int py = (int) (vp[3] - pickPoint.getY()); glu.gluPickMatrix(px, py, 1e-2, 1e-2, vp, 0); } gl.glOrtho(0, bounds.getWidth(), 0, bounds.getHeight(), .1, depth); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt(0, 0, depth - 0.1, 0, 0, 0, 0, 1, 0); gl.glInitNames(); gl.glPushName(-1); }
public void initialize() { GL gl = GLContext.getCurrentGL(); if (gl.isExtensionAvailable("GL_VERSION_1_2")) { gl12 = true; } // workaround, always assume we support GLSL100 // some cards just don't report this correctly caps.add(Caps.GLSL100); // Default values for certain GL state. gl.getGL2ES1().glShadeModel(GLLightingFunc.GL_SMOOTH); gl.getGL2().glColorMaterial(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_DIFFUSE); gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Enable rescaling/normaling of normal vectors. // Fixes lighting issues with scaled models. if (gl12) { gl.glEnable(GL2ES1.GL_RESCALE_NORMAL); } else { gl.glEnable(GLLightingFunc.GL_NORMALIZE); } if (gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two")) { caps.add(Caps.NonPowerOfTwoTextures); } else { logger.log( Level.WARNING, "Your graphics card does not " + "support non-power-of-2 textures. " + "Some features might not work."); } gl.glGetIntegerv(GL2ES1.GL_MAX_LIGHTS, ib1); maxLights = ib1.get(0); gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, ib1); maxTexSize = ib1.get(0); }
public static ShadowMap getWorldShadowMapInstance(DrawContext dc) { if (worldShadowMap == null) { GL gl = dc.getGL(); int[] maxSize = new int[1]; gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, maxSize, 0); int texSize = Math.min(maxSize[0], 2048); worldShadowMap = new ShadowMap(texSize, texSize); return worldShadowMap; } else { return worldShadowMap; } }
public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); // test if antialiasing works int buf[] = new int[1]; int sbuf[] = new int[1]; gl.glGetIntegerv(GL.GL_SAMPLE_BUFFERS, buf, 0); Log.log(Log.MESSAGE, "OpenGL: Number of sample buffers is " + buf[0]); gl.glGetIntegerv(GL.GL_SAMPLES, sbuf, 0); Log.log(Log.MESSAGE, "OpenGL: Number of samples is " + sbuf[0]); if (buf[0] > 0 && sbuf[0] > 0) { // antialiasing is working Log.log(Log.MESSAGE, "OpenGL: This means that antialiasing is working. Antialiasing ON."); controller.setAntialiasing(true); } else { Log.log( Log.MESSAGE, "OpenGL: This means that antialiasing is not working. Antialiasing OFF."); controller.setAntialiasing(false); } controller.init(gl); }
/** * Queries OpenGL for errors in the vertex program. Errors are logged as SEVERE, noting both the * line number and message. */ private static void checkProgramError() { final GL gl = GLU.getCurrentGL(); if (gl.glGetError() == GL.GL_INVALID_OPERATION) { // retrieve the error position final IntBuffer errorloc = BufferUtils.createIntBuffer(16); gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errorloc); // TODO Check for integer logger.severe( "Error " + gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB) + " in vertex program on line " + errorloc.get(0)); } }
public Ray() { GL gl = GLU.getCurrentGL(); double[] modelview = new double[16]; double[] projection = new double[16]; int[] viewport = new int[4]; gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, modelview, 0); gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projection, 0); gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0); m_delta = new Vector2f(2.0f / viewport[2], 2.0f / viewport[3]); m_constant = new Vector2f( -viewport[0] * 2.0f / viewport[2] - 1.0f, -viewport[1] * 2.0f / viewport[3] - 1.0f); this.combine_projection_and_modelview(projection, modelview); }
/** * compute the max texture size to use * * @param gl * @return */ private static int resolveMaxSize(GL gl) { int[] result = new int[1]; gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, result, 0); int maxTexSize = result[0]; return Math.min(maxTexSize, MAX_SAMPLES_PER_TEXTURE); }
public void init(GLAutoDrawable glAutoDrawable) { StringBuilder sb = new StringBuilder(); sb.append(gov.nasa.worldwind.Version.getVersion() + "\n"); sb.append("\nSystem Properties\n"); sb.append("Processors: " + Runtime.getRuntime().availableProcessors() + "\n"); sb.append("Free memory: " + Runtime.getRuntime().freeMemory() + " bytes\n"); sb.append("Max memory: " + Runtime.getRuntime().maxMemory() + " bytes\n"); sb.append("Total memory: " + Runtime.getRuntime().totalMemory() + " bytes\n"); for (Map.Entry prop : System.getProperties().entrySet()) { sb.append(prop.getKey() + " = " + prop.getValue() + "\n"); } GL gl = glAutoDrawable.getGL(); sb.append("\nOpenGL Values\n"); String oglVersion = gl.glGetString(GL.GL_VERSION); sb.append("OpenGL version: " + oglVersion + "\n"); String oglVendor = gl.glGetString(GL.GL_VENDOR); sb.append("OpenGL vendor: " + oglVendor + "\n"); String oglRenderer = gl.glGetString(GL.GL_RENDERER); sb.append("OpenGL renderer: " + oglRenderer + "\n"); int[] intVals = new int[2]; for (Attr attr : attrs) { sb.append(attr.name).append(": "); if (attr.attr instanceof Integer) { gl.glGetIntegerv((Integer) attr.attr, intVals, 0); sb.append(intVals[0]).append(intVals[1] > 0 ? ", " + intVals[1] : ""); } sb.append("\n"); } String extensionString = gl.glGetString(GL.GL_EXTENSIONS); String[] extensions = extensionString.split(" "); sb.append("Extensions\n"); for (String ext : extensions) { sb.append(" " + ext + "\n"); } sb.append("\nJOGL Values\n"); String pkgName = "javax.media.opengl"; try { getClass().getClassLoader().loadClass(pkgName + ".GL"); Package p = Package.getPackage(pkgName); if (p == null) { sb.append("WARNING: Package.getPackage(" + pkgName + ") is null\n"); } else { sb.append(p + "\n"); sb.append("Specification Title = " + p.getSpecificationTitle() + "\n"); sb.append("Specification Vendor = " + p.getSpecificationVendor() + "\n"); sb.append("Specification Version = " + p.getSpecificationVersion() + "\n"); sb.append("Implementation Vendor = " + p.getImplementationVendor() + "\n"); sb.append("Implementation Version = " + p.getImplementationVersion() + "\n"); } } catch (ClassNotFoundException e) { sb.append("Unable to load " + pkgName + "\n"); } this.outputArea.setText(sb.toString()); }
public static int queryGLInteger(int param, GL gl) { int[] value = new int[1]; gl.glGetIntegerv(param, value, 0); return value[0]; }
/* Given user requested textures size, determine if it fits. If it doesn't then * halve both sides and make the determination again until it does fit ( for * IR only ). * Note that proxy textures are not implemented in RE* even though they * advertise the texture extension. * Note that proxy textures are implemented but not according to spec in IMPACT* */ public static void closestFit( GL gl, int target, int width, int height, int internalFormat, int format, int type, int[] newWidth, int[] newHeight) { // Use proxy textures if OpenGL version >= 1.1 if (Double.parseDouble(gl.glGetString(GL.GL_VERSION).trim().substring(0, 3)) >= 1.1) { int widthPowerOf2 = nearestPower(width); int heightPowerOf2 = nearestPower(height); int[] proxyWidth = new int[1]; boolean noProxyTextures = false; // Some drivers (in particular, ATI's) seem to set a GL error // when proxy textures are used even though this is in violation // of the spec. Guard against this and interactions with the // DebugGL by watching for GLException. try { do { // compute level 1 width & height, clamping each at 1 int widthAtLevelOne = ((width > 1) ? (widthPowerOf2 >> 1) : widthPowerOf2); int heightAtLevelOne = ((height > 1) ? (heightPowerOf2 >> 1) : heightPowerOf2); int proxyTarget; assert (widthAtLevelOne > 0); assert (heightAtLevelOne > 0); // does width x height at level 1 & all their mipmaps fit? if (target == GL2GL3.GL_TEXTURE_2D || target == GL2GL3.GL_PROXY_TEXTURE_2D) { proxyTarget = GL2GL3.GL_PROXY_TEXTURE_2D; gl.glTexImage2D( proxyTarget, 1, internalFormat, widthAtLevelOne, heightAtLevelOne, 0, format, type, null); } else if ((target == GL2GL3.GL_TEXTURE_CUBE_MAP_POSITIVE_X) || (target == GL2GL3.GL_TEXTURE_CUBE_MAP_NEGATIVE_X) || (target == GL2GL3.GL_TEXTURE_CUBE_MAP_POSITIVE_Y) || (target == GL2GL3.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) || (target == GL2GL3.GL_TEXTURE_CUBE_MAP_POSITIVE_Z) || (target == GL2GL3.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)) { proxyTarget = GL2GL3.GL_PROXY_TEXTURE_CUBE_MAP; gl.glTexImage2D( proxyTarget, 1, internalFormat, widthAtLevelOne, heightAtLevelOne, 0, format, type, null); } else { assert (target == GL2GL3.GL_TEXTURE_1D || target == GL2GL3.GL_PROXY_TEXTURE_1D); proxyTarget = GL2GL3.GL_PROXY_TEXTURE_1D; gl.getGL2GL3() .glTexImage1D( proxyTarget, 1, internalFormat, widthAtLevelOne, 0, format, type, null); } if (gl.isGL2GL3()) { gl.getGL2GL3() .glGetTexLevelParameteriv(proxyTarget, 1, GL2GL3.GL_TEXTURE_WIDTH, proxyWidth, 0); } else { proxyWidth[0] = 0; } // does it fit? if (proxyWidth[0] == 0) { // nope, so try again with theses sizes if (widthPowerOf2 == 1 && heightPowerOf2 == 1) { /* A 1x1 texture couldn't fit for some reason so break out. This * should never happen. But things happen. The disadvantage with * this if-statement is that we will never be aware of when this * happens since it will silently branch out. */ noProxyTextures = true; break; } widthPowerOf2 = widthAtLevelOne; heightPowerOf2 = heightAtLevelOne; } // else it does fit } while (proxyWidth[0] == 0); } catch (GLException e) { noProxyTextures = true; } // loop must terminate // return the width & height at level 0 that fits if (!noProxyTextures) { newWidth[0] = widthPowerOf2; newHeight[0] = heightPowerOf2; return; } } int[] maxsize = new int[1]; gl.glGetIntegerv(GL2GL3.GL_MAX_TEXTURE_SIZE, maxsize, 0); // clamp user's texture sizes to maximum sizes, if necessary newWidth[0] = nearestPower(width); if (newWidth[0] > maxsize[0]) { newWidth[0] = maxsize[0]; } newHeight[0] = nearestPower(height); if (newHeight[0] > maxsize[0]) { newHeight[0] = maxsize[0]; } }
public void display(GLAutoDrawable glDrawable) { GL gl = glDrawable.getGL(); // Store old matrices gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glViewport(0, 0, glDrawable.getWidth(), glDrawable.getHeight()); // Store enabled state and disable lighting, texture mapping and the depth buffer gl.glPushAttrib(GL.GL_ENABLE_BIT); gl.glDisable(GL.GL_BLEND); gl.glDisable(GL.GL_LIGHTING); gl.glDisable(GL.GL_TEXTURE_2D); gl.glDisable(GL.GL_DEPTH_TEST); // Retrieve the current viewport and switch to orthographic mode IntBuffer viewPort = BufferUtil.newIntBuffer(4); gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort); glu.gluOrtho2D(0, viewPort.get(2), viewPort.get(3), 0); // Render the text gl.glColor3f(1, 1, 1); int x = OFFSET; int maxx = 0; int y = OFFSET + CHAR_HEIGHT; if (keyboardEntries.size() > 0) { gl.glRasterPos2i(x, y); glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, KEYBOARD_CONTROLS); maxx = Math.max( maxx, OFFSET + glut.glutBitmapLength(GLUT.BITMAP_HELVETICA_12, KEYBOARD_CONTROLS)); y += OFFSET; x += INDENT; for (int i = 0; i < keyboardEntries.size(); i++) { gl.glRasterPos2f(x, y); String text = (String) keyboardEntries.get(i); glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, text); maxx = Math.max(maxx, OFFSET + glut.glutBitmapLength(GLUT.BITMAP_HELVETICA_12, text)); y += OFFSET; } } if (mouseEntries.size() > 0) { x = maxx + OFFSET; y = OFFSET + CHAR_HEIGHT; gl.glRasterPos2i(x, y); glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, MOUSE_CONTROLS); y += OFFSET; x += INDENT; for (int i = 0; i < mouseEntries.size(); i++) { gl.glRasterPos2f(x, y); glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, (String) mouseEntries.get(i)); y += OFFSET; } } // Restore enabled state gl.glPopAttrib(); // Restore old matrices gl.glPopMatrix(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPopMatrix(); }
private void updateSubImageImpl( TextureData data, int newTarget, int mipmapLevel, int dstx, int dsty, int srcx, int srcy, int width, int height) throws GLException { GL gl = GLU.getCurrentGL(); data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr")); data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2")); Buffer buffer = data.getBuffer(); if (buffer == null && data.getMipmapData() == null) { // Assume user just wanted to get the Texture object allocated return; } int rowlen = data.getRowLength(); int dataWidth = data.getWidth(); int dataHeight = data.getHeight(); if (data.getMipmapData() != null) { // Compute the width, height and row length at the specified mipmap level // Note we do not support specification of the row length for // mipmapped textures at this point for (int i = 0; i < mipmapLevel; i++) { width = Math.max(width / 2, 1); height = Math.max(height / 2, 1); dataWidth = Math.max(dataWidth / 2, 1); dataHeight = Math.max(dataHeight / 2, 1); } rowlen = 0; buffer = data.getMipmapData()[mipmapLevel]; } // Clip incoming rectangles to what is available both on this // texture and in the incoming TextureData if (srcx < 0) { width += srcx; srcx = 0; } if (srcy < 0) { height += srcy; srcy = 0; } // NOTE: not sure whether the following two are the correct thing to do if (dstx < 0) { width += dstx; dstx = 0; } if (dsty < 0) { height += dsty; dsty = 0; } if (srcx + width > dataWidth) { width = dataWidth - srcx; } if (srcy + height > dataHeight) { height = dataHeight - srcy; } if (dstx + width > texWidth) { width = texWidth - dstx; } if (dsty + height > texHeight) { height = texHeight - dsty; } checkCompressedTextureExtensions(data); if (data.isDataCompressed()) { gl.glCompressedTexSubImage2D( newTarget, mipmapLevel, dstx, dsty, width, height, data.getInternalFormat(), buffer.remaining(), buffer); } else { int[] align = new int[1]; int[] rowLength = new int[1]; int[] skipRows = new int[1]; int[] skipPixels = new int[1]; gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment gl.glGetIntegerv(GL.GL_UNPACK_ROW_LENGTH, rowLength, 0); // save row length gl.glGetIntegerv(GL.GL_UNPACK_SKIP_ROWS, skipRows, 0); // save skipped rows gl.glGetIntegerv(GL.GL_UNPACK_SKIP_PIXELS, skipPixels, 0); // save skipped pixels gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment()); if (DEBUG && VERBOSE) { System.out.println("Row length = " + rowlen); System.out.println("skip pixels = " + srcx); System.out.println("skip rows = " + srcy); System.out.println("dstx = " + dstx); System.out.println("dsty = " + dsty); System.out.println("width = " + width); System.out.println("height = " + height); } gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rowlen); gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, srcy); gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, srcx); gl.glTexSubImage2D( newTarget, mipmapLevel, dstx, dsty, width, height, data.getPixelFormat(), data.getPixelType(), buffer); gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rowLength[0]); // restore row length gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, skipRows[0]); // restore skipped rows gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, skipPixels[0]); // restore skipped pixels } }
/** * Updates the content area of the specified target of this texture using the data in the given * image. In general this is intended for construction of cube maps. * * @throws GLException if no OpenGL context was current or if any OpenGL-related errors occurred */ public void updateImage(TextureData data, int target) throws GLException { GL gl = GLU.getCurrentGL(); imgWidth = data.getWidth(); imgHeight = data.getHeight(); aspectRatio = (float) imgWidth / (float) imgHeight; mustFlipVertically = data.getMustFlipVertically(); int texTarget = 0; int texParamTarget = this.target; // See whether we have automatic mipmap generation support boolean haveAutoMipmapGeneration = (gl.isExtensionAvailable("GL_VERSION_1_4") || gl.isExtensionAvailable("GL_SGIS_generate_mipmap")); // Indicate to the TextureData what functionality is available data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr")); data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2")); // Note that automatic mipmap generation doesn't work for // GL_ARB_texture_rectangle if ((!isPowerOfTwo(imgWidth) || !isPowerOfTwo(imgHeight)) && !haveNPOT(gl)) { haveAutoMipmapGeneration = false; } boolean expandingCompressedTexture = false; if (data.getMipmap() && !haveAutoMipmapGeneration) { // GLU always scales the texture's dimensions to be powers of // two. It also doesn't really matter exactly what the texture // width and height are because the texture coords are always // between 0.0 and 1.0. imgWidth = nextPowerOfTwo(imgWidth); imgHeight = nextPowerOfTwo(imgHeight); texWidth = imgWidth; texHeight = imgHeight; texTarget = GL.GL_TEXTURE_2D; } else if ((isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight)) || haveNPOT(gl)) { if (DEBUG) { if (isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight)) { System.err.println("Power-of-two texture"); } else { System.err.println("Using GL_ARB_texture_non_power_of_two"); } } texWidth = imgWidth; texHeight = imgHeight; texTarget = GL.GL_TEXTURE_2D; } else if (haveTexRect(gl) && !data.isDataCompressed()) { // GL_ARB_texture_rectangle does not work for compressed textures if (DEBUG) { System.err.println("Using GL_ARB_texture_rectangle"); } texWidth = imgWidth; texHeight = imgHeight; texTarget = GL.GL_TEXTURE_RECTANGLE_ARB; } else { // If we receive non-power-of-two compressed texture data and // don't have true hardware support for compressed textures, we // can fake this support by producing an empty "compressed" // texture image, using glCompressedTexImage2D with that to // allocate the texture, and glCompressedTexSubImage2D with the // incoming data. if (data.isDataCompressed()) { if (data.getMipmapData() != null) { // We don't currently support expanding of compressed, // mipmapped non-power-of-two textures to the nearest power // of two; the obvious port of the non-mipmapped code didn't // work throw new GLException( "Mipmapped non-power-of-two compressed textures only supported on OpenGL 2.0 hardware (GL_ARB_texture_non_power_of_two)"); } expandingCompressedTexture = true; } if (DEBUG) { System.err.println("Expanding texture to power-of-two dimensions"); } if (data.getBorder() != 0) { throw new RuntimeException( "Scaling up a non-power-of-two texture which has a border won't work"); } texWidth = nextPowerOfTwo(imgWidth); texHeight = nextPowerOfTwo(imgHeight); texTarget = GL.GL_TEXTURE_2D; } texParamTarget = texTarget; setImageSize(imgWidth, imgHeight, texTarget); if (target != 0) { // Allow user to override auto detection and skip bind step (for // cubemap construction) texTarget = target; if (this.target == 0) { throw new GLException("Override of target failed; no target specified yet"); } texParamTarget = this.target; gl.glBindTexture(texParamTarget, texID); } else { gl.glBindTexture(texTarget, texID); } if (data.getMipmap() && !haveAutoMipmapGeneration) { int[] align = new int[1]; gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment()); if (data.isDataCompressed()) { throw new GLException("May not request mipmap generation for compressed textures"); } try { GLU glu = new GLU(); glu.gluBuild2DMipmaps( texTarget, data.getInternalFormat(), data.getWidth(), data.getHeight(), data.getPixelFormat(), data.getPixelType(), data.getBuffer()); } finally { gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment } } else { checkCompressedTextureExtensions(data); Buffer[] mipmapData = data.getMipmapData(); if (mipmapData != null) { int width = texWidth; int height = texHeight; for (int i = 0; i < mipmapData.length; i++) { if (data.isDataCompressed()) { // Need to use glCompressedTexImage2D directly to allocate and fill this image // Avoid spurious memory allocation when possible gl.glCompressedTexImage2D( texTarget, i, data.getInternalFormat(), width, height, data.getBorder(), mipmapData[i].remaining(), mipmapData[i]); } else { // Allocate texture image at this level gl.glTexImage2D( texTarget, i, data.getInternalFormat(), width, height, data.getBorder(), data.getPixelFormat(), data.getPixelType(), null); updateSubImageImpl(data, texTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight()); } width = Math.max(width / 2, 1); height = Math.max(height / 2, 1); } } else { if (data.isDataCompressed()) { if (!expandingCompressedTexture) { // Need to use glCompressedTexImage2D directly to allocate and fill this image // Avoid spurious memory allocation when possible gl.glCompressedTexImage2D( texTarget, 0, data.getInternalFormat(), texWidth, texHeight, data.getBorder(), data.getBuffer().capacity(), data.getBuffer()); } else { ByteBuffer buf = DDSImage.allocateBlankBuffer(texWidth, texHeight, data.getInternalFormat()); gl.glCompressedTexImage2D( texTarget, 0, data.getInternalFormat(), texWidth, texHeight, data.getBorder(), buf.capacity(), buf); updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight()); } } else { if (data.getMipmap() && haveAutoMipmapGeneration) { // For now, only use hardware mipmapping for uncompressed 2D // textures where the user hasn't explicitly specified // mipmap data; don't know about interactions between // GL_GENERATE_MIPMAP and glCompressedTexImage2D gl.glTexParameteri(texParamTarget, GL.GL_GENERATE_MIPMAP, GL.GL_TRUE); usingAutoMipmapGeneration = true; } gl.glTexImage2D( texTarget, 0, data.getInternalFormat(), texWidth, texHeight, data.getBorder(), data.getPixelFormat(), data.getPixelType(), null); updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight()); } } } int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR); int magFilter = GL.GL_LINEAR; int wrapMode = (gl.isExtensionAvailable("GL_VERSION_1_2") ? GL.GL_CLAMP_TO_EDGE : GL.GL_CLAMP); // REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB if (texTarget != GL.GL_TEXTURE_RECTANGLE_ARB) { gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_MIN_FILTER, minFilter); gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_MAG_FILTER, magFilter); gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_S, wrapMode); gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_T, wrapMode); if (this.target == GL.GL_TEXTURE_CUBE_MAP) { gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_R, wrapMode); } } // Don't overwrite target if we're loading e.g. faces of a cube // map if ((this.target == 0) || (this.target == GL.GL_TEXTURE_2D) || (this.target == GL.GL_TEXTURE_RECTANGLE_ARB)) { this.target = texTarget; } // This estimate will be wrong for cube maps estimatedMemorySize = data.getEstimatedMemorySize(); }
public static void retrieveStoreModes3D(GL gl, PixelStorageModes psm) { int[] a = new int[1]; gl.glGetIntegerv(GL2GL3.GL_UNPACK_ALIGNMENT, a, 0); psm.setUnpackAlignment(a[0]); gl.glGetIntegerv(GL2GL3.GL_UNPACK_ROW_LENGTH, a, 0); psm.setUnpackRowLength(a[0]); gl.glGetIntegerv(GL2GL3.GL_UNPACK_SKIP_ROWS, a, 0); psm.setUnpackSkipRows(a[0]); gl.glGetIntegerv(GL2GL3.GL_UNPACK_SKIP_PIXELS, a, 0); psm.setUnpackSkipPixels(a[0]); gl.glGetIntegerv(GL2GL3.GL_UNPACK_LSB_FIRST, a, 0); psm.setUnpackLsbFirst((a[0] == 1)); gl.glGetIntegerv(GL2GL3.GL_UNPACK_SWAP_BYTES, a, 0); psm.setUnpackSwapBytes((a[0] == 1)); gl.glGetIntegerv(GL2GL3.GL_UNPACK_SKIP_IMAGES, a, 0); psm.setUnpackSkipImages(a[0]); gl.glGetIntegerv(GL2GL3.GL_UNPACK_IMAGE_HEIGHT, a, 0); psm.setUnpackImageHeight(a[0]); gl.glGetIntegerv(GL2GL3.GL_PACK_ALIGNMENT, a, 0); psm.setPackAlignment(a[0]); gl.glGetIntegerv(GL2GL3.GL_PACK_ROW_LENGTH, a, 0); psm.setPackRowLength(a[0]); gl.glGetIntegerv(GL2GL3.GL_PACK_SKIP_ROWS, a, 0); psm.setPackSkipRows(a[0]); gl.glGetIntegerv(GL2GL3.GL_PACK_SKIP_PIXELS, a, 0); psm.setPackSkipPixels(a[0]); gl.glGetIntegerv(GL2GL3.GL_PACK_LSB_FIRST, a, 0); psm.setPackLsbFirst((a[0] == 1)); gl.glGetIntegerv(GL2GL3.GL_PACK_SWAP_BYTES, a, 0); psm.setPackSwapBytes((a[0] == 1)); gl.glGetIntegerv(GL2GL3.GL_PACK_SKIP_IMAGES, a, 0); psm.setPackSkipImages(a[0]); gl.glGetIntegerv(GL2GL3.GL_PACK_IMAGE_HEIGHT, a, 0); psm.setPackImageHeight(a[0]); }