Sign in to follow this  
mycerius

OpenGL gluSphere and texture issue

Recommended Posts

I have created a sphere using the gluSphere() method and added a texture (earth map) to it. The problem is that the texture is being displayed reversed. The code below uses code from Andrew Davison's new book (Pro Java 6 3D Game Development) as a basis. I ran his sample code (from chpt 16) and had the same issue. I have searched online in various places to try and find a solution but have not had any luck. I could switch to creating the sphere manually instead of using gluSphere(), but I would rather find a solution to this. Does anyone have any ideas or suggestions? I have not used OpenGL that much and may just be missing something important but not obvious. Thanks. Note: You can find the code for the book here
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.GLUT;
import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import javax.media.opengl.*;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;

public class SphereTest implements GLEventListener, MouseListener, MouseMotionListener
{
	private GL gl;
	private GLU glu;
	private GLUT glut;
	
	private Texture earthTex;
	
	private int prevMouseX, prevMouseY;
	private boolean mouseRButtonDown = false;
	private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
	private GLUquadric quadric;
	
	public void init(GLAutoDrawable drawable)
	{
		gl = drawable.getGL();
		glu = new GLU();
		glut = new GLUT();
		
		System.err.println("INIT GL IS: " + gl.getClass().getName());
		
		System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
		
		gl.setSwapInterval(1);
		
		float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
		
		gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos, 0);
		gl.glEnable(GL.GL_CULL_FACE);
		gl.glEnable(GL.GL_LIGHTING);
		gl.glEnable(GL.GL_LIGHT0);
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);	// Really Nice Perspective Calculations
		
		// create a textured quadric
		quadric = glu.gluNewQuadric();
		// creates texture coords
		glu.gluQuadricTexture(quadric, true);

		loadTextures();
		
		drawable.addMouseListener(this);
		drawable.addMouseMotionListener(this);
	}
	
	public void display(GLAutoDrawable drawable)
	{
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		
		gl.glPushMatrix();
		gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
		gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
		gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);

		drawSphere();
	}
	
	public void reshape(GLAutoDrawable drawable, int i, int i0, int i1, int i2)
	{
	}
	
	public void displayChanged(GLAutoDrawable drawable, boolean b, boolean b0)
	{
		// Not used by JOGL
	}
	
	public void mouseClicked(MouseEvent e)
	{
	}
	
	public void mousePressed(MouseEvent e)
	{
		prevMouseX = e.getX();
		prevMouseY = e.getY();
		if ((e.getModifiers() & e.BUTTON3_MASK) != 0)
		{
			mouseRButtonDown = true;
		}
	}
	
	public void mouseReleased(MouseEvent e)
	{
		if ((e.getModifiers() & e.BUTTON3_MASK) != 0)
		{
			mouseRButtonDown = false;
		}
	}
	
	public void mouseEntered(MouseEvent e)
	{
	}
	
	public void mouseExited(MouseEvent e)
	{
	}
	
	public void mouseDragged(MouseEvent e)
	{
		int x = e.getX();
		int y = e.getY();
		Dimension size = e.getComponent().getSize();
		
		float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width);
		float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height);
		
		prevMouseX = x;
		prevMouseY = y;
		
		view_rotx += thetaX;
		view_roty += thetaY;
	}
	
	public void mouseMoved(MouseEvent e)
	{
	}
	
	public static void main(String[] args)
	{
		Frame frame = new Frame("Sphere Test");
		GLCanvas canvas = new GLCanvas();
		
		canvas.addGLEventListener(new SphereTest());
		frame.add(canvas);
		frame.setSize(300, 300);
		final Animator animator = new Animator(canvas);
		frame.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				// Run this on another thread than the AWT event queue to
				// make sure the call to Animator.stop() completes before
				// exiting
				new Thread(new Runnable()
				{
					public void run()
					{
						animator.stop();
						System.exit(0);
					}
				}).start();
			}
		});
		frame.setVisible(true);
		animator.start();
	}
	
	private void drawSphere()
	{
		// enable texturing and choose the 'earth' texture
		gl.glEnable(GL.GL_TEXTURE_2D);
		earthTex.bind();
		
		// set how the sphere's surface responds to the light
		gl.glPushMatrix();
		float[] greyColor = {0.8f, 0.8f, 1.0f};
		gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, greyColor, 0);
		float[] whiteColor = {10.f, 1.0f, 1.0f};
		gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, whiteColor, 0);
		gl.glMateriali(GL.GL_FRONT, GL.GL_SHININESS, 100);
		
		// rotate the sphere to present 'upright'
		gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
		
		glu.gluSphere(quadric, 1.0f, 32, 32);
		
		gl.glPopMatrix();
		
		gl.glDisable(GL.GL_TEXTURE_2D);
	}
	
	private void loadTextures()
	{
		earthTex = loadTexture("earth.png");
	}
	
	private Texture loadTexture(String fn)
	{
		String fileName = "images/" + fn;
		Texture tex = null;
		
		try
		{
			tex = TextureIO.newTexture( new File(fileName), false);
			tex.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
			tex.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
		}
		catch (Exception e)
		{
			
		}
		return tex;
	}
}

Share this post


Link to post
Share on other sites
One way to fix this problem could be to just save the texture after flipping it about the axis. Although it's not a nice solution it should work

Share this post


Link to post
Share on other sites
I'm not going to read the code, but the problem could just be with how the view is set up. It's easy to get stuff flipped on the way from world to window space.

And for completeness, a cheap hack is to scale the sphere by -1 in the y direction or whatever (and make sure you don't cull the wrong faces as a result).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this