Super newbie problem. Will not render, tried with LWJGL 3 then tried LWJGL 2.

Started by majikchicken, March 11, 2016, 06:50:07

Previous topic - Next topic

majikchicken

I cannot figure it out.  I'm sure it's a problem with my GL initialization, but after scouring the API and tutorials, and giving up on using the glfw and switched to lwjgl 2.9.2, I *still* cannot get the program to plot simple points to the screen.

Here's my code, note that this is in LWJGL 2, as I thought maybe my issue was with LWJGL 3 (but I guess not).  I would prefer to use LWJGL 3...

main.java:
package nf.co.region9cis;

// lwjgl
import org.lwjgl.opengl.GL11;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.input.Keyboard;

// java/system
import java.nio.ByteBuffer;
import java.sql.ClientInfoStatus;
import java.util.Random;

// internal
import nf.co.region9cis.CLI; // Just logging and debug output, no GL
import nf.co.region9cis.BuildVersion; // No GL, just strings
import nf.co.region9cis.engine.Points; // Has some GL in Points.glDrawPoint(), will post below
import nf.co.region9cis.engine.Vector; // No GL, just math

// jansi
import org.fusesource.jansi.AnsiConsole; // Windows :/

public class Main implements Runnable{
	//private
	private Thread thread;
	private long window; // Left over from LWJGL 3
	private int windowWidth;
	private int windowHeight;
	private int windowDepth = 300;
	
	//Public
	public boolean isRunning = true;
	public static boolean isWindows = false;
	public static boolean isNix = false;
	
	public static void main(String args[]){
		CLI.println("Build version " + BuildVersion.is);
		// Determine if windows or not
		String operatingSystem = System.getProperty("os.name");
		
		if(operatingSystem.startsWith("Windows")){
			isWindows = true;
			CLI.println("Installing ANSI.SYS to process...");
			AnsiConsole.systemInstall();
			CLI.println("Booting on a Windows machine");
		}else{
			isNix = true;
			CLI.println("Booting on a non windows machine (Unix?)");
		}

		CLI.getDebugger().enableDebugging();
		//CLI.getDebugger().setDbgLevel(0);
		//CLI.getDebugger().setDbgLevel(1);
		
		CLI.println("Starting game thread...");
		CLI.getDebugger().print("Assigning new game = Main instance");
		Main game = new Main();
		
		CLI.getDebugger().print("Calling game.start()");
		game.start();
	}
	
	public void start(){
		CLI.println("Set thread running state to TRUE");
		this.isRunning = true;
		
		CLI.println("Making thread");
		this.thread = new Thread(this, "8CornerRoad");
		
		CLI.println("Executing thread");
		this.thread.start();
	}
	
	public void init(){
		try{
			CLI.println("Setting up OpenGL display...");
			
			this.windowHeight = 600; // test these out
			CLI.getDebugger().print("Set windowHeight = " + this.windowHeight);
			this.windowWidth = 900; // I hope this doesn't do weird stuff
			CLI.getDebugger().print("Set windowWidth = " + this.windowWidth);
			
			CLI.getDebugger().print("Setting display mode");
			Display.setDisplayMode(new DisplayMode(this.windowWidth, this.windowHeight));
			CLI.getDebugger().print("Setting location");
			Display.setLocation(400, 300);
			CLI.getDebugger().print("Creating window");
			Display.create();
			
		}catch(LWJGLException e){
			CLI.throwError("Caught LWJGLException in Main.init()");
			e.printStackTrace();
			this.rageQuit(1);
		}
		
		CLI.getDebugger().print("Calling initGL()");
		this.initGL();
	}
	
	public void update(){
		CLI.getDebugger().print0("Calling Display.update()");
		Display.update();
	}
	
	public void render(){
		CLI.getDebugger().print0("Calling glClear - render()");
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
	}
	
