/** * Renders the tile to the given context, in the process building all needed resources. * * @param gl */ public void render(GL gl) { projection = ProjectionFactory.getCurrentProjection(); heightmap = State.getInstance().getLoadedHeightmap(); // BUILD TEXTURES IF NECESSARY if (!gl.glIsTexture(textureID)) { textureID = createTexture(gl, getImage(), false); // prerenderToTexture(gl); } if (!gl.glIsTexture(grainTextureID)) { createGrainTexture(gl); } // RENDER TILE FROM DISPLAY LIST, OR ELSE BUILD DISPLAY LIST if (gl.glIsList(displaylistID)) { gl.glCallList(displaylistID); } else { displaylistID = gl.glGenLists(1); gl.glNewList(displaylistID, GL_COMPILE_AND_EXECUTE); gl.glActiveTexture(GL_TEXTURE0); gl.glEnable(GL_TEXTURE_2D); gl.glBindTexture(GL_TEXTURE_2D, grainTextureID); gl.glActiveTexture(GL_TEXTURE1); gl.glEnable(GL_TEXTURE_2D); gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); gl.glBindTexture(GL_TEXTURE_2D, textureID); gl.glColor3f(1, 1, 1); float[] color = new float[3]; float hRes = HEIGHT_RESOLUTION - 1; float stepSize = bounds.getWidth() / hRes; Coordinates pos = new Coordinates(); for (int x = 0; x < hRes; x++) { gl.glBegin(GL_TRIANGLE_STRIP); for (int y = 0; y <= hRes; y++) { for (int i = 0; i < 2; i++) { pos.setLatitude(bounds.getTop() + y * stepSize); pos.setLongitude(bounds.getLeft() + (x + i) * stepSize); gl.glMultiTexCoord2f( GL_TEXTURE0, (x + i) / (float) GRAIN_RESOLUTION, y / (float) GRAIN_RESOLUTION); gl.glMultiTexCoord2f(GL_TEXTURE1, (x + i) / hRes, y / hRes); float height = heights[x + HEIGHT_BORDER + i][y + HEIGHT_BORDER]; getHeightColor(color, height); float shade = getShade(x + i, y, stepSize); gl.glColor3f(color[0] * shade, color[1] * shade, color[2] * shade); gl.glVertex3f(pos.getLongitude(), pos.getLatitude(), height); } } gl.glEnd(); } gl.glDisable(GL_TEXTURE_2D); gl.glActiveTexture(GL_TEXTURE0); renderPOIs(gl); gl.glEndList(); } }
public void copyTex(GLTexture srcTex, GLTexture destTex) { float uscale = srcTex.getMaxTextureCoordS(); float vscale = srcTex.getMaxTextureCoordT(); float cx = 0.0f; float sx = +1.0f; if (destTex.isFlippedX()) { cx = 1.0f; sx = -1.0f; } float cy = 0.0f; float sy = +1.0f; if (destTex.isFlippedY()) { cy = 1.0f; sy = -1.0f; } gl.glEnable(srcTex.getTextureTarget()); gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(srcTex.getTextureTarget(), srcTex.getTextureID()); pushFramebuffer(); setFramebuffer(FBO); FBO.setDrawBuffer(destTex.getTextureTarget(), destTex.getTextureID()); saveView(); setOrthographicView(destTex.width, destTex.height); gl.glEnable(srcTex.getTextureTarget()); gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(srcTex.getTextureTarget(), srcTex.getTextureID()); gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gl.glBegin(GL.GL_QUADS); gl.glTexCoord2f((cx + sx * 0.0f) * uscale, (cy + sy * 0.0f) * vscale); gl.glVertex2f(0.0f, 0.0f); gl.glTexCoord2f((cx + sx * 1.0f) * uscale, (cy + sy * 0.0f) * vscale); gl.glVertex2f(srcTex.width, 0.0f); gl.glTexCoord2f((cx + sx * 1.0f) * uscale, (cy + sy * 1.0f) * vscale); gl.glVertex2f(srcTex.width, srcTex.height); gl.glTexCoord2f((cx + sx * 0.0f) * uscale, (cy + sy * 1.0f) * vscale); gl.glVertex2f(0.0f, srcTex.height); gl.glEnd(); gl.glBindTexture(srcTex.getTextureTarget(), 0); restoreView(); popFramebuffer(); }
private void display(GL gl, GLU glu, final JoglFrameBufferObject theFBO) { final int w = theFBO.getPixelWidth(); final int h = theFBO.getPixelHeight(); /* bind position data */ gl.glEnableClientState(GL.GL_VERTEX_ARRAY); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, _myVBO); gl.glVertexPointer(4, GL.GL_FLOAT, 0, 0); /* bind point size data */ _myShaderManager.enable(_myPointSpriteShader); final int myPointSizeAttrib = gl.glGetAttribLocation(_myPointSpriteShader.getOpenGLID(), "vertexAttribute"); gl.glEnableVertexAttribArray(myPointSizeAttrib); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, _myIBO); gl.glVertexAttribPointer(myPointSizeAttrib, 3, GL.GL_FLOAT, false, 0, 0); gl.glEnable(GL.GL_VERTEX_PROGRAM_POINT_SIZE_ARB); /* --- */ final JoglFrameBufferObject READ_FBO = _myFBO; _myShaderManager.setUniform( _myPointSpriteShader, "textureVelocity", READ_FBO.additional_texture(BufferInfo.SECONDARY).getTextureUnit() - GL.GL_TEXTURE0); _myShaderManager.setUniform(_myPointSpriteShader, "velocityThreshold", velocity_threshold); _myShaderManager.setUniform(_myPointSpriteShader, "sizeThreshold", size_threshold); _myShaderManager.setUniform(_myPointSpriteShader, "pointSize", point_size); _myShaderManager.setUniform(_myPointSpriteShader, "flowdirection", flow_direction); _myShaderManager.setUniform(_myPointSpriteShader, "collisionratio", collision_ratio); gl.glActiveTexture(READ_FBO.additional_texture(BufferInfo.SECONDARY).getTextureUnit()); gl.glBindTexture( READ_FBO.additional_texture(BufferInfo.SECONDARY).getTextureTarget(), READ_FBO.additional_texture(BufferInfo.SECONDARY).getTextureID()); JoglUtil.printGLError(gl, glu, "binding texture", true); gl.glDrawArrays(GL.GL_POINTS, 0, w * h); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); gl.glDisableClientState(GL.GL_VERTEX_ARRAY); gl.glDisableVertexAttribArray(myPointSizeAttrib); _myShaderManager.disable(); gl.glDisable(GL.GL_VERTEX_PROGRAM_POINT_SIZE_ARB); gl.glBindTexture(READ_FBO.additional_texture(BufferInfo.SECONDARY).getTextureTarget(), 0); JoglUtil.printGLError(gl, glu, "display()", true); }
/** * initPermTexture(GLuinttexID) - create and load a 2D texture for a combined index permutation * and gradient lookup table. This texture is used for 2D and 3D noise, both classic and simplex. */ private void initPermTexture(GL gl, int[] texID) { ByteBuffer pixels; int i, j; gl.glGenTextures(1, texID, 0); // Generate a unique texture ID gl.glBindTexture(GL.GL_TEXTURE_2D, texID[0]); // Bind the texture to texture unit 0 pixels = ByteBuffer.allocateDirect(256 * 256 * 4); for (i = 0; i < 256; i++) for (j = 0; j < 256; j++) { int offset = (i * 256 + j) * 4; int value = perm[(j + perm[i]) & 0xFF]; pixels.put(offset, (byte) (grad3[value & 0x0F][0] * 64 + 64)); // Gradient x pixels.put(offset + 1, (byte) (grad3[value & 0x0F][1] * 64 + 64)); // Gradient y pixels.put(offset + 2, (byte) (grad3[value & 0x0F][2] * 64 + 64)); // Gradient z pixels.put(offset + 3, (byte) value); // Permuted index } // GLFW texture loading functions won't work here - we need // GL.GL_NEAREST lookup. gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, 256, 256, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); }
/** * Creates a texture in the given OpenGL context. * * @param gl the context * @param image the RGB or RGBA image serving as texture source * @param repeat whether the texture should should have repeat mode activated * @return the texture name (ID) */ private static int createTexture(GL gl, BufferedImage image, boolean repeat) { if (image == null) { return -1; } final int[] tmp = new int[1]; gl.glGenTextures(1, tmp, 0); int tex = tmp[0]; gl.glBindTexture(GL_TEXTURE_2D, tex); int[] data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); ByteBuffer dest = ByteBuffer.allocate(data.length * BufferUtil.SIZEOF_INT); // TODO direct? dest.order(ByteOrder.nativeOrder()); dest.asIntBuffer().put(data, 0, data.length); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int wrapMode = (repeat) ? GL_REPEAT : GL_CLAMP_TO_EDGE; gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); int oglFormat = (image.getType() == BufferedImage.TYPE_INT_ARGB) ? GL_RGBA : GL_RGB; gl.glTexImage2D( GL_TEXTURE_2D, 0, oglFormat, image.getWidth(), image.getHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, dest); // (new GLU()).gluBuild2DMipmaps(GL.GL_TEXTURE_2D, GL.GL_RGB, image.getWidth(), // image.getHeight(), GL.GL_BGRA, // GL.GL_UNSIGNED_BYTE, dest); return tex; }
void texsel(int id) { if (id != sh.curtex) { HavenPanel.texmiss++; if (id == -1) { gl.glDisable(GL.GL_TEXTURE_2D); } else { gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, id); } sh.curtex = id; } else { HavenPanel.texhit++; } }
void LoadTextures(final GL gl) { // There is only one texture needed here--we'll set up a basic // checkerboard--which is used to modulate the diffuse channel in the // fragment shader. final int[] handle = new int[1]; gl.glGenTextures(1, handle, 0); // Basic OpenGL texture state setup gl.glBindTexture(GL.GL_TEXTURE_2D, handle[0]); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_GENERATE_MIPMAP_SGIS, GL.GL_TRUE); 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); // Fill in the texture map. final int RES = 512; final float[] data = new float[RES * RES * 4]; int dp = 0; for (int i = 0; i < RES; ++i) for (int j = 0; j < RES; ++j) { if ((i / 32 + j / 32) % 2 != 0) { data[dp++] = .7f; data[dp++] = .7f; data[dp++] = .7f; } else { data[dp++] = .1f; data[dp++] = .1f; data[dp++] = .1f; } data[dp++] = 1.0f; } gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, RES, RES, 0, GL.GL_RGBA, GL.GL_FLOAT, FloatBuffer.wrap(data)); // Tell Cg which texture handle should be associated with the sampler2D // parameter to the fragment shader. CgGL.cgGLSetTextureParameter( CgGL.cgGetNamedParameter(fragmentProgram, "diffuseMap"), handle[0]); }
public void setTexture(int unit, Texture tex) { if (unit != 0 || tex.getType() != Texture.Type.TwoDimensional) { // throw new UnsupportedOperationException(); return; } Image image = tex.getImage(); if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { updateTexImageData(image, tex.getType(), unit); } int texId = image.getId(); assert texId != -1; Image[] textures = context.boundTextures; int type = convertTextureType(tex.getType()); // if (!context.textureIndexList.moveToNew(unit)) { // if (context.boundTextureUnit != unit){ // gl.glActiveTexture(GL.GL_TEXTURE0 + unit); // context.boundTextureUnit = unit; // } // gl.glEnable(type); // } // if (context.boundTextureUnit != unit) { // gl.glActiveTexture(GL.GL_TEXTURE0 + unit); // context.boundTextureUnit = unit; // } if (textures[unit] != image) { GL gl = GLContext.getCurrentGL(); gl.glEnable(type); gl.glBindTexture(type, texId); textures[unit] = image; statistics.onTextureUse(image, true); } else { statistics.onTextureUse(image, false); } setupTextureParams(tex); }
public final void unbindTexture(GL gl) { gl.glBindTexture(GL.GL_TEXTURE_2D, 0); }
public final void bindTexture(GL gl) { gl.glBindTexture(GL.GL_TEXTURE_2D, textureId); }
/** * 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(); }
protected void drawIcon(DrawContext dc) { if (this.getIconFilePath() == null) return; GL gl = dc.getGL(); OGLStackHandler ogsh = new OGLStackHandler(); try { // Initialize texture if necessary Texture iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath()); if (iconTexture == null) { this.initializeTexture(dc); iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath()); if (iconTexture == null) { String msg = Logging.getMessage("generic.ImageReadFailed"); Logging.logger().finer(msg); return; } } gl.glDisable(GL.GL_DEPTH_TEST); double width = this.getScaledIconWidth(); double height = this.getScaledIconHeight(); // Load a parallel projection with xy dimensions (viewportWidth, viewportHeight) // into the GL projection matrix. java.awt.Rectangle viewport = dc.getView().getViewport(); ogsh.pushProjectionIdentity(gl); double maxwh = width > height ? width : height; gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh); // Translate and scale ogsh.pushModelviewIdentity(gl); double scale = this.computeScale(viewport); Vec4 locationSW = this.computeLocation(viewport, scale); gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z()); // Scale to 0..1 space gl.glScaled(scale, scale, 1); gl.glScaled(width, height, 1d); if (!dc.isPickingMode()) { gl.glEnable(GL.GL_BLEND); gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); // Draw background color behind the map gl.glColor4ub( (byte) this.backColor.getRed(), (byte) this.backColor.getGreen(), (byte) this.backColor.getBlue(), (byte) (this.backColor.getAlpha() * this.getOpacity())); dc.drawUnitQuad(); // Draw world map icon gl.glColor4d(1d, 1d, 1d, this.getOpacity()); gl.glEnable(GL.GL_TEXTURE_2D); iconTexture.bind(); TextureCoords texCoords = iconTexture.getImageTexCoords(); dc.drawUnitQuad(texCoords); gl.glBindTexture(GL.GL_TEXTURE_2D, 0); gl.glDisable(GL.GL_TEXTURE_2D); // Draw crosshair for current location gl.glLoadIdentity(); gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z()); // Scale to width x height space gl.glScaled(scale, scale, 1); // Set color float[] colorRGB = this.color.getRGBColorComponents(null); gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity()); // Draw crosshair Position groundPos = this.computeGroundPosition(dc, dc.getView()); if (groundPos != null) { int x = (int) (width * (groundPos.getLongitude().degrees + 180) / 360); int y = (int) (height * (groundPos.getLatitude().degrees + 90) / 180); int w = 10; // cross branch length // Draw gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3d(x - w, y, 0); gl.glVertex3d(x + w + 1, y, 0); gl.glEnd(); gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3d(x, y - w, 0); gl.glVertex3d(x, y + w + 1, 0); gl.glEnd(); } // Draw view footprint in map icon space if (this.showFootprint) { this.footPrintPositions = this.computeViewFootPrint(dc, 32); if (this.footPrintPositions != null) { gl.glBegin(GL.GL_LINE_STRIP); LatLon p1 = this.footPrintPositions.get(0); for (LatLon p2 : this.footPrintPositions) { int x = (int) (width * (p2.getLongitude().degrees + 180) / 360); int y = (int) (height * (p2.getLatitude().degrees + 90) / 180); // Draw if (LatLon.locationsCrossDateline(p1, p2)) { int y1 = (int) (height * (p1.getLatitude().degrees + 90) / 180); gl.glVertex3d(x < width / 2 ? width : 0, (y1 + y) / 2, 0); gl.glEnd(); gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3d(x < width / 2 ? 0 : width, (y1 + y) / 2, 0); } gl.glVertex3d(x, y, 0); p1 = p2; } gl.glEnd(); } } // Draw 1px border around and inside the map gl.glBegin(GL.GL_LINE_STRIP); gl.glVertex3d(0, 0, 0); gl.glVertex3d(width, 0, 0); gl.glVertex3d(width, height - 1, 0); gl.glVertex3d(0, height - 1, 0); gl.glVertex3d(0, 0, 0); gl.glEnd(); } else { // Picking this.pickSupport.clearPickList(); this.pickSupport.beginPicking(dc); // Where in the world are we picking ? Position pickPosition = computePickPosition( dc, locationSW, new Dimension((int) (width * scale), (int) (height * scale))); Color color = dc.getUniquePickColor(); int colorCode = color.getRGB(); this.pickSupport.addPickableObject(colorCode, this, pickPosition, false); gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()); dc.drawUnitQuad(); this.pickSupport.endPicking(dc); this.pickSupport.resolvePick(dc, dc.getPickPoint(), this); } } finally { dc.restoreDefaultDepthTesting(); dc.restoreDefaultCurrentColor(); if (dc.isPickingMode()) dc.restoreDefaultBlending(); ogsh.pop(gl); } }
public void updateTexImageData(Image img, Texture.Type type, int unit) { int texId = img.getId(); GL gl = GLContext.getCurrentGL(); if (texId == -1) { // create texture gl.glGenTextures(1, ib1); texId = ib1.get(0); img.setId(texId); objManager.registerObject(img); statistics.onNewTexture(); } // bind texture int target = convertTextureType(type); // if (context.boundTextureUnit != unit) { // glActiveTexture(GL_TEXTURE0 + unit); // context.boundTextureUnit = unit; // } if (context.boundTextures[unit] != img) { gl.glEnable(target); gl.glBindTexture(target, texId); context.boundTextures[unit] = img; statistics.onTextureUse(img, true); } // Check sizes if graphics card doesn't support NPOT if (!gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") && img.isNPOT()) { // Resize texture to Power-of-2 size MipMapGenerator.resizeToPowerOf2(img); } if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired()) { // No pregenerated mips available, // generate from base level if required // Check if hardware mips are supported if (gl.isExtensionAvailable("GL_VERSION_1_4")) { gl.glTexParameteri(target, GL2ES1.GL_GENERATE_MIPMAP, GL.GL_TRUE); } else { MipMapGenerator.generateMipMaps(img); } img.setMipmapsGenerated(true); } else { } if (img.getWidth() > maxTexSize || img.getHeight() > maxTexSize) { throw new RendererException( "Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize); } /* if (target == GL_TEXTURE_CUBE_MAP) { List<ByteBuffer> data = img.getData(); if (data.size() != 6) { logger.log(Level.WARNING, "Invalid texture: {0}\n" + "Cubemap textures must contain 6 data units.", img); return; } for (int i = 0; i < 6; i++) { TextureUtil.uploadTexture(img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, tdc); } } else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT) { List<ByteBuffer> data = img.getData(); // -1 index specifies prepare data for 2D Array TextureUtil.uploadTexture(img, target, -1, 0, tdc); for (int i = 0; i < data.size(); i++) { // upload each slice of 2D array in turn // this time with the appropriate index TextureUtil.uploadTexture(img, target, i, 0, tdc); } } else {*/ TextureUtil.uploadTexture(img, target, 0, 0, false); // } img.clearUpdateNeeded(); }
/** * 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); } } }
public void prerenderToTexture(GL gl) { int texSize = 256; final int[] tmp = new int[1]; gl.glGenTextures(1, tmp, 0); textureID = tmp[0]; gl.glBindTexture(GL_TEXTURE_2D, textureID); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl.glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_BGRA, GL_UNSIGNED_BYTE, null); final int[] fbo = new int[1]; gl.glGenFramebuffersEXT(1, IntBuffer.wrap(fbo)); gl.glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[0]); gl.glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureID, 0); gl.glDrawBuffers(1, IntBuffer.wrap(new int[] {GL_COLOR_ATTACHMENT0_EXT})); final int[] rba = new int[1]; gl.glGenRenderbuffersEXT(1, IntBuffer.wrap(rba)); gl.glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rba[0]); gl.glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texSize, texSize); gl.glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rba[0]); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glPushAttrib(GL_VIEWPORT_BIT); gl.glViewport(0, 0, texSize, texSize); gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glOrtho(0, texSize, 0, texSize, 0, 10); gl.glMatrixMode(GL.GL_MODELVIEW); Set<MapElement> map = State.getInstance().getMapInfo().queryElements(detailLevel, bounds, true); gl.glDisable(GL_TEXTURE_2D); gl.glColor3f(1, 1, 1); for (MapElement element : map) { if (element instanceof Street) { drawLine( gl, ((Street) element).getDrawingSize() / (float) Projection.getZoomFactor(detailLevel), ((Street) element).getNodes()); } } gl.glColor3f(0.3f, 0.3f, 0.3f); for (MapElement element : map) { if ((element instanceof Area) && (((Area) element).getWayInfo().isBuilding())) { gl.glBegin(GL_POLYGON); for (Node node : ((Area) element).getNodes()) { Coordinates pos = getLocalCoordinates(node.getPos()); gl.glVertex3f(pos.getLongitude(), pos.getLatitude(), 0f); } gl.glEnd(); } } gl.glEnable(GL_TEXTURE_2D); gl.glMatrixMode(GL.GL_PROJECTION); gl.glPopMatrix(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPopAttrib(); gl.glPopMatrix(); gl.glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); gl.glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); gl.glDeleteFramebuffersEXT(1, fbo, 0); gl.glDeleteRenderbuffersEXT(1, rba, 0); }