How to change the color of the cylinder when double clicked it

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

How to change the color of the cylinder when double clicked it

Irene Tang
Hi, I wrote a demo to change the color of the cylinder when double clicked it. But it disappeared when I did that. First time of running the demo, the cylinder was drawn, and I outputted the modelview and projection matrix, which were
[1.0, 0.0, 0.0, 0.0, 0.0, 0.9848077, 0.17364818, 0.0, 0.0, -0.17364818, 0.9848077, 0.0, 0.0, -8.0, -40.0, 1.0]
and
[1.2268693, 0.0, 0.0, 0.0, 0.0, 1.7320509, 0.0, 0.0, 0.0, 0.0, -1.020202, -1.0, 0.0, 0.0, -2.020202, 0.0]. Then I double clicked it, it disappeared. But the the modelview and projection matrix were the same as above.

Here is the code:
import static com.jogamp.opengl.fixedfunc.GLMatrixFunc.GL_MODELVIEW;
import static com.jogamp.opengl.fixedfunc.GLMatrixFunc.GL_PROJECTION;

import java.nio.IntBuffer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLDrawableFactory;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.gl2.GLUT;


public class DrawCylinder {
        private static int currentX, currentY;
        private static float cameraDistance = 40.0f, cameraAngleX = 10.0f, cameraAngleY = 0.0f;
       
        private static final int UPDATE = 1, SELECT = 2;
        private static int cmd = UPDATE;
        public static void main(String[] args) {
                final Display display = new Display();
                Shell shell = new Shell(display);
                shell.setLayout(new FillLayout());
                Composite comp = new Composite(shell, SWT.NONE);
                comp.setLayout(new FillLayout());
                GLData data = new GLData();
                data.doubleBuffer = true;
                final GLCanvas canvas = new GLCanvas(comp, SWT.NONE, data);

                canvas.setCurrent();
                GLProfile glprofile = GLProfile.getDefault();
                final GLContext context = GLDrawableFactory.getFactory(glprofile).createExternalGLContext();

                canvas.addControlListener(new ControlAdapter() {
                        @Override
                        public void controlResized(ControlEvent e) {
                                Rectangle rect = canvas.getClientArea();
                                canvas.setCurrent();
                                context.makeCurrent();
                                reshape(context.getGL().getGL2(), rect.width, rect.height);
                                context.release();
                        }
                });

                context.makeCurrent();
                init(context.getGL().getGL2());
                context.release();
                canvas.addPaintListener(new PaintListener() {

                        @Override
                        public void paintControl(PaintEvent e) {
                                canvas.setCurrent();
                                context.makeCurrent();
                                display(context.getGL().getGL2());
                                canvas.swapBuffers();
                                context.release();
                        }
                });
               
                canvas.addMouseListener(new MouseListener() {
                        @Override
                        public void mouseDoubleClick(MouseEvent e) {
                                if(e.button == 1) {
                                        cmd = SELECT;
                                        updateMousePosition(e.x, e.y);
                                        canvas.redraw();
                                }
                        }

                        @Override
                        public void mouseDown(MouseEvent e) {

                        }

                        @Override
                        public void mouseUp(MouseEvent e) {

                        }
            });

                shell.setText("SWT/Cylinder Example");
                shell.setSize(640, 480);
                shell.open();

                while (!shell.isDisposed()) {
                        if (!display.readAndDispatch())
                                display.sleep();
                }
                display.dispose();
        }

        static void reshape(GL2 gl2, int width, int height) {
                System.out.println("reshape...");
                if (height == 0) {
                        height = 1;
                }

                gl2.glViewport(0, 0, width, height);
               
                GLU glu = new GLU();
                gl2.glMatrixMode(GL_PROJECTION);
                gl2.glLoadIdentity();
                glu.gluPerspective(60.0f, (float) width / (float) height, 1.0f, 100.0f);
                gl2.glMatrixMode(GL_MODELVIEW);
                gl2.glTranslatef(0, -8, -cameraDistance);
                gl2.glRotatef(cameraAngleX, 1, 0, 0);
                gl2.glRotatef(cameraAngleY, 0, 1, 0);
        }

        static void init(GL2 gl2) {
                System.out.println("init...");
                gl2.glShadeModel(GL2.GL_SMOOTH);
                gl2.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                gl2.glClearDepth(1.0f);
                gl2.glEnable(GL2.GL_DEPTH_TEST);
                gl2.glDepthFunc(GL2.GL_LEQUAL);
                gl2.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
        }