	public void run(){
		CLI.getDebugger().print("Calling this.init()");
		this.init();
		CLI.getDebugger().print("Called this.init()");
		
		/// TEST2
		CLI.getDebugger().print("Starting Test2");
		Points[] pArray = new Points[100];
		
		for(int x = 0; x < 100; x++){
			pArray[x] = new Points(this.randInt(0, this.windowWidth), this.randInt(0, this.windowHeight), this.randInt(0, this.windowDepth));
		}
		
		CLI.getDebugger().print("isRunning loop starts now");
		while(this.isRunning){
			if(Display.isCloseRequested()){
				this.isRunning = false;
			}
			
			this.update();
			this.render();
			
			if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
				this.isRunning = false;
			}else if(Keyboard.isKeyDown(Keyboard.KEY_D)){
				this.redrawScreen(pArray);
			}else if(Keyboard.isKeyDown(Keyboard.KEY_A)){
				for(int l = 0; l < pArray.length; l++){
					pArray[l].Scale(0.5, 0.5, 0.5);
				}
				this.redrawScreen(pArray);
			}else if(Keyboard.isKeyDown(Keyboard.KEY_S)){
				for(int l = 0; l < pArray.length; l++){
					pArray[l].Scale(2.0, 2.0, 2.0);
				}
				this.redrawScreen(pArray);
			}else if(Keyboard.isKeyDown(Keyboard.KEY_R)){
				Points origin = new Points(0,0,0);
				Vector tmpVector;
				
				for(int l = 0; l < pArray.length; l++){
					tmpVector = pArray[l].subtractPointFromPoint(origin);
					pArray[l] = origin;
					pArray[l].addVectorToPoint(tmpVector.rotateXY(15));
				}
				this.redrawScreen(pArray);
			}
		}
		
		this.rageQuit();
	}
	
	// Overload method
	public void rageQuit(){
		CLI.println("Cleaning up!!!");
		
		Display.destroy();
		
		CLI.getDebugger().print("Uninstalling ANSI.SYS if needed");
		if(isWindows){
			CLI.println("Uninstalling ANSI.SYS from process...");
			AnsiConsole.systemUninstall();
		}
		
		CLI.println("Exited gracefully.  Like a butterfly, like a butterfly.");
		System.exit(0);
	}
	
	public void rageQuit(int n){
		Integer status = new Integer(n);
		
		Display.destroy();
		
		if(status == 0){
			CLI.println("Cleaning up!!!");
			
			CLI.getDebugger().print("Uninstalling ANSI.SYS if needed");
			if(isWindows){
				CLI.println("Uninstalling ANSI.SYS from process...");
				AnsiConsole.systemUninstall();
			}
			
			CLI.println("Exited gracefully.  Like a butterfly, like a butterfly.");
			System.exit(n);
		}else{
			CLI.throwError("Uggghhh!! /ragequit");
			CLI.throwError("Disgracefully cleaning up.");
			
			CLI.getDebugger().print("Uninstalling ANSI.SYS if needed");
			if(isWindows){
				CLI.throwError("Uninstalling ANSI.SYS from process...");
				AnsiConsole.systemUninstall();
			}
			
			CLI.println("Exited disgracefully.  Like a plane crash..Or maybe a car crash?  An elephant sitting down? Whatever.");
			CLI.println("Exited with status code = " + n);
			System.exit(n);
		}
	}
	
	public int randInt(int min, int max){
		Random rand = new Random();
		
		int r = rand.nextInt((max - min) + 1) + min;
		
		return r;
	}
	
	public void redrawScreen(Points[] pArray){
		CLI.getDebugger().print0("Calling glClear - redrawScreen()");
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
		
		
		for(int i = 0; i < pArray.length; i++){
			CLI.getDebugger().print1("Calling .glDrawPoint - redrawScreen()");
			pArray[i].glDrawPoint();
			
			this.update();
		}
		
		CLI.getDebugger().print1("Done");
	}
	
	public void initGL(){
		GL11.glClearColor(0f, 0f, 0f, 0f);
		
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, this.windowWidth, this.windowHeight, 0, 0.01f, this.windowDepth);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
	}
}


The relevant, GL part of the points class is:
public class Public{
...
	public void glDrawPoint(){
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
		GL11.glBegin(GL11.GL_POINTS);
		{
			GL11.glColor3f(0.0f, 1.0f, 0.2f);
			GL11.glVertex3d(this.tuple[0], this.tuple[1], this.tuple[2]);
		}
		GL11.glEnd();
	}
}


I cannot get it to run.  Maybe if I can figure it out with LWJGL 2 then I will be able to figure out how to fix the issue with LWJGL 3.

Thanks!

Kai

First thing I'd do is completely erase any randomness out of this program.
Start to work with clearly set values. Like always printing the point (200, 200, 100).
Second thing: You are setting up the near plane to 0.01, however your point's 'z' ordinate can be 0.
So, the depth you are setting up for glOrtho should match the depth range of your points.
You can use 0 or even negative numbers for glOrtho if you like.
The default is -1 to +1.

majikchicken

I've replaced the point array with an array with 3 points, (1,1,1), (5,5,5), and (50,50,50).  I changed the 0.1f in ortho to a 0.


