How can I resize my circle in Java using OpenGL - java

How can I resize my circle shape in Java using OpenGL? I am very new to Java and OpenGL and I don't understand why my circle isn't being resized? I'm calling the function again with different parameters but for some reason my circle stays exactly the same and doesn't change, why is that?
I initially draw the circle calling drawCircle(..,..,..,..) in my display(..) function
You'll notice that when a key is pressed; 'a' , I want to increase the size of the circle
#Override
public void keyTyped(KeyEvent e)
{
// TODO Auto-generated method stub
char key= e.getKeyChar();
System.out.printf("Key typed: %c\n", key);
// Make shape bigger
// increase size of circle
if(key == 'a')
{
drawCircle(test, 10.0f, 10.0f, 10.0f);
}
// move right
if(key == 'f')
{
}
}
For some reason though it just doesn't even change my initial circle drawn whatsoever.
I have:
JoglEventListener.java
package helloOpenGL;
/*************************************************************************************
* IMPORTS
**************************************************************************************/
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import com.jogamp.opengl.*;
import com.jogamp.opengl.glu.GLU;
/*************************************************************************************
* JoglEventListener
**************************************************************************************/
public class JoglEventListener implements GLEventListener, KeyListener
{
float rot;
GL2 gl = null;
GLAutoDrawable test = null;
// Instantiate GLU thing?
private GLU glu = new GLU();
/*************************************************************************************
* displayChanged
* What does this do?
**************************************************************************************/
public void displayChanged(GLAutoDrawable gLDrawable,
boolean modeChanged, boolean deviceChanged)
{
// Function that does nothing?
}
/** Called by the drawable immediately after the OpenGL context is
* initialized for the first time. Can be used to perform one-time OpenGL
* initialization such as setup of lights and display lists.
* #param gLDrawable The GLAutoDrawable object.
*/
/*************************************************************************************
* init
**************************************************************************************/
public void init(GLAutoDrawable gLDrawable)
{
GL2 gl = gLDrawable.getGL().getGL2();
//gl.glShadeModel(GL.GL_LINE_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
// Really Nice Perspective Calculations
//gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
}
/*************************************************************************************
* reshape ?
* ?
**************************************************************************************/
public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width,
int height)
{
gl = gLDrawable.getGL().getGL2();
if (height <= 0) // avoid a divide by zero error!
height = 1;
final float h = (float) width / (float) height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, h, 1.0, 200.0);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -40.0f);
}
public void drawCircle(GLAutoDrawable gLDrawable, float x, float y, float radius)
{
GL2 gl = gLDrawable.getGL().getGL2();
int i;
test = gLDrawable;
//GLfloat radius = 0.8f; //radius
float twicePi = (float) (2.0f * Math.PI);
gl.glBegin(GL.GL_LINE_LOOP);
for(i = 0; i <= 360;i++)
{
gl.glVertex2f(
x + ((float)(radius * Math.cos(i * twicePi / 360))),
y + ((float)(radius* Math.sin(i * twicePi / 360)))
);
}
gl.glEnd();
}
#Override
public void display(GLAutoDrawable gLDrawable)
{
// TODO Auto-generated method stub
final GL2 gl = gLDrawable.getGL().getGL2();
gl.glClearColor(backrgb[0], 0, 1, 1);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
backrgb[0]+=0.0005;
if (backrgb[0]> 1) backrgb[0] = 0;
// DRAW STUFF IN THIS FUNCTION
drawCircle(gLDrawable, 5.0f, 5.0f, 3.0f);
}
#Override
public void dispose(GLAutoDrawable arg0)
{
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e)
{
// TODO Auto-generated method stub
char key= e.getKeyChar();
System.out.printf("Key typed: %c\n", key);
// Move Horizontally
// move left
if(key == 'a')
{
drawCircle(test, 10.0f, 10.0f, 10.0f);
}
// move right
if(key == 'f')
{
}
}
#Override
public void keyPressed(KeyEvent e)
{
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e)
{
// TODO Auto-generated method stub
}
}

You'll need to give the updated radius in the display function to get it drawn. Otherwise the image gets overwritten by it. So store the radius into a variable, for example under float rot; and don't draw when pressing 'a', only update the variable. Then in the display function use the variable:
drawCircle(gLDrawable, 5.0f, 5.0f, radius);