        static void display(GL2 gl2) {
                float[] m = new float[16];
                System.out.println("display...");
                switch (cmd) {
                case UPDATE:
                        System.out.println(cmd);
                        gl2.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, m, 0);
                        gl2.glGetFloatv(GL2.GL_PROJECTION_MATRIX, m, 0);
                        drawCylinder(gl2, 2, 6, 6, 2, 12, 4, 1);
                        break;
                case SELECT:
                        System.out.println(cmd);
                        GLU glu = new GLU();
                       
                        int buffsize = 512;
                        double x = (double) currentX, y = (double) currentY;
                        int[] viewPort = new int[4];
                        IntBuffer selectBuffer = Buffers.newDirectIntBuffer(buffsize);
                        int hits = 0;
                        gl2.glGetIntegerv(GL2.GL_VIEWPORT, viewPort, 0);
                        gl2.glSelectBuffer(buffsize, selectBuffer);
                        gl2.glRenderMode(GL2.GL_SELECT);
                        gl2.glInitNames();
                        gl2.glMatrixMode(GL2.GL_PROJECTION);
                        gl2.glPushMatrix();
                        gl2.glLoadIdentity();
                        glu.gluPickMatrix(x, (double) viewPort[3] - y, 5.0d, 5.0d, viewPort, 0);
                        glu.gluPerspective(60.0f, (float) viewPort[2] / (float) viewPort[3], 1.0f, 100.0f);
                       
                        gl2.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, m, 0);
                        gl2.glGetFloatv(GL2.GL_PROJECTION_MATRIX, m, 0);
                        drawCylinder(gl2, 2, 6, 6, 2, 12, 4, 1);
                        gl2.glMatrixMode(GL2.GL_PROJECTION);
                        gl2.glPopMatrix();
                        gl2.glFlush();
                        hits = gl2.glRenderMode(GL2.GL_RENDER);
                        System.out.println(hits);
                        processHits(hits, selectBuffer);
                        cmd = UPDATE;
                       
                        gl2.glColor3f(1.0f, 0.0f, 0.0f);
                        display(gl2);
                        break;
                }
        }
       
        private static void processHits(int hits, IntBuffer buffer) {
                System.out.println("---------------------------------");
                System.out.println(" HITS: " + hits);
                int offset = 0;
                int names;
                float z1, z2;
                for (int i = 0; i < hits; i++) {
                        System.out.println("- - - - - - - - - - - -");
                        System.out.println(" hit: " + (i + 1));
                        names = buffer.get(offset);
                        offset++;
                        z1 = (float) (buffer.get(offset) & 0xffffffffL) / 0x7fffffff;
                        offset++;
                        z2 = (float) (buffer.get(offset) & 0xffffffffL) / 0x7fffffff;
                        offset++;
                        System.out.println(" number of names: " + names);
                        System.out.println(" z1: " + z1);
                        System.out.println(" z2: " + z2);
                        System.out.println(" names: ");

                        for (int j = 0; j < names; j++) {
                                System.out.print("       " + buffer.get(offset));
                                if (j == (names - 1))
                                        System.out.println("<-");
                                else
                                        System.out.println();
                                offset++;
                        }
                        System.out.println("- - - - - - - - - - - -");
                }
                System.out.println("---------------------------------");
               
        }

        static void updateMousePosition(int x, int y) {
                currentX = x;
                currentY = y;
        }
       
        static void drawCylinder(GL2 gl2, float x1, float y1, float z1, float x2, float y2, float z2, int id) {
               
                System.out.println("draw cylinder...");
                gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
               
            float dx = x2 - x1;  
            float dy = y2 - y1;  
            float dz = z2 - z1;  
           
            float  distance = (float)Math.sqrt(dx*dx + dy*dy + dz*dz);  
           
            float  px = x1;  
            float  py = y1;  
            float  pz = z1;  
           
            float  bx = px;    
            float  by = py;
            float  bz = distance + pz;  
           
            float  sx = bx - x1;  
            float  sy = by - y1;  
            float  sz = bz - z1;  
           
            float fx = sy * dz - dy * sz;  
            float fy = sz * dx - sx * dz;  
            float fz = sx * dy - dx * sy;  
           
            float ax = x2 - bx;  
            float ay = y2 - by;  
            float az = z2 - bz;  
            float length = (float)Math.sqrt(ax * ax + ay * ay + az * az);  
           
            float angle = (float)(Math.acos((distance*distance*2 - length*length)/(2*distance*distance))*180.0f / Math.PI);  
            GLUT glut = new GLUT();
           
            gl2.glPushName(id);
            gl2.glPushMatrix();  
            gl2.glTranslatef(x1, y1, z1);  
            gl2.glRotatef(angle, fx, fy, fz);    
            glut.glutSolidCylinder(0.5, distance, 32, 32);
            gl2.glPopMatrix();  
        }
       
}
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
PS, the variable hits always equals 0. WHY
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
You shouldn't use deprecated OpenGL, Irene