Still just a black window with a black background.

Kai

Well, the next obvious error is that you are clearing the screen every frame in render() but only drawing a point when you press some key. Try holding the 'D' key. The points should probably appear then.

majikchicken

I tried your suggestion, and then I tried commenting out the render call.  Neither seemed to work. How big will the point be?  Will they be too small to see?

Kai

Quote from: majikchicken on March 11, 2016, 21:01:39
How big will the point be?
Exactly one pixel.
So, if you have a retina display, probably quite invisible. :)

majikchicken

Quote from: Kai on March 11, 2016, 21:04:06
Quote from: majikchicken on March 11, 2016, 21:01:39
How big will the point be?
Exactly one pixel.
So, if you have a retina display, probably quite invisible. :)


Ah.  I changed the points into lines that should be about 20 pixels long and used glLineWidth(50), but still nothing.

Kai

Here is a reference. Uses LWJGL3, though. I really advise you to upgrade to LWJGL3, which you can download on lwjgl.org.
(your issue is however very likely not related to using LWJGL 2)
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.glfw.GLFWErrorCallback;
public class PointDemo {
    public static void main(String[] args) {
        GLFWErrorCallback errorCallback;
        glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
        if (glfwInit() != GLFW_TRUE)
            throw new IllegalStateException("Unable to initialize GLFW");
        glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
        long window = glfwCreateWindow(800, 600, "Hello Point!", NULL, NULL);
        if (window == NULL)
            throw new RuntimeException("Failed to create the GLFW window");
        glfwMakeContextCurrent(window);
        createCapabilities();
        glClearColor(0.2f, 0.4f, 0.6f, 1.0f);
        glPointSize(10.0f);
        while (glfwWindowShouldClose(window) == GLFW_FALSE) {
            glClear(GL_COLOR_BUFFER_BIT);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(0, 800, 0, 600, -1, 1);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glBegin(GL_POINTS);
            glVertex2f(400, 300);
            glEnd();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
        glfwDestroyWindow(window);
        glfwTerminate();
        errorCallback.free();
    }
}

majikchicken

Thanks.  I did find the problem.  My call to GL11.glVertex3d(x, y, z) was not being rendered...When I changed it to GL11.glVertex2d(x, y), it was rendered.  Anyone know why?

Among that issue, now I realize that inside the for loop that rotates points around the axis (lines 152-156 have not changed between the working and none working versions) the point value of each member of pArray is updated, but it seems to be setting ALL pArray members to the same value, even though I reference them one by one and they should not be the same.

To help visualize this:
for(int l = 0; l < pArray.length; l++){
					tmpVector = pArray[l].subtractPointFromPoint(origin);
					tmpVector.drawVector();
					pArray[l] = origin;
					pArray[l].addVectorToPoint(tmpVector.rotateXY(15));
					pArray[l].drawPoint0();
					CLI.getDebugger().print(""+l+"");
				}
				pArray[98].drawPoint0();
				pArray[99].drawPoint0();
				this.redrawScreen(pArray);


results in something similar to this:
....
[Core dbgger] <357.0944344680955, 302.085102140758, 52.0> // Vector from iteration 99
[Core dbgger] .drawPoint p = (692.6469245329588, 483.7444435801725, 52.0) // Calculated point from iteration 99 (value of pArray[98])
[Core dbgger] 98 // value of integer l
[Core dbgger] <-690.6469245329588, -330.7444435801728, -18.0> // Vector from iteration 100
[Core dbgger] .drawPoint p = (111.13618433984175, 13.763789130833686, 34.0) // Calculated point from iteration 100 (value of pArray[99])
[Core dbbger] 99 // value of integer l
[Core dbgger] .drawPoint p = (111.13618433984175, 13.763789130833686, 34.0) // Value of pArray[98] somehow has been set to pArray[99]
[Core dbgger] .drawPoint p = (111.13618433984175, 13.763789130833686, 34.0) // Value of pArray[99], the last value assigned in the for loop


What's going on?  Is there a memory leak with Java?

Edit: Nevermind.  I forgot that I had to declare the Points object "origin" inside the loop, same with tmpVector.  It works fine now except for getting smaller when rotated, and using glVertex3d doesn't draw.

Thanks everybody!

Kai

Using glVertex2* is _exactly_ the same as doing glVertex3*(.., .., 0), which in turn is exactly the same as glVertex4*(.., .., 0, 1)

So, the points seem to be culled, so the z-ordinate of your points are outside of the view frustum.
Either the z-ordinate of your points are wrong or your projection matrix.