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
}
Related
I am designing a picture lab project for school and I can't figure out how to modify the rgb of pixels. My project is an eye test game where players choose the one color that is different from the rest. Should I modify the pixels of the background or of a blank photo? Also, how do I implement mouseClickedAction (given method that runs when mouse is clicked)?
Here's some bare stuff I have so far:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.ImageObserver;
import java.util.ArrayList;
public class EagleEye extends FlexiblePictureExplorer {
public static Picture background = new Picture(1003,1003);
//settings
private int gameDimensions = 4;
private int difficulty = 30;
private final int statsHeight = 80;
public EagleEye(DigitalPicture Picture) {
super(background);
setTitle("Eagle Eye");
int xGrid = gameDimensions;
int yGrid = gameDimensions;
int r1 = (int)(Math.random() * gameDimensions + 1);
int r2 = (int)(Math.random() * gameDimensions + 1);
colorSetter(xGrid,yGrid);
}
private void colorSetter(int x,int y) {
for (int i=0;i<x;i++) {
for (int j=0;j<y;j++) {
fillBox(i,j);
}
}
}
private void fillBox(int x, int y) {
int r = (int)(Math.random() * 255 + 1);
int g = (int)(Math.random() * 255 + 1);
int b = (int)(Math.random() * 255 + 1);
int x1;
int x2;
if (x==0) {
x1 = 0;
x2 = 250;
}
else if (x==1) {
x1 = 252;
x2 = 501;
}
else if (x==2) {
x1 = 503;
x2 = 752;
}
else {
x1 = 754;
x2 = 1003;
}
int y1;
int y2;
if (y==0) {
y1 = 0;
y2 = 250;
}
else if (y==1) {
y1 = 252;
y2 = 501;
}
else if (y==2) {
y1 = 503;
y2 = 752;
}
else {
y1 = 754;
y2 = 1003;
}
int rgb = calculateColors(r,g,b);
for (int i=x1;i<=x2;i++) {
for (int j=y1;j<=y2;j++) {
background.setBasicPixel(x1,y1,rgb);
}
}
setImage(background);
}
private int calculateColors(int r, int g, int b) {
int r1 = r * 65536;
int g1 = g * 256;
int b1 = b;
return r1 + g1 + b1;
}
private void drawStats(Picture img){
Picture statsImg = new Picture(statsHeight, imageWidth);
Graphics g = statsImg.getGraphics();
g.setFont(new Font("Times New Roman", Font.PLAIN, 16));
g.setColor(Color.blue);
}
private void updateImage() {
}
public void mouseClickedAction(DigitalPicture pict, Pixel pix) {
}
private void endGame() {
}
public boolean imageUpdate(Image arg0, int arg1, int arg2, int arg3, int arg4, int arg5) {
// TODO Auto-generated method stub
return false;
}
public static void main(String[] args) {
Picture white = new Picture(100,100);
EagleEye game = new EagleEye(white);
}
}
I think the easiest way that you will find for drawing and graphics will not be drawing to an image, but instead drawing directly to the JPanel. If you have a class that extends JPanel, you can implement
public void paintComponent(Graphics g) {
//Code to draw whatever you like, e.g.
g.setColor(new Color(255, 255, 255));
g.drawRect(0, 0, width, height);
}
With this, you will not have to worry about handling images,
If you would still like to use images, you can use the BufferedImage, which has great docs explaining how to use it:
https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
(You will still need to display these images, most likely using the paintComponent method above anyways, and if you want to draw in a loop, you will have to put that loop on another thread, be aware)
As for the mouseClicked, you will need to implement a MouseListener, which is quite simple:
Create a MouseListener object in your class, you will have to implement a number of methods inside it, most of which will likely go unused.
Somewhere in your code (probably the constructor) you will need to add the MouseListener to whatever component you want to wait for the clicks (probably the panel you are drawing on)
When that component is clicked on, the mouseClicked method will be called and from there you can do whatever you need to, like calling the other methods you have there to handle mouse clicks.
The MouseEvent object in the listener has all the useful information yu will need, like it's position (relative to the component you added the listener to)
public class YourClass {
public YourClass() {
this.addMouseListener(ml);
}
//code
private MouseListener ml = new MouseListener() {
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println(arg0.getX() + ", " + arg0.getY());
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
}
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);
I'm a beginner in learning this.Doing a test by drawing a triangle and now I want to move it.it's not working so I want to ask what's my mistake.Sorry it's long.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
public class Test extends JFrame {
private Triangle triangle;
private final int step = 10;
private Triangle keyboardPanel = new Triangle();
public static void main(String[] args)
{
Test t = new Test();
}
public Test()
{
setTitle("TRY TRY TRY");
setLocationRelativeTo(null); // Center the frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 500, 500);
JPanel tripanel = new JPanel();
add(tripanel);
triangle = new Triangle();
tripanel.addKeyListener(null);
tripanel.addMouseListener(null);
tripanel.addMouseMotionListener(null);
setVisible(true);
}
static class move extends JPanel implements KeyListener,MouseListener, MouseMotionListener{
private int x = 210;
private int y = 210;
private Color color = Color.BLACK;
move()
{
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void keyPressed(KeyEvent ke) {
int KeyCode = ke.getKeyCode();
System.out.println("key code is" +KeyCode);
/*switch (KeyCode)
{
case KeyEvent.VK_UP:
triangle.moveTriangle(-10, 0);
break;
case KeyEvent.VK_DOWN:
triangle.moveTriangle(10, 0);
break;
case KeyEvent.VK_LEFT:
triangle.moveTriangle(0, -10);
break;
case KeyEvent.VK_RIGHT:
triangle.moveTriangle(0, 10);
break;
}
repaint();*/
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("hello");
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
System.out.println("hello123");
if(e.isControlDown())
color = Color.RED;
else
color = Color.BLACK;
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println(e.getPoint());
}
}
public void paint(Graphics g)
{
super.paint(g);
triangle.drawTriangle(g);
}
public void paintComponent(Graphics g)
{
super.paintComponents(g);
triangle.drawTriangle(g);
}
}
import java.awt.Graphics;
import javax.swing.JPanel;
public class Triangle {
private Point p1;
private Point p2;
private Point p3;
int numX;
int numY;
public Triangle()
{
p1 = new Point(200,200);
p2 = new Point(170,230);
p3 = new Point(230,230);
}
public void moveTriangle(int dx, int dy)
{
p1.move(dx, dy);
p2.move(dx, dy);
p3.move(dx, dy);
}
public void drawTriangle(Graphics g)
{
g.drawLine(p1.getX(), p1.getY(),p2.getX(),p2.getY());
g.drawLine(p2.getX(),p2.getY(),p3.getX(),p3.getY());
g.drawLine(p3.getX(), p3.getY(),p1.getX(),p1.getY());
}
}
public class Point {
private int x;
private int y;
public Point(int X, int Y)
{
x = X;
y = Y;
}
public void setX(int X)
{
x = X;
}
public void setY(int Y)
{
x = Y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void move(int dx, int dy)
{
x +=dx;
y +=dy;
}
public String toString()
{
return("X = "+x+" Y= "+y);
}
}
there are lot of problems in your code .when you coding always test current code before go further.
you create a panel and add to the jframe .
JPanel tripanel = new JPanel();
add(tripanel);
but your graphical mechanism has written in move panel so you need to make a move panel instead of jpanel.
keylistners has added to panel but keylisners not get triggered because keylistners work when component is focused . it works for component like jtextfiled . but not for panels .you have to use keybinding .i have added keybind for rightarrow key ..you have to add it to other keys up ,down etc..
also move your paint method from jframe to move jpanel .
example code (run this code and press right arrow ->)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test extends JFrame {
private Triangle triangle;
private final int step = 10;
private Triangle keyboardPanel = new Triangle();
public static void main(String[] args) {
Test t = new Test();
}
public Test() {
setTitle("TRY TRY TRY");
setLocationRelativeTo(null); // Center the frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 500, 500);
JPanel tripanel = new move();
add(tripanel);
triangle = new Triangle();
setVisible(true);
}
class move extends JPanel implements MouseListener, MouseMotionListener {
private int x = 210;
private int y = 210;
private Color color = Color.BLACK;
move() {
addMouseListener(move.this);
addMouseMotionListener(move.this);
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "moveright");
this.getActionMap().put("moveright", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
triangle.moveTriangle(10, 0);
repaint();
}
});
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("hello");
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
System.out.println("hello123");
if (e.isControlDown()) {
color = Color.RED;
} else {
color = Color.BLACK;
}
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
//System.out.println(e.getPoint());
}
#Override
public void paint(Graphics g) {
super.paint(g);
triangle.drawTriangle(g);
}
}
class Triangle {
private Point p1;
private Point p2;
private Point p3;
int numX;
int numY;
public Triangle() {
p1 = new Point(200, 200);
p2 = new Point(170, 230);
p3 = new Point(230, 230);
}
public void moveTriangle(int dx, int dy) {
p1.move(dx, dy);
p2.move(dx, dy);
p3.move(dx, dy);
}
public void drawTriangle(Graphics g) {
g.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
g.drawLine(p2.getX(), p2.getY(), p3.getX(), p3.getY());
g.drawLine(p3.getX(), p3.getY(), p1.getX(), p1.getY());
}
}
class Point {
private int x;
private int y;
public Point(int X, int Y) {
x = X;
y = Y;
}
public void setX(int X) {
x = X;
}
public void setY(int Y) {
x = Y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void move(int dx, int dy) {
x += dx;
y += dy;
}
public String toString() {
return ("X = " + x + " Y= " + y);
}
}
}
output >>
I have code to draw a pie chart with value and random colors. Now I would like to rotate the entire figure, not one piece of pie. Here is my code:
class Slice{
double value;
Color color;
public Slice(double _value){
this.value = _value;
}
public void setColor(Color _color){
this.color = _color;
}
}
class Component extends JComponent implements MouseListener{
int movx = 0;
int movy = 0;
Slice[] slice = {new Slice(5),new Slice(20),new Slice(33),new Slice(55)};
public Component(){
addMouseListener(this);
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
drawPie(g2, getBounds(), slice);
}
public void drawPie(Graphics2D g, Rectangle area, Slice[] s){
double total = 0.0D;
//calculate total value
for(int i=0;i<s.length;i++)
total+=s[i].value;
double curentValue = 0.0D;
int startAngle = 0;
for(int i = 0;i<s.length;i++){
Random numGen = new Random();
s[i].setColor(new Color(numGen.nextInt(256), numGen.nextInt(256), numGen.nextInt(256)));
startAngle = (int)((curentValue*360)/total);
int arcAngle = (int)((s[i].value*360)/total) ;
g.setColor(s[i].color);
g.rotate(30);//row AA
g.fillArc(area.x, area.y, area.width, area.height, startAngle, arcAngle);
curentValue+=s[i].value;
}
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
movx = e.getX();
movy = e.getY();
repaint();
}
// unimplemented Mouse methods removed
}
public class PieChart {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame frame = new JFrame();
frame.getContentPane().add(new Component());
frame.setSize(300,200);
frame.setVisible(true);
}
}
In row AA when I write rotate, it cannot work normally? Can you help me? How can I rotate the entire chart?
The argument of Graphics2D.rotate is in radians.
http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#rotate%28double%29
http://en.wikipedia.org/wiki/Radian#Conversion_between_radians_and_degrees
If you want to rotate the whole chart, you should put the rotate code at the beginning of the drawPie method, not in the for loop.
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