I have this code that I understand now:
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class Main {
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// init OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 0, 800);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while (!Display.isCloseRequested()) {
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// set the color of the quad (R,G,B,A)
GL11.glColor3f(1.0f,1.0f,1.0f);
// draw quad
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();
}
public static void main(String[] argv) {
Main quadExample = new Main();
quadExample.start();
}
}
I want to know how to draw the box so that it is not drawn on the screen, but setback a bit, how?
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex3f(100,100,-100);
GL11.glVertex3f(100+200,100,-100);
GL11.glVertex3f(100+200,100+200,-100);
GL11.glVertex3f(100,100+200,-100);
GL11.glEnd();
Though that won't make any visual difference with a single quad in ortho. You'll have to switch to a perspective projection matrix for it to look like it's "moved back".
Related
This is my drawRect code:
public static void drawRect(float X, float Y, float WIDTH, float HEIGHT, float RED, float GREEN, float BLUE)
{
// clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// set the color of the quad (R,G,B,A)
GL11.glColor3f(RED, GREEN, BLUE);
// draw quad
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(X,Y);
GL11.glVertex2f(X+WIDTH,Y);
GL11.glVertex2f(X+WIDTH,Y+HEIGHT);
GL11.glVertex2f(X,Y+HEIGHT);
GL11.glEnd();
}
This is what i'm doing
Renderer.drawRect(0, 0, Display.getWidth(), Display.getHeight(), 255, 255, 255);
It fills the entire screen (like it should) but the color is always black.
I suggested reading tutorials because glColor3f() expects 3 floats in the 0...1 range for color components, just like most accelerated graphics API-s. And if this one slipped, there may be confusion about other details too. But nevertheless, 255 would be still clamped to 1, so the routine does not draw a black rectangle, something is missing before (in the setup) and/or after (like a call making the drawing actually appear on screen).
LWJGL wiki has a complete example code for exactly what you are trying to do, by the way: http://wiki.lwjgl.org/wiki/LWJGL_Basics_3_(The_Quad).html
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class QuadExample {
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// init OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while (!Display.isCloseRequested()) {
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// set the color of the quad (R,G,B,A)
GL11.glColor3f(0.5f,0.5f,1.0f);
// draw quad
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();
}
public static void main(String[] argv) {
QuadExample quadExample = new QuadExample();
quadExample.start();
}
}
in LWJGL I add text to my Display. When done, the program drops to about 1-2FPS. I have capped it with Display.sync(60);
Without text, it runs fine. With, absolutely... terrible?
Here is the source for my text:
import java.awt.Font;
import java.io.InputStream;
import org.newdawn.slick.Color;
import org.newdawn.slick.TrueTypeFont;
import org.newdawn.slick.util.ResourceLoader;
public class Text {
private TrueTypeFont font2;
public void drawString(String font, String string, int x, int y, Color color) {
// TODO: Fix extreme lag issues.
try {
InputStream inputStream = ResourceLoader.getResourceAsStream(font);
Font awtFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
awtFont = awtFont.deriveFont(24f); // set font size
font2 = new TrueTypeFont(awtFont, false);
Color.white.bind();
font2.drawString(x, y, string, color);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Dont exactly want to release my games source but heres the code that displays the text.
// Initialization code OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Text t = new Text();
t.drawString("res/Minecraftia.ttf", "test", 0, 0, Color.yellow);
Edit:
// Initialization code OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT);
while (!Display.isCloseRequested()) {
// Render
init();
input();
grid.draw();
drawSelectionBox();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void init() {
// This is what i'm meant to do????
Text t = new Text();
t.drawString("res/Minecraftia.ttf", "test", 0, 0, Color.white);
}
Edit again: (Hope not too long)
public Boot() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setTitle("Test Program.");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
grid = new BlockGrid();
// Initialization code OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT);
init();
input();
grid.draw();
drawSelectionBox();
Display.update();
Text t = new Text();
t.drawString("res/Minecraftia.ttf", "test", 0, 0, Color.white);
while (!Display.isCloseRequested()) {
// Render
init();
input();
grid.draw();
drawSelectionBox();
//Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
Because you read the whole font and create it in every render call.
public void drawString(String font, String string, int x, int y, Color color) {
try {
//You create a new resource stream and load a file
InputStream inputStream = ResourceLoader.getResourceAsStream(font); // <-- slow
//You create a new Fonts and load it out of the input stream
Font awtFont = Font.createFont(Font.TRUETYPE_FONT, inputStream); // <-- extremely slow
//You create a new TrueTypeFont out of it
awtFont = awtFont.deriveFont(24f); // set font size
font2 = new TrueTypeFont(awtFont, false); // <-- slow
Color.white.bind();
font2.drawString(x, y, string, color);
} catch (Exception e) {
e.printStackTrace();
}
}
Instead, you should do the Font-loading only once in an init call and then just refer to the TrueTypeFont when rendering.
Remember that rendering is a very performance sensitive call and creating instances or streams and loading in that method (and in update(..), too) can drastically drop your FPS rate and should be avoided.
Update
Furthermore, you are creating a new instance of Text every rendering call too:
Text t = new Text();
t.drawString("res/Minecraftia.ttf", "test", 0, 0, Color.yellow);
Here too, create this once in the beginning or, better, just pass the String to draw to the drawString method instead of having a wrapper object like Text for that.
Hi guys i am trying to draw a 100 by 100 image to my screen. However when i draw it, openGL draws it half the size of my square with a kind of border round the right and bottom edges.
This is my code:
package biz.boulter.lwjglgame;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import static org.lwjgl.opengl.GL11.*;
public class Game
{
public static final int WIDTH = 1000;
public static final int HEIGHT = WIDTH / 16 * 9;
private static Texture t;
private static void render()
{
glClear(GL_COLOR_BUFFER_BIT);
t.bind();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(100, 100); // top-left
glTexCoord2f(1, 0);
glVertex2i(200, 100); // top-right
glTexCoord2f(1, 1);
glVertex2i(200, 200); // bottom-right
glTexCoord2f(0, 1);
glVertex2i(100, 200); // bottom-left
glEnd();
}
private static Texture loadTexture(String path) throws Exception{
return TextureLoader.getTexture("PNG", Game.class.getResourceAsStream(path));
}
public static void main(String[] args)
{
try
{
Display.setDisplayMode(new DisplayMode(1000, 1000 / 16*9));
Display.create();
t = loadTexture("/assets/guy.png");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1000, 1000/16*9, 0, 1, -1);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
while(!Display.isCloseRequested())
{
render();
Display.sync(60);
Display.update();
}
}catch(Exception e)
{
e.printStackTrace();
System.exit(0);
}
}
}
Why is it doing this. Also i am using slick-util.jar for the texture loading.
ScreenShot:
http://oi59.tinypic.com/13zyflk.jpg
I have a rectangle and this will be the base of my moving object.
I`m trying to rotate the object only when the A button is pressed, when is released the object should stop rotating.
package Tanc;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.LWJGLException;
public class Tanc{
public Tanc(){
try{
Display.setDisplayMode(new DisplayMode(640,480));
Display.setTitle("Tanc");
Display.create();
}catch(LWJGLException e){
e.printStackTrace();
}
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glOrtho(1, 1, 1, 1, 1, -1);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glMatrixMode(GL11.GL_PROJECTION);
float y_angle = 0;
boolean aFlag = false;
while(!Display.isCloseRequested()){
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
// GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glRectd(0, 0, 0.2f, 0.3f);
GL11.glTranslatef(0, 0, 0);
while(Keyboard.next()){
if(Keyboard.getEventKey() == Keyboard.KEY_A){
aFlag = true;
}
}
if(aFlag){
y_angle = 0.1f;
GL11.glRotatef(y_angle, 0, 0, 1);
}
else{
y_angle = 0;
GL11.glRotatef(0, 0, 0, 1);
}
// GL11.glPopMatrix();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
public static void main(String[] args){
new Tanc();
}
}
That is because you never really rotate anything. You y_angle doesn't really change other than from 0.0 to 0.1.
Remember that the angle parameter glRotatef() takes, need to be in degrees and not radians. A full circle in radians goes from 0.0 to ~6.2831 radians. Where a full circle using degress goes from 0.0 to 360.0 degress. So your angle isn't noticeable at all, because your only changing it by such a small amount.
I've changed your code. When you now hold the A button, it will rotate and when you release the button it will stop rotating.
float y_angle = 0;
while (!Display.isCloseRequested()) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glLoadIdentity();
GL11.glRectd(0, 0, 0.2f, 0.3f);
GL11.glTranslatef(0, 0, 0);
while (Keyboard.next()){
if (Keyboard.getEventKey() == Keyboard.KEY_A) {
y_angle += 10f;
}
}
GL11.glRotatef(y_angle, 0, 0, 1);
Display.update();
Display.sync(60);
}
I'm trying to get a simple triangle drawn in Java using LWJGL.
I'm trying to get a simple triangle up, each with a corner of one specific color. Right now it is just giving me a blank screen.
Here is my code:
package com.ex;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.input.Keyboard;
public class ColoredTriangle {
public void start() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// Init OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 640, 480, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
boolean quit = false;
while (!quit) {
// Clear the screen.
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// Begin drawing
GL11.glBegin(GL11.GL_TRIANGLES);
// Top & Red
GL11.glColor3f(1.0f, 0.0f, 0.0f);
GL11.glVertex2f(0.0f, 1.0f);
// Right & Green
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glVertex2f(1.0f, 1.0f);
// Left & Blue
GL11.glColor3f(0.0f, 0.0f, 1.0f);
GL11.glVertex2f(1.0f, -1.0f);
GL11.glEnd();
Display.update();
if (Display.isCloseRequested() || Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
quit = true;
}
Display.destroy();
}
public static void main(String args[]) {
ColoredTriangle ct = new ColoredTriangle();
ct.start();
}
}
It is working perfectly fine, it's just that your triangle is 1 unit high and your window is 480 units high, so it only shows up as one pixel in the corner.
If you replace GL11.glOrtho(0, 640, 480, 0, 1, -1); with GL11.glOrtho(-3.2, 3.2, -2.4, 2.4, -1, 1); then you'll see everything just fine.