is there a specific reason why you are using that?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
No. I have no idea about what is out of date in opengl. I searched online and found that way, so I tried. So, do you have any other ideas that can accomplish that result?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
What is your hardware? GPU and Operating System?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
Win7, GPU info
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
Unfortunately Intel is a little cryptic, I'd need something more...

click on the start menù, and then right click on "Computer", you should have something similar, which is the CPU?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
Cool, you should have OpenGL 4 based on the Intel reference

Just update your drivers , the current is 15.40 and you have 10.80..

then try this small Hello Triangle

Once you get it running, you can use it as a template base and modify it to render your cylinder and whatever you want more :)
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
I ran HelloTriangle and encountered this problem com.jogamp.opengl.GLException: Method "glCreateBuffers" not available. I haven't updated my driver yet. Is it because of this? Actually, I am not sure about the updating driver thing. I am learning OpenGL to use it during my work. Is it appropriate to ask my client to update their driver?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
The current driver may not offer you access to GL4 and so on, step back to GL3 then, use this one.

You don't have to update, you can learn and use GL3, which is still totally fine.

Let me know if it runs.
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

gouessej
Administrator
In reply to this post by Irene Tang
Some customers might refuse to update their drivers because they have to respect their own policies but using obsolete drivers expose them to bugs. Moreover, if they use the default Microsoft GDI driver, they will be able to use only OpenGL 1.1 and this driver is known to be semi-broken, it's a nightmare.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
In reply to this post by elect
I've been trying to access github but failed because it has been forbidden for a long time in our country. I can only check util I get to the company.
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
can you access this?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
No, not even at company. I can access github now. And there is a problem. Where did you define gl_Position in hello-triangle.frag. I've got this Shader status invalid: ERROR: 0:21: 'gl_Position' : undeclared identifier
ERROR: 0:21: 'assign' :  cannot convert from '4-component vector of float' to 'float'
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
In the hello-triangle.frag there is no gl_Position, if you meant hello-triangle.vert are you sure you didn't modify it? Because it looks fine, there was an error with the glsl '#version', it was 400, I fixed it and changed it to 330. But it shouldn't have had nothing to do with your problem.

/*
 * Vertex shader.
 */
#version 330

// Incoming vertex position, Model Space.
in vec2 position;
// Incoming vertex color.
in vec3 color;

// Uniform matrix from Model Space to Clip Space.
uniform mat4 modelToClipMatrix;

// Outgoing color.
out vec3 interpolatedColor;

void main() {

    // Normally gl_Position is in Clip Space and we calculate it by multiplying
    // it with the modelToClipMatrix.
    gl_Position = modelToClipMatrix * vec4(position, 0, 1);

    // We assign the color to the outgoing variable.
    interpolatedColor = color;
}

On line 21, we take position, which is a vec2, set to a vec4 by padding it with 0, 1 and the multiply the mat4 modelToClipMatrix with it. A mat4 * vec4 multiplication returns a vec4.

Can you paste me here your shader?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
It runs successfully now. Thanks a lot.
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
Brava :)

Now change the geometry to render the cylinder, if you need help, paste code here and let's discuss it
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

Irene Tang
I've got a problem with your hello-triangle demo in line wrote an annotation "Ibo is part of the VAO...", what's it mean?
Reply | Threaded
Open this post in threaded view
|

Re: How to change the color of the cylinder when double clicked it

elect
In the init, after we generated one VAO, we have to set it up. This means we have to set the vertex layout (through glVertexAttribPointer) and the element/index buffer object (IBO) if we render indexed geometry. That is, while the VAO is bound we bind the corresponding IBO.

In the rendering then, we don't have to set up again any vertex layout or bind again the IBO, we will just need to bind the VAO, like here, and it will automatically restore all the parameters we set inside it.