I recevie 0 errors but I get this in the console:
>Exception in thread "main" java.lang.NullPointerException
>>at org.lwjgl.opengl.GL11.glMatrixMode(GL11.java:2052)
>>>at game.engine.GameLoop.start(GameLoop.java:22)
>>>>at game.engine.GameLoop.main(GameLoop.java:15)
I tried to put the actual value into "glMatrixMode()" instead of "GL11.GL_PROJECTION" but it returns same Exception.
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Display;
public class GameLoop
{
//Main
public static void main(String[] argv)
{
GameLoop.start();
}
//Metodo che gestisce il loop
public static void start()
{
//Inizializzazione OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 600, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
try
{
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e)
{
e.printStackTrace();
System.exit(0);
}
while(!Display.isCloseRequested())
{
Entità.pulisci();
Entità.colora();
Entità.disegna();
Display.update();
}
}
}
import org.lwjgl.opengl.GL11;
public class Entità
{
//Disegna un poligono
public static void disegna()
{
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(100,100);
GL11.glVertex2f(200,100);
GL11.glVertex2f(200,200);
GL11.glVertex2f(100,200);
GL11.glEnd();
}
//Pulisce il buffer
public static void pulisci()
{
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}
//Setta il colore al poligono
public static void colora()
{
GL11.glColor3f(0.5f,0.5f,1.0f);
}
}
I don't have any experience with Java or LWJGL, but from looking at your code it seems
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
creates the actual display canvas (or however you may call it) which also sets up the OpenGL context. Thus calling any OpenGL function (like GL11.glMatrixMode) before those is likely to result in some error, as in your case a null pointer exception.
So try to put those four functions after the display creation. You are making changes to the OpenGL context, thus you first need a valid context.
Related
https://github.com/terryaa/KOSTA_MAC/tree/master/Java/NetBeans/day13_01_15/src/ex1
What I'm trying to do is to draw circles, but one circle on a canvas at a time and then moving on to drawing next circle using Runnable join. It should draw a circle using .start() and the other .start() shouldn't start until formal .start()'s drawing circle is done.
In linked page's package, Ex3_Canvas1 class has main and use Runnable MyThread0 class to draw a circle using basic .start() and .join() and it does perfectly what I want.
I created NetBean's automatic JFrame class Ex2_CanvasDemo and tried to do the same and failed. JFrame window pops up after drawing a full circle and then shows creating of next circle. What I want is that the window should first appear and it shows creation of both circles ,not simulataneously but sequently, like Ex3_Canvas1.
I guess it's because main thread waits for th(Ex2_CanvasDemo) to finish so window doesn't apply for changes. But shouldn't Ex1_Canvas1 should do the same? Is this differences due to automatically generated code by netbeans? How can I do the same as Ex1_Canvas1 in Ex2_CanvasDemo.
I tried making a Runnable class and used in Ex2_CanvasDemo but failed also..
Any help?
I'm using jdk 8 and netbeans8 on mac.
--Thread part of Ex2_CanvasDemo--
public Ex2_CanvasDemo() {
initComponents();
Thread th=new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<370;i+=10){
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Ex2_CanvasDemo.class.getName()).log(Level.SEVERE, null, ex);
}
arcNUm=i;
System.out.println("circle"+arcNUm);
canvas1.repaint();
}
}
});
th.start();
try {
th.join();
} catch (InterruptedException ex) {
Logger.getLogger(Ex2_CanvasDemo.class.getName()).log(Level.SEVERE, null, ex);
}
th=new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<370;i+=10){
System.out.println("circle"+i);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Ex2_CanvasDemo.class.getName()).log(Level.SEVERE, null, ex);
}
arcNum2=i;
canvas2.repaint();
}
}
});
th.start();
// try {
// th.join();
// } catch (InterruptedException ex) {
// Logger.getLogger(Ex2_CanvasDemo.class.getName()).log(Level.SEVERE, null, ex);
// }
}
Caveat
Animation is hard, good animation is really hard. You need to repeat this to yourself, because animation done right is, really hard.
What you need to know...
Animation is basically the illusion of change over time. Very rarely do you want to perform linear animation, animation is normally done over a period of time, as it allows for performance difference in the platform to be smoothed out in away which is not as harsh to the user.
Swing is single threaded and not thread safe. This means that you should not block the event dispatching thread and that you must only update the UI from within the context of the event dispatching thread.
See Concurrency in Swing for more details
This makes life a little difficult, as you can't simply run a linear loop in the EDT, as this will block the UI and it's difficult to do it from a Thread because it's a mess of synchronisation.
One of the simplest solutions is to make use of the available API and use a Swing Timer, which acts as a pseudo loop, putting in a small delay between call backs, in which you can perform some operations
Example...
While there are a number of ways you might approach this, I've set up a simple List which contains a bunch of Animatables which "do stuff" and then simply run one after the other in serial.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
TestPane testPane = new TestPane();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(testPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
testPane.play();
}
});
}
});
}
public class TestPane extends JPanel {
private List<Animatable> animations;
private Animatable animation;
private Timer timer;
public TestPane() {
animations = new ArrayList<>(25);
animations.add(new CircleAnimation(Color.RED));
animations.add(new CircleAnimation(Color.BLUE));
timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (animation == null) {
animation = animations.remove(0);
}
if (animation.update(getBounds())) {
if (animations.isEmpty()) {
((Timer)e.getSource()).stop();
} else {
animation = animations.remove(0);
}
}
repaint();
}
});
}
public void play() {
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (animation != null) {
Graphics2D g2d = (Graphics2D) g.create();
animation.paint(g2d);
g2d.dispose();
}
}
}
public interface Animatable {
public boolean update(Rectangle bounds);
public void paint(Graphics2D g2d);
}
public class CircleAnimation implements Animatable {
private Color color;
private Ellipse2D circle;
private double delta = -1;
public CircleAnimation(Color color) {
this.color = color;
}
#Override
public boolean update(Rectangle bounds) {
if (circle == null) {
circle = new Ellipse2D.Double(bounds.width, (bounds.height / 2) - 10, 20, 20);
}
Rectangle rect = circle.getBounds();
rect.x += delta;
circle.setFrame(rect);
return rect.x + 20 < bounds.x;
}
#Override
public void paint(Graphics2D g2d) {
if (circle == null) {
return;
}
g2d.setColor(color);
g2d.fill(circle);
}
}
}
I drew a white triangle in the screen(WIDTH=800,HEIGHT=600). I got the white screen sized triangle, working perfectly fine with OpenGl version 4.2.0 - Build 10.18.10.3496 (current version)
but when I switched to 3.3.0 - Build 10.18.10.3496
I got nothing but black blank screen. When I again went for 4.2.0, everything is just working fine.
I have no idea what's going on?
public abstract class Window {
public static void createNormalVersion(int width,int height,String title){
try {
Display.setDisplayMode(new DisplayMode(width, height));
Display.setTitle(title);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
}
public static void createSpecifiedVersion
(int width,int height,String title,int firstVer,int secondVer){
try{
PixelFormat pixel=new PixelFormat();
ContextAttribs context=new ContextAttribs(firstVer,secondVer)
.withForwardCompatible(true)
.withProfileCore(true);
Display.setDisplayMode(new DisplayMode(width,height));
Display.setTitle(title);
Display.create(pixel,context);
}catch(LWJGLException e){
e.printStackTrace();
}
}
// I choose the version from main method
public static void main(String[] args) {
Window.createSpecifiedVersion(WIDTH, HEIGHT, TITLE, 3, 3);
MainComponent game = new MainComponent();
game.start();
}
I am running this simple code to display a window in eclipse using lwjgl:
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
#SuppressWarnings("unused")
public class DisplayExample {
public void start() {
try {
Display.setDisplayMode(new DisplayMode(1920, 1080));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// init OpenGL here
while (!Display.isCloseRequested()) {
// render OpenGL here
Display.update(); //flushes OpenGL pipeline and swaps back and front buffers. perhaps waits for v-sync.
}
Display.destroy();
}
public static void main(String[] argv) {
DisplayExample displayExample = new DisplayExample();
displayExample.start();
}
}
However the screen appears like this and is flickering:
http://tinypic.com/r/33upp2u/6
This is running on a mac, any ideas what is going wrong?
You aren't clearing the screen before you update the display. Add GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); before // render OpenGL here. You also need to import the org.lwjgl.opengl.GL11 class for this.
This is an extremely simple question, but I have no idea what to do.
package typeandscreen;
imports
public class DisplayWindow {
Font f = new Font();
void run(){
try {
Display.setDisplayMode(new DisplayMode(1000,560));
Display.setTitle("Test for Bitmaps / Letters");
Display.create();
} catch(LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
while(!Display.isCloseRequested()){
Graphics g;
What do I make Graphics g equal? I just want to draw the subImage f.letters[0] onto the screen, but I don't know what I'm supposed to put there.
Making the lower line Graphics.drawImage(etc) doesn't work, and leaving it how it is, is a null pointer exception. If I do "Graphics g = f.letters[0].getGraphics()" for the above line then it's also a null pointer exception.
g.drawImage(f.letters[0],0,0,null);
Display.update();
}
Display.destroy();
}
public static void main(String args[]){
DisplayWindow dw = new DisplayWindow();
dw.run();
}
}
My ultimate goal is to be able to make use of additional mouse buttons in Java. Currently, LWJGL's JInput doesn't seem capable of detecting more than three buttons. To make use of Java's System.setProperty("sun.awt.enableExtraMouseButtons", "true"), I've tried mounting the Display onto an AWT Canvas, within a JFrame. Unfortunately, this does not appear to work, and I am unsure why. [I should note that I've been away from Java for a some time]
import java.awt.Canvas;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class MainCanvas extends Canvas implements MouseListener
{
private static final long serialVersionUID = 1L;
public void mouseClicked(MouseEvent e)
{
System.out.println(e.getButton());
}
public void mouseEntered(MouseEvent e)
{
System.out.println(e.getButton());
}
public void mouseExited(MouseEvent e)
{
System.out.println(e.getButton());
}
public void mousePressed(MouseEvent e)
{
System.out.println(e.getButton());
}
public void mouseReleased(MouseEvent e)
{
System.out.println(e.getButton());
}
public void init()
{
}
public static void main(String[] args)
{
MainCanvas mainCanvas = new MainCanvas();
JFrame mainFrame = new JFrame("Simplify");
mainFrame.setSize(640, 480);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.getContentPane().add(mainCanvas);
mainFrame.setVisible(true);
mainCanvas.addMouseListener(mainCanvas);
try
{
DisplayMode mainDisplay = new DisplayMode(640, 480);
Display.setDisplayMode(mainDisplay);
Display.setParent(mainCanvas);
Display.create();
}
catch (LWJGLException le)
{
System.out.println("Oh dear.");
}
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 640, 480, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while (!Display.isCloseRequested())
{
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glColor3f(0.5f,0.5f,1.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(100,100);
GL11.glVertex2f(100+200,100);
GL11.glVertex2f(100+200,100+200);
GL11.glVertex2f(100,100+200);
GL11.glEnd();
Display.update();
}
Display.destroy();
}
}
I spoke with the fellows in the FreeNode IRC some months back. The gist is because the canvas is a heavyweight component, events would not rise to the JFrame level. A Frame has to be used in its stead.
Basically, the answer is you can't: i.e with lwjgl 2.8.2 on Windows only.
The reason is that the Windows implementation of lwjgl clobbers a key data structure that AWT requires for event handling.
http://www.java-gaming.org/topics/cannot-add-mouselistener-to-java-awt-canvas-with-lwjgl-on-windows/24650/msg/208505/view.html#msg208505
Try adding the mouse listener to the JFRame instead. I ran into this before, and I think that's how I solved it.