Related

how to Rotate only one object by using glrotate in java

I am trying to rotate only one square but it did not work it rotates all of them
in this code when I click N it creates a new square and pushes it in the array I want when I click R to
rotates specific square not all of them
when I search on google I found that glrotate move all the objects created after the calling and I did
know if it is right
package assignment;
import static org.lwjgl.opengl.GL11.*;
import java.util.ArrayList;
import java.util.Random;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
public class input {
private static final ArrayList<Square> shapes = new ArrayList<Square>();
private static boolean thingselected=false;
private static boolean flag=true;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Input Demo");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
glMatrixMode(GL_PROJECTION);
glOrtho(0, 640, 480, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
shapes.add(new Square(20,20));
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT);
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
Display.destroy();
System.exit(0);
}
while(Keyboard.next()) {
if(Keyboard.getEventKey()==Keyboard.KEY_N && Keyboard.getEventKeyState()) {
shapes.add(new Square(15,15));
}
}
for (final Square square:shapes) {
System.out.println(square.rotated);
if(Mouse.isButtonDown(0) && square.ismoved(Mouse.getX(),480-`Mouse.getY())&&!thingselected) {`
square.selected=true;
thingselected=true;
}
if(square.selected) {
square.update(Mouse.getDX(), -Mouse.getDY());
}
if(Mouse.isButtonDown(1) ) {
square.selected=false;
thingselected=false;
}
if(Keyboard.isKeyDown(Keyboard.KEY_C)&&square.ismoved(Mouse.getX(),480-Mouse.getY())&&!thingselected ) {
square.changeColor();
}
if(Keyboard.getEventKey() == Keyboard.KEY_R && square.ismoved(Mouse.getX(),480-Mouse.getY())){
if(flag)
square.rotated=true;
if(square.rotated)
{
square.rotate();
}
flag = false;
}
if(Keyboard.getEventKey() == Keyboard.KEY_T) {
square.transelate();
}
square.draw();
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
private static class Square{
public int x,y;
private float red,green,blue;
public boolean selected=false;
public boolean rotated=false;
Square(int x, int y){
this.x=x;
this.y=y;
Random random=new Random();
red=random.nextFloat();
green=random.nextFloat();
blue=random.nextFloat();
}
void draw() {
glColor3f(red, green, blue);
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x+50, y);
glVertex2f(x+50, y+50);
glVertex2f(x, y+50);
glEnd();
}
boolean ismoved(int mousex,int mousey) {
return mousex > x && mousex < x+50 && mousey > y && mousey < y+50;
}
void update(double dx,double dy) {
x+=dx;
y+=dy;
}
void changeColor() {
Random random=new Random();
red=random.nextFloat();
green=random.nextFloat();
blue=random.nextFloat();
}
void transelate() {
glTranslated(0.1, 0, 0);
}
void rotate() {
glRotated(0.1, 0, 0, 1);
}
}
glRotate and glTranslate manipulate the current matrix. You have to do the rotation and translation before drawing the object. Use glPushMatrix and glPopMatrix (see glPushMatrix / glPopMatrix) to save the current matrix on the matrix stack before changing it and to restore it after the object is drawn.
Add variables for the rotation and translation and change them in translate an roatate. Use the variables in draw:
private static class Square {
private double translateX, angleZ;
// [...]
void draw() {
glPushMatrix();
glTranslated(translateX, 0, 0);
glRotated(angleZ, 0, 0, 1);
glColor3f(red, green, blue);
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x+50, y);
glVertex2f(x+50, y+50);
glVertex2f(x, y+50);
glEnd();
glPopMatrix();
}
void transelate() {
translateX += 0.1;
}
void rotate() {
angleZ += 0.1;
}
}

Using user input radius to create a circle in JOGL

