Outsmarted myself - JOGL instance variables in subclasses.

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Outsmarted myself - JOGL instance variables in subclasses.

LordSmoke
It seems I outsmarted myself. This is more a general Java question, but relevant to my current JOGL work...

I am creating a lineage of dialogs each implementing a single JOGL feature and inheriting the code from previous classes:

dialog01 draw white triangle on black background
dialog02 colored triangle on colored background
dialog03 animate rotation of triangle
dialog04 fix aspect ratio regardless of window shape
...

dialog04 extends dialog03 extends dialog02 extends dialog01 so that each dialog only contains more-or-less the code necessary to implement the new feature. Each dialog has its own vertex and fragment shader that extends those of the previous dialog.

This code is part of JavaDoc'ed and heavily commented code Java JOGL/OpenGL utility program I have been/am writing for my own use, but I am hoping it may serve as a useful "getting started" example.

Unfortunately, I just noticed (dialog04) that instanced variable values are shared in subclasses (1,2) - declare the background color in dialog01, change it in dialog04, and it changes for all open dialogs when they are redrawn.

I can hide this problem in my application by making the dialogs modal (won't be able to open any others), but is their a recommended solution for each subclass to have its own variable that is used by superclass methods?

I will want to change the geometry around dialog05 from a triangle to a cube, and expect I will run into this problem again with my vertexArray (dialog01), in addition to my bgColor and whatever else is lying around I have not tested.

(1) I can't believe I have not run into this problem before in all the 10s of thousands of lines and 100s of classes of Java code I have written. In thinking about it, I can see that I have never exploited the features of inheritance in my own code. I have written lots of unique java classes that only extend Java base classes and use their own variables internally.

(2) This also explains comments about not using an instanced glCanvas variable in response to and earlier question I posted. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Outsmarted myself - JOGL instance variables in subclasses.

gouessej
Administrator
Hi

I don't really understand your problem. The drawing code should be in the classes extending GLEventLister, shouldn't it?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Outsmarted myself - JOGL instance variables in subclasses.

LordSmoke
This post was updated on .
Right, but the GLEventlistener routines in subclasses call that of super classes.

dialog01
        declares bgColor
        display() {
        gl.glClearColor(bgColor.r, bgColor.g, bgColor.b, 1.0f);        
        gl.glClear(GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);
        ...
        }
dialog02 extends dialog01
        changes bgColor
        display() {
                super.display()
                new stuff...
        }
dialog03 extends dialog02
        sets its own bgColor
        display() {
                super.display()
                new stuff...
        }
       
Setting the background color in dialog03 changes the bgColor (upon repaint) for all open dialog02 dialogs and other dialog02 descendents since the bgColor is declared in dialog01. Hiding the bgColor in, say, dialog03 doesn't help since the method setting the background color is in dialog01, and that appears to use the original bgColor variable.

Classes at the same "level" at which the variable is declared get their own copies (multiple dialog01 dialogs could all have their own background colors), but subsequently developed subclasses all share the same copy.

This seems to be a general problem of superclass-instanced variables, which will probably bite me when I go to change the geometry from triangle to cube in a later subclass since vertexArray is declared in dialog01.

I have also found this to be an issue with registering the instanced glCanvas with the animator - only the last window is registered since current code uses the dialog01 glCanvas variable, which gets changed (I think) with each construction.

NOTE: I haven't included method arguments, e.g., GLAutoDrawable to display(), to simplify the shown structure.
Reply | Threaded
Open this post in threaded view
|

Re: Outsmarted myself - JOGL instance variables in subclasses.

LordSmoke
In reply to this post by LordSmoke
I think I have it figured out. Not as code-minimizing a solution as I would have liked, but seems to work and may be what is necessary given the inheritance issues.

Solution - uniquely variables have to be instanced in each subclass with associated overridden get/set functions. That way, superclass methods using these functions will get/set the local version in the subclass. Haven't checked to see if they have to be uniquely named, but...

dialog01:
    class JOGLColor {
        float r = 0;
        float g = 0;
        float b = 0;
        JOGLColor( float red, float green, float blue ) {
            r = red;
            g = green;
            b = blue;
        }
    };
    // Some colors I like.
    final JOGLColor WHITE = new JOGLColor( 1f, 1f, 1f );
...
        JOGLColor demo01BGColor = BLACK;
    JOGLColor getBGColor() {
      return demo01BGColor;  
    };
    void setBGColor(float red, float green, float blue, boolean doRepaint) {
        demo01BGColor.r = red;
        demo01BGColor.g = green;
        demo01BGColor.b = blue;
        // Allow for resetting of background color without repainting.
        if (doRepaint) {
            glCanvas.repaint();
        }
    }

dialog02:
    JOGLColor demo02BGColor = new JOGLColor(DARKRED.r, DARKRED.g, DARKRED.b);
    JOGLColor getBGColor() {
      return demo02BGColor;  
    };
    void setBGColor(float red, float green, float blue, boolean doRepaint) {
        demo02BGColor.r = red;
        demo02BGColor.g = green;
        demo02BGColor.b = blue;
        // Allow for resetting of background color without repainting.
        if (doRepaint) {
            glCanvas.repaint();
        }
    }
   
dialog03:
    JOGLColor demo03BGColor = new JOGLColor( DARKGREEN.r, DARKGREEN.g, DARKGREEN.b);
    JOGLColor getBGColor() {
      return demo03BGColor;  
    };
    void setBGColor(float red, float green, float blue, boolean doRepaint) {
        demo03BGColor.r = red;
        demo03BGColor.g = green;
        demo03BGColor.b = blue;
        // Allow for resetting of background color without repainting.
        if (doRepaint) {
            glCanvas.repaint();
        }
    }

Will have to do the same for glCanvas in above and a set of other variables, but will put everything between comment blocks to note this is a Java requirement and not anything JOGL/OpenGL specific.