Login  Register

Textures - program works on one machine, but not on another.

Posted by Ralph Martin on Feb 24, 2011; 10:19am
URL: https://forum.jogamp.org/Textures-program-works-on-one-machine-but-not-on-another-tp2566528.html

I've tried to port ToyShader ( see http://projects.autonomy.net.au/ai/browser/POC/OpenGL/TimLambertsToys/ToyShader.java?rev=) to JOGL2. It all seems to work except as follows:

- MacBook Pro - works perfectly
- Mac Pro        - textures displayed incorrectly

The main difference between these two is that the MacBook has an Nvidia graphics card, the Mac Pro has ATI. Otherwise,
- the exact same JOGL2 library files are used on each
- the exact same Netbeans project is used on each to compile and run

I'm reluctant to report this as a bug, as I may have done something wrong in my porting. I'd like someone to have a look at the code first, and see if there's an obvious mistake, before I report a bug. Also, the issue probably needs stripping down to essentials for a bug report.

Here's the code for the main class, which is the one dealing with textures.


package org.yourorghere;

/**
 * Toy plaything for me to learn JOGL/OpenGL
 * See effects of different OpneGL settings and shaders
 */

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.GL2;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.texture.*;
import java.io.*;
import java.nio.*;

public class ToyShader2 extends JFrame
        implements GLEventListener, KeyListener {

    ShapeManager shapeManager;
    FPSAnimator animator;
    trackball ball = new trackball();
    int aWidth = 1000;
    int aHeight = 1000;
    JCheckBoxMenuItem wireframe;
    JCheckBoxMenuItem specular;
    JCheckBoxMenuItem headLight;
    JCheckBoxMenuItem directionalLight;
    JCheckBoxMenuItem smooth;
    JCheckBoxMenuItem backFaceCull;
    JCheckBoxMenuItem zBuffer;
    JCheckBoxMenuItem twoSided;
    JCheckBoxMenuItem useShader;
    JCheckBoxMenuItem useTexture;
    JRadioButtonMenuItem[] levelItems, shaderItems, textureItems;
    //associates shader names with programs
    Map<String, Integer> programs = new HashMap<String, Integer>();
    String shader; //name of current shader
    static final String shaderDir = "shaders";
    //associates texture names with Textures
    Map<String, Texture> textures = new HashMap<String, Texture>();
    String texture; //name of current texture
    static final String textureDir = "textures";
    private float time = 0.0f; // keeps track of time -- passed to shaders
    private int timeLoc;  // location of time variable

    public static void main(String[] args) {
        ToyShader2 t = new ToyShader2();
        //exit if frame's close box is clicked
        t.addWindowListener(new WindowAdapter() {

            public void windowClosed(WindowEvent e) {
                System.exit(0);
            }

            public void windowClosing(WindowEvent e) {
                windowClosed(e);
            }
        });
    }
    int level;


    /* These functions are "callbacks" for events we are
    not interested in
     */
    public void keyTyped(KeyEvent evt) {
    }

    public void keyReleased(KeyEvent evt) {
    }

    public ToyShader2() {
        super("ToyShader");

        GLProfile glp = GLProfile.getDefault();
      // Specifies a set of OpenGL capabilities, based on your profile.
      GLCapabilities caps = new GLCapabilities(glp);
      GLCanvas glc = new GLCanvas(caps);

        add("Center", glc);
        glc.setSize(aWidth, aHeight);

        JPopupMenu.setDefaultLightWeightPopupEnabled(false); //so menus appear above GLCanvas

        JMenuBar menubar = new JMenuBar();
        setJMenuBar(menubar);

        shapeManager = new ShapeManager();
        menubar.add(shapeManager.getMenu());

        JMenu options = new JMenu("Options");
        menubar.add(options);
        wireframe = new JCheckBoxMenuItem("Wireframe");
        options.add(wireframe);
        headLight = new JCheckBoxMenuItem("Head Light");
        options.add(headLight);
        headLight.setSelected(true);
        directionalLight = new JCheckBoxMenuItem("Directional Light");
        options.add(directionalLight);
        specular = new JCheckBoxMenuItem("Specular Lighting");
        options.add(specular);
        twoSided = new JCheckBoxMenuItem("Two-sided Lighting");
        options.add(twoSided);
        backFaceCull = new JCheckBoxMenuItem("Back-face Cull");
        options.add(backFaceCull);
        zBuffer = new JCheckBoxMenuItem("Use Z Buffer");
        options.add(zBuffer);
        zBuffer.setSelected(true);
        smooth = new JCheckBoxMenuItem("Smooth Shading");
        options.add(smooth);
        useShader = new JCheckBoxMenuItem("Use Shader");
        options.add(useShader);
        useTexture = new JCheckBoxMenuItem("Use Texture");
        options.add(useTexture);

        JMenu levels = new JMenu("Level");
        ButtonGroup lbg = new ButtonGroup();
        levelItems = new JRadioButtonMenuItem[7];
        for (int i = 0; i < levelItems.length; i++) {
            levelItems[i] = new JRadioButtonMenuItem(i + "");
            levels.add(levelItems[i]);
            lbg.add(levelItems[i]);
            levelItems[i].addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    level = Integer.parseInt(e.getActionCommand());
                }
            });
        }
        level = 2;
        levelItems[level].setSelected(true);
        menubar.add(levels);

        String[] names = ShaderUtil.listShaders(shaderDir);
        JMenu shaders = new JMenu("Shader");
        ButtonGroup sbg = new ButtonGroup();
        shaderItems = new JRadioButtonMenuItem[names.length];
        if (names != null) {
            for (int i = 0; i < names.length; i++) {
                // strip off ".vert" suffix
                String thisname = names[i].substring(0, names[i].length() - 5);
                shaderItems[i] = new JRadioButtonMenuItem(thisname);
                shaders.add(shaderItems[i]);
                sbg.add(shaderItems[i]);
                shaderItems[i].addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        shader = e.getActionCommand();
                    }
                });
            }
        }
        shaderItems[0].setSelected(true);
        shader = shaderItems[0].getActionCommand();
        menubar.add(shaders);

        //texture menu -- we look for .png files in the texture directory.  
        File dir = new File(textureDir);
        names = dir.list(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                String lowname = name.toLowerCase();
                return lowname.endsWith(".png") || lowname.endsWith(".jpg");
            }
        });
        JMenu textures = new JMenu("Texture");
        ButtonGroup tbg = new ButtonGroup();
        textureItems = new JRadioButtonMenuItem[names.length];
        if (names != null) {
            for (int i = 0; i < names.length; i++) {
                textureItems[i] = new JRadioButtonMenuItem(names[i]);
                textures.add(textureItems[i]);
                tbg.add(textureItems[i]);
                textureItems[i].addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        texture = e.getActionCommand();
                    }
                });
            }
        }
        textureItems[0].setSelected(true);
        texture = textureItems[0].getActionCommand();
        menubar.add(textures);


        ball.listen(glc);
        glc.addGLEventListener(this);
        glc.addKeyListener(this);
        addKeyListener(this);
        animator = new FPSAnimator(glc, 100); //animate at 30 fps
        animator.start();
        pack(); //work out sizes of all Components
        setVisible(true);
    }

    public void init(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glClearColor(0.2f, 0.3f, 0.2f, 1.0f);

    }

    public void keyPressed(KeyEvent evt) {
        if (evt.getKeyChar() == 'q') {
            animator.stop();
            System.exit(0);
        }
        if (evt.getKeyChar() == 's') {
            specular.setSelected(!specular.isSelected()); //toggle
        }
        if (evt.getKeyChar() == 'r') {
            smooth.setSelected(!smooth.isSelected()); //toggle
        }
        if (evt.getKeyChar() == 'l') {
            twoSided.setSelected(!twoSided.isSelected()); //toggle
        }
        if (evt.getKeyChar() == '+' && level < levelItems.length - 1) {
            levelItems[++level].setSelected(true);
        }

        if (evt.getKeyChar() == '-' && level > 0) {
            levelItems[--level].setSelected(true);
        }

    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glViewport(x, y, width, height);
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(-2, 2, -2, 2, -5, 10);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glEnable(GL2.GL_AUTO_NORMAL);
        aWidth = width;
        aHeight = height;

    }

    public void display(GLAutoDrawable drawable) {
        float[] teapotMat = {0.6f, 0.6f, 0.6f, 1.0f};
        float[] teapotSpec = {0.8f, 0.8f, 0.8f, 1.0f};
        float[] zero = {0.0f, 0.0f, 0.0f, 1.0f};

        GL2 gl = drawable.getGL().getGL2();
        gl.glShadeModel(smooth.isSelected() ? GL2.GL_SMOOTH : GL2.GL_FLAT);
        gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, twoSided.isSelected() ? 1 : 0);

        if (zBuffer.isSelected()) {
            gl.glEnable(GL2.GL_DEPTH_TEST);
        } else {
            gl.glDisable(GL2.GL_DEPTH_TEST);
        }
        if (backFaceCull.isSelected()) {
            gl.glEnable(GL2.GL_CULL_FACE);
        } else {
            gl.glDisable(GL2.GL_CULL_FACE);
        }

        gl.glClear(GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_COLOR_BUFFER_BIT);
        // gl.glColor3f(1.0f, 1.0f, 1.0f);
        float[] hlightpos = {0.0f, 0.0f, 1.0f, 0.0f};
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, hlightpos, 0);
        gl.glEnable(GL2.GL_LIGHTING);
        if (headLight.isSelected()) {
            gl.glEnable(GL2.GL_LIGHT0);
        } else {
            gl.glDisable(GL2.GL_LIGHT0);
        }
        gl.glEnable(GL2.GL_NORMALIZE); //scale normals to have length 1

        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.0f, -5.0f);
        gl.glMultMatrixf(ball.getRotMatrix(), 0);
        float[] dlightpos = {1.0f, 1.0f, 1.0f, 0.0f};
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, dlightpos, 0);
        float[] dcolour = {0.6f, 0.6f, 0.6f, 0.0f};
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, dcolour, 0);
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_SPECULAR, dcolour, 0);
        if (directionalLight.isSelected()) {
            gl.glEnable(GL2.GL_LIGHT1);
        } else {
            gl.glDisable(GL2.GL_LIGHT1);
        }
        gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE, teapotMat, 0);
        if (specular.isSelected()) {
            gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, teapotSpec, 0);
            gl.glMateriali(GL2.GL_FRONT, GL2.GL_SHININESS, 80);
        } else {
            gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, zero, 0);
            gl.glMateriali(GL2.GL_FRONT, GL2.GL_SHININESS, 0);
        }
        if (wireframe.isSelected()) {
            gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
        } else {
            gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
        }


        if (useShader.isSelected()) {
            //use vertex and fragment shaders
            Integer programObject = programs.get(shader);
            if (programObject == null) { //need to load shaders into opengl
                int program = ShaderUtil.makeShaders(gl, shaderDir, shader);
                timeLoc = gl.glGetUniformLocation(program, "time");
                programObject = new Integer(program);
                programs.put(shader, programObject);
            }
            gl.glUseProgram(programObject.intValue());
            //tell shaders the time
            gl.glUniform1f(timeLoc, time);
            time += 1;
        } else {
            if (gl.isFunctionAvailable("glUseProgram")) {
                gl.glUseProgram(0);
            }
        }

        if (useTexture.isSelected()) {
            //apply specular lighting after texturing
            gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR);
            //enable texturing
            gl.glEnable(GL2.GL_TEXTURE_2D);
            Texture tex = textures.get(texture);
            if (tex == null) { //need to load texture
                tex = loadTexture(textureDir + File.separator + texture);
                textures.put(texture, tex);
            }
            tex.enable();
            gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_REPEAT);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_REPEAT);
            gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE,
                    GL2.GL_MODULATE);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER,
                    GL2.GL_LINEAR);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER,
                    GL2.GL_LINEAR_MIPMAP_LINEAR);
            tex.bind();
        } else {
            gl.glDisable(GL2.GL_TEXTURE_2D);
        }

        shapeManager.display(gl, level, wireframe.isSelected());

        gl.glPopMatrix();
    }

    /** This method handles things if display depth changes */
    public void displayChanged(GLAutoDrawable drawable,
            boolean modeChanged,
            boolean deviceChanged) {
    }

    public void dispose(GLAutoDrawable drawable) {
    }

    /** Load a texture from a file */
    Texture loadTexture(String filename) {
        Texture texture = null;

        try {
            texture = TextureIO.newTexture(new File(filename), true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (texture);
    }
}