I want to take user input to get the radius value and use that to create a circle in java opengl (jogl). The radius variable name is rx. However, when i try to take the input in main(), the variable is not recognized anywhere else. I cannot take the input outside this function either. But when i manually assign a value to rx(radius), the code works fine. What should i do?
package rrassi2;
import java.awt.Frame;
import java.util.Scanner;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
public class ellipse implements GLEventListener{
/**
* #param args
*/
int pntX1 = 70, pntY1=50, ry=50;
private GLU glu;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner bucky = new Scanner(System.in);
int rx = bucky.nextInt();
bucky.close();
GLProfile glp = GLProfile.get(GLProfile.GL2);
GLCapabilities cap = new GLCapabilities(glp);
GLCanvas canvas = new GLCanvas(cap);
Frame frame = new Frame("Assignment1");
frame.setSize(1200, 800);
frame.add(canvas);
frame.setVisible(true);
ellipse l = new ellipse();
canvas.addGLEventListener(l);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
System.exit(0);
}});
}
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
gl.glClear (GL2.GL_COLOR_BUFFER_BIT);
//gl.glColor3f (0.0f, 0.0f, 0.0f);
gl.glPointSize(1.0f);
midPointCircleAlgo(gl);
gl.glFlush ();
}
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
public void init(GLAutoDrawable gld) {
// TODO Auto-generated method stub
GL2 gl = gld.getGL().getGL2();
glu = new GLU();
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glPointSize(4.0f);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void plot(GL2 gl,int x, int y)
{
gl.glBegin(GL2.GL_POINTS);
gl.glVertex2i(x+pntX1, y+pntY1);
gl.glEnd();
}
void midPointCircleAlgo(GL2 gl)
{
int x = 0;
int y = ry;
float decision = ry^2-rx^2*ry+((rx^2)/4);
plot(gl, x, y);
while(! ((2*(ry^2)*x )> (2*(rx^2)*y)))
{
if (decision < 0)
{
x++;
decision += (2*(ry^2)*x)+ry^2 ;
}
else
{
y--;
x++;
decision +=(2*(ry^2)*x)-(2*(ry^2)*y)+ry^2;
}
plot(gl,x, y);
plot(gl, -x, y);
plot (gl, x,-y);
plot (gl, -x, -y);
}
double decision2 = (((ry^2)*((x+0.5)*(x+0.5)))-((rx^2)*(ry^2))+((rx^2)*((y-1)^2)));
plot(gl, x, y);
while(y> 0)
{
if (decision2 > 0)
{
y--;
decision2 += -(2*(rx^2)*y)+rx^2 ;
}
else
{
y--;
x++;
decision2 +=(2*(ry^2)*x)-(2*(rx^2)*y)+rx^2;
}
plot(gl,x, y);
plot(gl, -x, y);
plot (gl, x,-y);
plot (gl, -x, -y);
}
}
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
}
Either create a static int rx above the main function
static int rx;
int pntX1 = 70, pntY1=50, ry=50;
private GLU glu;
public static void main(String[] args) {
// your code here
rx = bucky.nextInt();
// your code here
}
Or add a method to your class ellipse:
int pntX1 = 70, pntY1=50, ry=50;
int rx; // <-------------- Note this new line here
private GLU glu;
public static void main(String[] args) {
// your code here
ellipse l = new ellipse();
l.readRadius();
// your code here
}
public void readRadius() {
Scanner bucky = new Scanner(System.in);
this.rx = bucky.nextInt();
bucky.close();
}
Note the static keyword in
public static void main(String[] args)
In a static method you can only assign values to variables that also have the static keyword:
static int myAwesomeNumber;
int myOtherNumber;
static void myMethod() {
myAwesomeNumber = 123; // this works
myOtherNumber = 789 // this does not work
}
void myOtherMethod() {
myAwesomeNumber = 123; // this works
myOtherNumber = 789 // this works aswell because the method is not static
}

Java-Accessing value of parent class from child class

Hey I am trying to figure a confusion with accessing a variable's value from parent class in child class.
Scenario #1
Below is the code for the class DrawingPanel():
public class DrawingPanel extends JPanel implements MouseListener
{
private ArrayList<Balloon> balloons;
private Balloon activeBalloon;
private boolean picked;
private int offsetX, offsetY;
private double offsetR;
int rotate;
// Constructor:
public DrawingPanel()
{
setBackground(Color.WHITE);
addMouseListener(this);
balloons = new ArrayList<Balloon>();
activeBalloon = null;
picked = false;
rotate = 0;
}
// Called from controlPanel when the "Add balloon" button is clicked.
// Places a new balloon with a random radius and the current color
// at the center of the drawing panel.
public void addBalloon(int shape)
{
int w = getWidth();
int h = getHeight();
int radius = 10 + (int) (Math.random() * w / 2);
switch (shape)
{
case 1:
activeBalloon = new SquareBalloon(w / 2, h / 2, radius);
break;
default:
activeBalloon = new SquareBalloon(w / 2, h / 2, radius);
break;
}
balloons.add(activeBalloon);
repaint();
}
// Repaints this panel. If activeBalloon is set, paints it on top.
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for (Balloon b : balloons)
{
if (!picked || b != activeBalloon)
{
b.draw(g, true);
}
}
if (picked && activeBalloon != null)
activeBalloon.draw(g, false);
}
// Called when the mouse is clicked on the drawing panel.
// If inside a balloon, makes it "active", remembers the offsets
// of the click from the center.
// If on the border of a balloon, makes it "active", remembers the
// distance of the click from the center.
#Override
public void mousePressed(MouseEvent e)
{
// Value for parameter rotate is set here on mouse click
rotate = 2;
int x = e.getX();
int y = e.getY();
picked = false;
for (int k = balloons.size() - 1; k >= 0 && !picked; k--)
{
Balloon b = balloons.get(k);
if (b.isInside(x, y))
{
picked = true;
offsetX = x - b.getX();
offsetY = y - b.getY();
activeBalloon = b;
} else if (b.isOnBorder(x, y))
{
picked = true;
offsetR = b.distance(x, y) - b.getRadius();
activeBalloon = b;
}
}
if (picked)
repaint();
}
// "Drops" the picked balloon, if any.
#Override
public void mouseReleased(MouseEvent e)
{
}
// Not used:
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
#Override
public void mouseClicked(MouseEvent e)
{
}
}
Below is the SquareBalloon() class which inherits the parent class Balloon. The Balloon class inherits the DrawingPanel() class.
public class SquareBalloon extends Balloon implements MouseListener
{
public SquareBalloon()
{
}
/**
* Constructs a balloon with a given center, radius and color
*
* #param x
* x-coordinate of the center
* #param y
* y-coordinate of the center
* #param r
* radius of the balloon
*/
public SquareBalloon(int x, int y, int r)
{
super(x, y, r);
}
/**
* Draws a solid circle if makeItFilled is true and outline only if
* makeItFilled is false
*
* #param g
* graphics context
* #param makeItFilled
* draws a solid circle if true
*/
#Override
public void draw(Graphics g, boolean makeItFilled)
{
Graphics2D g2d = (Graphics2D) g;
g.setColor(color);
System.out.println("This is the value of rotate" + rotate + "from the draw() method of SquareBalloon() class.");
if (makeItFilled)
{
Rectangle rect2 = new Rectangle(xCenter - radius, yCenter - radius, radius, radius);
if (rotate == 2)
{
System.out.println("This is the value of rotate" + rotate
+ "from the makedItFilled if statement in draw() method of SquareBalloon() class.");
g2d.rotate(45 * (Math.PI / 180));
}
g2d.fill(rect2);
} else
{
Rectangle rect2 = new Rectangle(xCenter - radius, yCenter - radius, radius, radius);
if (rotate == 2)
{
System.out.println("This is the value of rotate" + rotate
+ "from the other if statement in draw() method of SquareBalloon() class.");
g2d.rotate(45 * (Math.PI / 180));
}
g2d.draw(rect2);
}
}
}
Scenario #2
Below is the code for the class DrawingPanel():
public class DrawingPanel extends JPanel implements MouseListener
{
private ArrayList<Balloon> balloons;
private Balloon activeBalloon;
private boolean picked;
private int offsetX, offsetY;
private double offsetR;
int rotate;
// Constructor:
public DrawingPanel()
{
setBackground(Color.WHITE);
addMouseListener(this);
balloons = new ArrayList<Balloon>();
activeBalloon = null;
picked = false;
rotate = 0;
}
// Called from controlPanel when the "Add balloon" button is clicked.
// Places a new balloon with a random radius and the current color
// at the center of the drawing panel.
public void addBalloon(int shape)
{
int w = getWidth();
int h = getHeight();
int radius = 10 + (int) (Math.random() * w / 2);
switch (shape)
{
case 1:
activeBalloon = new SquareBalloon(w / 2, h / 2, radius);
break;
default:
activeBalloon = new SquareBalloon(w / 2, h / 2, radius);
break;
}
balloons.add(activeBalloon);
repaint();
}
// Repaints this panel. If activeBalloon is set, paints it on top.
#Override
public void paintComponent(Graphics g)
{
// to restore original angle of balloon objects
if (rotate > 2)
rotate = 0;
super.paintComponent(g);
for (Balloon b : balloons)
{
if (!picked || b != activeBalloon)
{
b.draw(g, true, rotate);
}
}
if (picked && activeBalloon != null)
activeBalloon.draw(g, false, rotate);
}
// Called when the mouse is clicked on the drawing panel.
// If inside a balloon, makes it "active", remembers the offsets
// of the click from the center.
// If on the border of a balloon, makes it "active", remembers the
// distance of the click from the center.
#Override
public void mousePressed(MouseEvent e)
{
// Value for parameter rotate is set here on mouse click
rotate++;
int x = e.getX();
int y = e.getY();
picked = false;
for (int k = balloons.size() - 1; k >= 0 && !picked; k--)
{
Balloon b = balloons.get(k);
if (b.isInside(x, y))
{
picked = true;
offsetX = x - b.getX();
offsetY = y - b.getY();
activeBalloon = b;
} else if (b.isOnBorder(x, y))
{
picked = true;
offsetR = b.distance(x, y) - b.getRadius();
activeBalloon = b;
}
}
if (picked)
repaint();
}
// "Drops" the picked balloon, if any.
#Override
public void mouseReleased(MouseEvent e)
{
}
// Not used:
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
#Override
public void mouseClicked(MouseEvent e)
{
}
}
Below is the SquareBalloon() class which inherits the parent class Balloon. The Balloon class inherits the DrawingPanel() class.
public class SquareBalloon extends Balloon implements MouseListener
{
public SquareBalloon()
{
}
/**
* Constructs a balloon with a given center, radius and color
*
* #param x
* x-coordinate of the center
* #param y
* y-coordinate of the center
* #param r
* radius of the balloon
*/
public SquareBalloon(int x, int y, int r)
{
super(x, y, r);
}
/**
* Draws a solid circle if makeItFilled is true and outline only if
* makeItFilled is false
*
* #param g
* graphics context
* #param makeItFilled
* draws a solid circle if true
* #param rotate
* receives rotate variable value set in mousePressed() method of
* DrawingPanel() class
*/
#Override
public void draw(Graphics g, boolean makeItFilled, int rotate)
{
Graphics2D g2d = (Graphics2D) g;
g.setColor(color);
System.out.println("This is the value of rotate" + rotate + "from the draw() method of SquareBalloon() class.");
if (makeItFilled)
{
Rectangle rect2 = new Rectangle(xCenter - radius, yCenter - radius, radius, radius);
if (rotate == 2)
{
System.out.println("This is the value of rotate" + rotate
+ "from the makedItFilled if statement in draw() method of SquareBalloon() class.");
g2d.rotate(45 * (Math.PI / 180));
}
g2d.fill(rect2);
} else
{
Rectangle rect2 = new Rectangle(xCenter - radius, yCenter - radius, radius, radius);
if (rotate == 2)
{
System.out.println("This is the value of rotate" + rotate
+ "from the other if statement in draw() method of SquareBalloon() class.");
g2d.rotate(45 * (Math.PI / 180));
}
g2d.draw(rect2);
}
}
}
Can someone please explain why in Scenario #1, the change in value of variable int rotate after the mousePressed method initiates is not being passed to the subclasses of Balloon class so that the if statements with condition rotate == 2 in the draw method of class SquareBalloon executes? Because in Scenario #2 it does work.
Thank you!

How to make the camera move in the direction of the rotation?

How can I make the camera move in the direction of the rotation? How do I calculate the position of the camera to follow the rotation?
This is my code:
import javax.media.opengl.*;
import javax.media.opengl.awt.*;
import com.sun.opengl.util.*;
import com.sun.opengl.util.gl2.GLUT;
import javax.media.opengl.glu.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Rotation2 extends JFrame implements GLEventListener, KeyListener
{
GLCanvas canvas = null;
Animator an;
public Rotation2()
{
canvas=new GLCanvas();
an=new Animator(canvas);
add(canvas);
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
setSize(1280,900);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
an.start();
requestFocus();
}
float xPosition = 0;
float zPosition = 0;
float red = 0;
float green = 0;
float blue = 1;
public void init(GLAutoDrawable drawable)
{
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
double w = drawable.getWidth();
double h = drawable.getHeight();
double aspect = w/h;
glu.gluPerspective(60.0, aspect, 2.0, 20.0);
}
double zRot = 0;
double xRot = 0;
public void display(GLAutoDrawable drawable)
{
GL2 gl=drawable.getGL().getGL2();
GLU glu = new GLU();
GLUT glut = new GLUT();
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glClearColor(0f,0f,0f,0f);
//xPosition+=0.005;
//zPosition+=0.005;
gl.glRotated(zRot, 0, 1, 0);
gl.glRotated(xRot, 1, 0, 0);
glu.gluLookAt(xPosition, 0, zPosition,
xPosition, 0, (zPosition+20),
0, 1, 0);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT);
red = 0.0f;
green = 0.0f;
blue = 0.9f;
gl.glColor3f(red, green, blue);
//transforming the place the next shape
//will be drawn.
gl.glTranslated(2, 0, 2);
//We use wire here because default
//lighting is not good enough to
//use when rendering the solid version
glut.glutWireIcosahedron();
//more shapes to navigate through
gl.glTranslated(-4, 0, 0);
glut.glutWireIcosahedron();
red = 0.0f;
green = 0.9f;
blue = 0.1f;
gl.glColor3f(red, green, blue);
gl.glTranslated(4, 0, 4);
glut.glutWireIcosahedron();
gl.glTranslated(-4, 0, 0);
glut.glutWireIcosahedron();
red = 0.9f;
green = 0.0f;
blue = 0.1f;
gl.glColor3f(red, green, blue);
gl.glTranslated(4, 0, 4);
glut.glutWireIcosahedron();
gl.glTranslated(-4, 0, 0);
glut.glutWireIcosahedron();
red = 0.9f;
green = 0.0f;
blue = 0.9f;
gl.glColor3f(red, green, blue);
gl.glTranslated(4, 0, 4);
glut.glutWireIcosahedron();
gl.glTranslated(-4, 0, 0);
glut.glutWireIcosahedron();
}
public void reshape(GLAutoDrawable drawable,int x,int y,int width,int height)
{}
public void dispose(GLAutoDrawable drawable)
{}
public static void main(String[] ar)
{
new Rotation2();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
zPosition++;
}
else if (e.getKeyCode() == KeyEvent.VK_S) {
zPosition--;
}
else if(e.getKeyCode() == KeyEvent.VK_A) {
xPosition++;
}
else if (e.getKeyCode() == KeyEvent.VK_D) {
xPosition--;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
zRot+=5;
}
else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
zRot-=5;
}
else if (e.getKeyCode() == KeyEvent.VK_UP) {
xRot-=5;
}
else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
xRot+=5;
}
canvas.repaint();
}
#Override
public void keyReleased(KeyEvent e) {
}
}
p.s. You have to click the canvas for things to start working.
elect is right, you have to understand the basic concepts, you can't just tinker with no understanding of the notions on computer graphics. You can read the OpenGL Red Book, its code examples have been ported to JOGL and are available on Github here.
Those classes of my own first person shooter's very oldest alpha version show how to implement a camera except that you cannot look up or down:
GameGLView
GameController
GameModel
P.S: I have to update it soon to make it work with JOGL 2.3.2 and later. It works with JOGL 2.3.1.
P.P.S: I updated the source code above to make it work with JOGL 2.3.2 yesterday (February, 4th, 2016).

Large Line Strip management in JOGL / OPENGL...?

Im trying to make a Java screensaver of a 3D rotating Lorenz Attractor
Im using java and jogl (OPENGL) to render the graphics...
i have 2 classes one is the main program setup OPENGL etc...
and another that just stores a LinkedList of Point3d's That are the vertex of the line..
Only one new point is added to the List every frame render.....
The problem i am having is render speed is very slow, my question is this...
1. Is there a Better / Easy way of buffering either the screen or the line strip so i only need to draw the last line....
2. Can VBO's be used for LINE_STRIP's and if i have to add one vertex to the buffer every step is this really going to speed things up...?
Its really quite annoying... glBegin()/ glEnd() works fine up to about 100 lines then crashes badly.
Help much needed to speed up render and would be greatly apreaciated.....
Ive added the working code below to get it to work you have to link to JOGL opengl lib's
CODE
LorenzSim.java
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
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.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.vecmath.Point3d;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.*;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.gl2.GLUT;
import java.util.*;
import java.awt.event.*;
import sun.misc.*;
public class LorenzSim implements GLEventListener, KeyListener {
private static final int MIN_X = -20;
private static final int MAX_X = 20;
private static final int MIN_Y = -20;
private static final int MAX_Y = 20;
private static final double MIN_Z = 0;
private static final double MAX_Z = 40;
/**
* #param args
*/
// GLOBAL PARTS
boolean started = false;
int index = 0; // ANIMATOR COUNTER
String consoleLine = "";
// GENERAL OPEN GL
GLProfile glp = null;
GLCapabilities caps = null;
GLCanvas canvas = null;
GraphicsEnvironment ge = null;
GraphicsDevice gd = null;
Frame frame = null;
// GL _ CAM
double camX = 30;
double camY = 30;
double camZ = 50;
Lorenz myLorenz = null;
public LorenzSim ()
{
// GENERAL OPEN GL AND AWT SETUP
glp = GLProfile.getDefault();
caps = new GLCapabilities(glp);
canvas = new GLCanvas(caps);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
frame = new Frame("QuadSim");
frame.setSize(600,600);
//frame.setUndecorated(true);
//gd.setFullScreenWindow(frame);
frame.setVisible(true);
canvas.setSize(frame.getWidth(),frame.getHeight());
frame.add(canvas);
// SETUP EVENT LISTENERS
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
});
started = true;
FPSAnimator animator = new FPSAnimator(canvas, 60);
animator.add(canvas);
animator.start();
caps.setDoubleBuffered(true);
myLorenz = new Lorenz();
myLorenz.doSteps(0);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to Quad Simulator v0.1 - by Phil Poore");
LorenzSim mySim = new LorenzSim();
}
//############################################
// GL EVENT INTERFACE
//############################################
#Override
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
if (started)
{
update();
render(drawable);
//System.out.println("Drisplay_index:"+index);
}
}
private void update() {
// TODO Auto-generated method stub
index++;
myLorenz.step();
}
private void render(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
drawable.swapBuffers();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// START OF RENDER CYCLE
setCamera(gl,glu);
drawAxis(gl);
drawBox(gl);
drawLorenz(gl);
drawHUD(gl);
}
private void drawLorenz(GL2 gl) {
// TODO Auto-generated method stub
gl.glBegin(GL.GL_LINE_STRIP);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glLineWidth(0.1f);
for (int i = 0; i < myLorenz.myPoints.size() - 1; i++)
{
//float dx = (float) (myLorenz.myPoints.get(i).x - myLorenz.myPoints.get(i+1).x);
//float dy = (float) (myLorenz.myPoints.get(i).y - myLorenz.myPoints.get(i+1).y);
//float dz = (float) (myLorenz.myPoints.get(i).z - myLorenz.myPoints.get(i+1).z);
//float dc = (Math.abs(dx) + Math.abs(dy) + Math.abs(dz))/3.0f;
//gl.glColor3d(dc,dc,dc);
gl.glVertex3d(
myLorenz.myPoints.get(i).x,
myLorenz.myPoints.get(i).y,
myLorenz.myPoints.get(i).z);
}
gl.glEnd();
}
private void drawBox(GL2 gl) {
// TODO Auto-generated method stub
Point3d a = new Point3d(MIN_X,MIN_Y,MIN_Z);
Point3d b = new Point3d(MAX_X,MIN_Y,MIN_Z);
Point3d c = new Point3d(MAX_X,MAX_Y,MIN_Z);
Point3d d = new Point3d(MIN_X,MAX_Y,MIN_Z);
Point3d aa = new Point3d(MIN_X,MIN_Y,MAX_Z);
Point3d ab = new Point3d(MAX_X,MIN_Y,MAX_Z);
Point3d ac = new Point3d(MAX_X,MAX_Y,MAX_Z);
Point3d ad = new Point3d(MIN_X,MAX_Y,MAX_Z);
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(a.x, a.y, a.z);
gl.glEnd();
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glEnd();
}
private void drawHUD(GL2 gl) {
// TODO Auto-generated method stub
gl.glRasterPos2d(10,10);
gl.glWindowPos2d(10, 10);
gl.glColor3d(0.8, 0.8, 0.8);
GLUT glut = new GLUT();
//DecimalFormat df = new DecimalFormat("#.##");
glut.glutBitmapString(GLUT.BITMAP_8_BY_13,
":");
}
#Override
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
#Override
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
//gl.glOrtho(0,100,-5,25,0,100);
gl.glEnable( GL.GL_LINE_SMOOTH );
gl.glHint( GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST );
}
#Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
private void drawAxis(GL2 gl) {
gl.glLineWidth((float) 1.0);
gl.glBegin(GL.GL_LINES);
// X
gl.glColor3f(1, 0, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(1,0,0);
// Y
gl.glColor3f(0, 1, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,1,0);
// Z
gl.glColor3f(0, 0, 1);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,0,1);
gl.glEnd();
}
private void setCamera(GL2 gl,GLU glu)
{
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(120, 1.0, 5, 100);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(camX, camY, camZ,
0.0,0.0 ,0.0 ,
0.0,0.0, 1.0);
gl.glRotated(0.0+index, 0, 0, 1);
// gl.glTranslated(MAX_X-MIN_X, MAX_Y-MIN_Y, MAX_Z-MIN_Z);
}
//############################################
// KEY LISTENER INTERFACE
//############################################
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == 27)
System.exit(0);
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Lorenz.java
import javax.vecmath.*;
import java.awt.geom.;
import java.util.;
public class Lorenz {
public static final double rho = 28.0;
public static final double sigma = 10.0;
public static final double beta = 8.0/3.0;
private static final double step = 200.0;
public LinkedList<Point3d> myPoints = null;
public Lorenz ()
{
myPoints = new LinkedList<Point3d>();
Point3d first = new Point3d(0.1,0.1,0.1);
myPoints.add(first);
}
public void step()
{
System.out.println("stepping..."+myPoints.size());
Point3d last = myPoints.get(myPoints.size()-1);
double dx = (sigma * (last.y - last.x))/step;
double dy = ((last.x*(rho-last.z))-last.y)/step;
double dz = ((last.x*last.y - beta*last.z))/step;
Point3d next = new Point3d(last.x+dx,last.y+dy,last.z+dz);
myPoints.add(next);
}
public void doSteps(int count)
{
for (int i = 0; i < count; i++)
{
step();
}
}
public void dump()
{
System.out.println(myPoints.toString());
}
}
Phil
Try creating multiple VBOs for your set of lines. That way you only have to update a smaller number of vertices for each new line and the bulk of your geometry is already (probably) in video memory.
this may sound funny but try to remove the System.out.println() in the step() method. Printing to console is fairly slow/unpredictable in java so don't do this every frame.
to answer your question:
2) VBOs are fast for large(er) datasets and best used with rarely or partly updating data. They can represent any primitive you like, triangles, line strips etc. Adding one vertex every frame is not a good idea since they are allocated statically. You can still use them by predicting the maximum amount of vertices you would like to render and simply allocate this buffer a-priory.
if you decide to use VBOs you will have to make this changes:
- allocate a VBO which will determine the max amount of vertices of the graph
- upload only the new vertices per frame
- stop at max or think about a ringbuffer, but you will probably need an additional buffer used as indexbuffer to implement this
tipp: use JOGL's debug pipeline, it will try to throw an exception as soon as OpenGL sets an error code. This will may help to fix the crash issue you mentioned.
http://michael-bien.com/mbien/entry/jogl_2_composeable_pipline

Categories