I have a 3d program that was working fine before I updated my nvidia gf 620m graphics drivers to version 22.21.13.8494 .Now whenever I run the program I get a black screen . I tried to find the source of the problem and it seems to be with the multisampling FBO in my program as the problem only occurs when its enabled.
My FBO class.
public class Fbo {
public static final int NONE = 0;
public static final int DEPTH_TEXTURE = 1;
public static final int DEPTH_RENDER_BUFFER = 2;
private final int width;
private final int height;
private int frameBuffer;
private boolean multisampleMultiTargets = false;
private int colourTexture;
private int depthTexture;
private int depthBuffer;
private int colourBuffer;
private int colourBuffer2;
/**
* Creates an FBO of a specified width and height, with the desired type of
* depth buffer attachment.
*
* #param width
* - the width of the FBO.
* #param height
* - the height of the FBO.
* #param depthBufferType
* - an int indicating the type of depth buffer attachment that
* this FBO should use.
*/
public Fbo(int width, int height, int depthBufferType) {
this.width = width;
this.height = height;
initialiseFrameBuffer(depthBufferType);
}
public Fbo(int width, int height) {
this.width = width;
this.height = height;
this.multisampleMultiTargets = true;
initialiseFrameBuffer(DEPTH_RENDER_BUFFER);
}
/**
* Deletes the frame buffer and its attachments when the game closes.
*/
public void cleanUp() {
GL30.glDeleteFramebuffers(frameBuffer);
GL11.glDeleteTextures(colourTexture);
GL11.glDeleteTextures(depthTexture);
GL30.glDeleteRenderbuffers(depthBuffer);
GL30.glDeleteRenderbuffers(colourBuffer);
GL30.glDeleteRenderbuffers(colourBuffer2);
}
/**
* Binds the frame buffer, setting it as the current render target. Anything
* rendered after this will be rendered to this FBO, and not to the screen.
*/
public void bindFrameBuffer() {
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
}
/**
* Unbinds the frame buffer, setting the default frame buffer as the current
* render target. Anything rendered after this will be rendered to the
* screen, and not this FBO.
*/
public void unbindFrameBuffer() {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
}
/**
* Binds the current FBO to be read from (not used in tutorial 43).
*/
public void bindToRead() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, frameBuffer);
GL11.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0);
}
/**
* #return The ID of the texture containing the colour buffer of the FBO.
*/
public int getColourTexture() {
return colourTexture;
}
/**
* #return The texture containing the FBOs depth buffer.
*/
public int getDepthTexture() {
return depthTexture;
}
/**
* Creates the FBO along with a colour buffer texture attachment, and
* possibly a depth buffer.
*
* #param type
* - the type of depth buffer attachment to be attached to the
* FBO.
*/
public void resolveToFbo(int readBuffer,Fbo outputFbo){
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER,outputFbo.frameBuffer);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER,this.frameBuffer);
GL11.glReadBuffer(readBuffer);
GL30.glBlitFramebuffer(0,0,width,height,0,0,outputFbo.width,outputFbo.height,GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT,GL11.GL_LINEAR);
this.unbindFrameBuffer();
}
public void resolveToScreen(){
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER,0);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER,this.frameBuffer);
GL11.glDrawBuffer(GL11.GL_BACK);
GL30.glBlitFramebuffer(0,0,width,height,0,0,Display.getWidth(),Display.getHeight(),GL11.GL_COLOR_BUFFER_BIT ,GL11.GL_LINEAR);
this.unbindFrameBuffer();
}
private void initialiseFrameBuffer(int type) {
createFrameBuffer();
if(multisampleMultiTargets){
colourBuffer = createMultisampledColourbuffer(GL30.GL_COLOR_ATTACHMENT0);
colourBuffer2 = createMultisampledColourbuffer(GL30.GL_COLOR_ATTACHMENT1);
}else{
createTextureAttachment();
}
if (type == DEPTH_RENDER_BUFFER) {
createDepthBufferAttachment();
} else if (type == DEPTH_TEXTURE) {
createDepthTextureAttachment();
}
unbindFrameBuffer();
}
/**
* Creates a new frame buffer object and sets the buffer to which drawing
* will occur - colour attachment 0. This is the attachment where the colour
* buffer texture is.
*
*/
private void createFrameBuffer() {
frameBuffer = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
determineDrawBuffer();
}
private void determineDrawBuffer(){
IntBuffer drawBuffers = BufferUtils.createIntBuffer(2);
drawBuffers.put(GL30.GL_COLOR_ATTACHMENT0);
if(this.multisampleMultiTargets){
drawBuffers.put(GL30.GL_COLOR_ATTACHMENT1);
}
drawBuffers.flip();
GL20.glDrawBuffers(drawBuffers);
}
/**
* Creates a texture and sets it as the colour buffer attachment for this
* FBO.
*/
private void createTextureAttachment() {
colourTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, colourTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
(ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colourTexture,
0);
}
/**
* Adds a depth buffer to the FBO in the form of a texture, which can later
* be sampled.
*/
private void createDepthTextureAttachment() {
depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT24, width, height, 0, GL11.GL_DEPTH_COMPONENT,
GL11.GL_FLOAT, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);
}
private int createMultisampledColourbuffer(int Attachment){
int colourBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, colourBuffer);
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER,4, GL11.GL_RGBA8, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER,Attachment, GL30.GL_RENDERBUFFER,
colourBuffer);
return colourBuffer;
}
/**
* Adds a depth buffer to the FBO in the form of a render buffer. This can't
* be used for sampling in the shaders.
*/
private void createDepthBufferAttachment() {
depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
if(!multisampleMultiTargets){
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, width, height);
}else{
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER,4, GL14.GL_DEPTH_COMPONENT24, width, height);
}
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER,
depthBuffer);
}
}
Related
This question already has answers here:
glTranslatef not working within glBegin .. glEnd
(2 answers)
Closed 7 years ago.
I'm attempting to draw a red square with LGJWL (native OpenGL bindings for Java) in Java. I receive a 1282 error from OpenGL and my square does not appear.
Below is (what I believe to be) the basic implementation for what I'm trying to do.
// begin drawing quads
glBegin(GL11.GL_QUADS);
// set color
glColor4d(255, 0, 0, 255);
// draw rectangle vertices
glVertex2i(0, 0);
glVertex2i(100, 0);
glVertex2i(100, 100);
glVertex2i(0, 100);
glEnd();
Following is what I'm trying to do in practice.
public class WindowComponent extends Component {
/** Window color */
private Color color = new Color();
/**
* Sets the window's color
* #param r red
* #param b blue
* #param g green
* #param a alpha
*/
public void setColor(int r, int g, int b, int a) {
color.set(r, g, b, a);
}
/**
* #see Component#renderComponent()
*/
#Override
protected void renderComponent() {
// begin drawing quads
begin(GL11.GL_QUADS);
// set color
GL11.glColor4ub(color.getRedByte(), color.getGreenByte(), color.getBlueByte(), color.getAlphaByte());
// draw rectangle vertices
GL11.glVertex2i(0, 0);
GL11.glVertex2i(getWidth(), 0);
GL11.glVertex2i(getWidth(), getHeight());
GL11.glVertex2i(0, getHeight());
end();
}
}
is an extension of...
public abstract class Component {
/** Dimension of component */
private Dimension size = new Dimension();
/** Position of component */
private Vector2f position = new Vector2f();
/**
* Gets width
* #return width
*/
public int getWidth() {
return size.getWidth();
}
/**
* Gets height
* #return height
*/
public int getHeight() {
return size.getHeight();
}
/**
* Gets size
* #return size
*/
public Dimension getSize() {
return size;
}
/**
* Gets X position
* #return X position
*/
public float getX() {
return position.getX();
}
/**
* Gets Y position
* #return Y position
*/
public float getY() {
return position.getY();
}
/**
* Gets position vector
* #return position vector
*/
public Vector2f getPosition() {
return position;
}
/**
* Sets width
* #param width width
*/
public void setWidth(int width) {
size.setWidth(width);
}
/**
* Sets height
* #param height height
*/
public void setHeight(int height) {
size.setHeight(height);
}
/**
* Sets size
* #param width width
* #param height height
*/
public void setSize(int width, int height) {
size.setSize(width, height);
}
/**
* Sets X position
* #param x X position
*/
public void setX(float x) {
position.setX(x);
}
/**
* Sets Y position
* #param y Y position
*/
public void setY(float y) {
position.setY(y);
}
/**
* Sets position
* #param x X position
* #param y Y position
*/
public void setPosition(float x, float y) {
position.set(x, y);
}
/**
* Begins drawing and does parent translations
* #param mode drawing mode
*/
protected void begin(int mode) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glBegin(mode);
GL11.glTranslatef(getX(), getY(), 0);
}
/**
* Ends drawing and does parent translations
*/
protected void end() {
GL11.glTranslatef(-getX(), -getY(), 0);
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
/**
* Applies pre-rendering checks then renders the component
*/
public void render() {
renderComponent();
}
/**
* Component rendering code here
*/
protected abstract void renderComponent();
}
and I'm initializing this all with...
WindowComponent window = new WindowComponent();
window.setSize(100, 100);
window.setPosition(100, 100);
window.setColor(255, 0, 0, 255);
window.render();
In begin:
GL11.glBegin(mode);
GL11.glTranslatef(getX(), getY(), 0);
You cannot call glTranslate in between glBegin and glEnd; move it to before.
im using the Canvas class to make a screensaver as a schoolproject.
But the window generated by Canvas doesnt show my objects on it (current time)
until i minimize it an resize it again. After that all things works fine.
so what is wrong?
thank you for coming answers!
with kind regards
leon
those are the classes, i peronally think that the problem is in the class Start or BufferedCanvas
import java.awt.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Start
{
int fensterX = 900;
int fensterY = 700;
Farbengenerator fg = new Farbengenerator();
BufferedCanvas c =newBufferedCanvas("Bild",fensterX,fensterY);
Zeit z = new Zeit();
SchriftParameter sp = new SchriftParameter();
public void zeichneText(){
double x = 100;
double y = 100;
double fy =0.01;
double fx =0.02;
int red=0;
int green=0;
int blue=0;
double colourGrowRate=0.05;
String uhr;
c.setFont(sp.setzteSchrift());
c.setForegroundColour(Color.BLACK);
c.setBackgroundColour(Color.WHITE);
for(int i=0;i<100;i++){
c.drawString("Starting...",(int)x,(int)y);
c.updateAndShow();
try{Thread.sleep(50);}
catch(Exception e){};
c.updateAndShow();
}
CreateButton d = new CreateButton();
d.run();
while(true) {
c.erase();
uhr = z.erstelleZeit();
c.drawString(uhr,(int)x,(int)y);
if((int)x >fensterX-93 || (int)x <5){
fx = fx * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)y > fensterY-1 || (int)y < 46){
fy = fy * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)colourGrowRate>=1){
fg.generiereFarbe();
colourGrowRate = 0.05;
}
colourGrowRate=colourGrowRate+colourGrowRate;
x = x + fx;
y = y + fy;
c.updateAndShow();
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
public class BufferedCanvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColour;
private Image canvasImage;
BufferStrategy buff;
/**
* Create a BufferedCanvas with default height,
width and background colour
* (300, 300, white).
* #param title title to appear in Canvas Frame
*/
public BufferedCanvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a BufferedCanvas with default background colour (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public BufferedCanvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a BufferedCanvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background colour of the canvas
*/
public BufferedCanvas(String title, int width, int height, Color bgColour)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColour = bgColour;
frame.pack();
frame.createBufferStrategy(2);
buff = frame.getBufferStrategy();
graphic = (Graphics2D)buff.getDrawGraphics();
setVisible(true);
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background colour
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColour);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Update the canvas and show the new image.
*/
public void updateAndShow(){
buff.show();
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
//canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground colour of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
//canvas.repaint();
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.fill(shape); // erase by filling background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.draw(shape); // erase by drawing background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
//canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
//canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.drawString(text, x, y);
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
//canvas.repaint();
}
/**
* Draws a dot/pixel on the Canvas.
* #param x x co-ordinate of dot
* #param y y co-ordinate of dot
*/
public void drawDot(int x, int y)
{
graphic.drawLine(x, y, x, y);
//canvas.repaint();
}
/**
* Sets the foreground colour of the Canvas.
* #param newColour the new colour for the foreground of the Canvas
*/
public void setForegroundColour(Color newColour)
{
graphic.setColor(newColour);
}
/**
* Returns the current colour of the foreground.
* #return the colour of the foreground of the Canvas
*/
public Color getForegroundColour()
{
return graphic.getColor();
}
/**
* Sets the background colour of the Canvas.
* #param newColour the new colour for the background of the Canvas
*/
public void setBackgroundColour(Color newColour)
{
backgroundColour = newColour;
graphic.setBackground(newColour);
}
/**
* Returns the current colour of the background
* #return the colour of the background of the Canvas
*/
public Color getBackgroundColour()
{
return backgroundColour;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (Exception e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Nested class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class CreateButton extends JFrame implements ActionListener{
public void run() {
createAndShowGUI();
}
public CreateButton() {
// set layout for the frame
this.getContentPane().setLayout(new FlowLayout());
JButton button1 = new JButton();
button1.setText("closeApp");
//set actionlisteners for the buttons
button1.addActionListener(this);
// define a custom short action command for the button
button1.setActionCommand("closeApp");
// add buttons to frame
add(button1);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new CreateButton();
//Display the window.
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae) {
String action = ae.getActionCommand();
if (action.equals("closeApp")) {
System.exit(1);
}
}
}
import java.awt.*;
public class SchriftParameter
{
public Font setzteSchrift(){
Font f = new Font("Fixed",1,24);
return (f);
}
}
public class Farbengenerator
{
int r=0;
int g=0;
int b=0;
public void generiereFarbe(){
if (r<255&&g==0&&b==0){
r++;
}
else if (r==255&&g<255&&b==0){
g++;
}
else if (r>0&&g==255&&b==0){
r= r-1;
}
else if (r==0&&g==255&&b<255){
b++;
}
else if (r==0&&g>0&&b==255){
g=g-1;
}
else if (r<255&&g==0&&b==255){
r++;
}
else if (r==255&&g==0&&b>0){
b=b-1;
}
}
public int gibROT () {
return(r);
}
public int gibGRUEN () {
return(g);
}
public int gibBLAU () {
return(b);
}
}
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Zeit
{
public String erstelleZeit(){
DateFormat df = new SimpleDateFormat("HH:mm:ss");
Date d = new Date();
String uhr = df.format(d);
return (uhr);
}
}
On my JFrame, I am using the following code to display an image on the Panel :
ImageIcon img= new ImageIcon("res.png");
jLabel.setIcon(img);
I would like to "auto-size" the picture in the label. Indeed, sometimes the image size is only few pixel, sometimes well more.
Is there a way to set the size of the label, and then to autosize the image in the label?
This is a tricky question. You highlight the fact that you are using a JLabel to show the image, which is the standard way of doing things, but, JLabel is a complex little beast, with text, icon and text alignment and positioning.
If you don't need all that extra functionality, I would simply create yourself a custom component capable of painting a scaled image...
The next question is, how do you want to scale the image? Do you want to maintain the aspect ratio of the image? Do you want to "fit" or "fill" the image to the available space.
#David is right. You should, where possible, avoid Image#getScaledInstance as it's not the fastest, but, more importantly, generally, it doesn't provide the highest quality either.
Fit vs Fill
The following example is rather simple (and borrows heavy from my library of code, so it's probably also a little convoluted ;)). It could use from a background scaling thread, but I would base the decision on the potential size of original image.
public class ResizableImage {
public static void main(String[] args) {
new ResizableImage();
}
public ResizableImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
try {
BufferedImage image = ImageIO.read(new File("/path/to/your/image"));
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ScalablePane(image));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (Exception exp) {
exp.printStackTrace();
}
}
});
}
public class ScalablePane extends JPanel {
private Image master;
private boolean toFit;
private Image scaled;
public ScalablePane(Image master) {
this(master, true);
}
public ScalablePane(Image master, boolean toFit) {
this.master = master;
setToFit(toFit);
}
#Override
public Dimension getPreferredSize() {
return master == null ? super.getPreferredSize() : new Dimension(master.getWidth(this), master.getHeight(this));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Image toDraw = null;
if (scaled != null) {
toDraw = scaled;
} else if (master != null) {
toDraw = master;
}
if (toDraw != null) {
int x = (getWidth() - toDraw.getWidth(this)) / 2;
int y = (getHeight() - toDraw.getHeight(this)) / 2;
g.drawImage(toDraw, x, y, this);
}
}
#Override
public void invalidate() {
generateScaledInstance();
super.invalidate();
}
public boolean isToFit() {
return toFit;
}
public void setToFit(boolean value) {
if (value != toFit) {
toFit = value;
invalidate();
}
}
protected void generateScaledInstance() {
scaled = null;
if (isToFit()) {
scaled = getScaledInstanceToFit(master, getSize());
} else {
scaled = getScaledInstanceToFill(master, getSize());
}
}
protected BufferedImage toBufferedImage(Image master) {
Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
BufferedImage image = createCompatibleImage(masterSize);
Graphics2D g2d = image.createGraphics();
g2d.drawImage(master, 0, 0, this);
g2d.dispose();
return image;
}
public Image getScaledInstanceToFit(Image master, Dimension size) {
Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
return getScaledInstance(
toBufferedImage(master),
getScaleFactorToFit(masterSize, size),
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true);
}
public Image getScaledInstanceToFill(Image master, Dimension size) {
Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
return getScaledInstance(
toBufferedImage(master),
getScaleFactorToFill(masterSize, size),
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true);
}
public Dimension getSizeToFit(Dimension original, Dimension toFit) {
double factor = getScaleFactorToFit(original, toFit);
Dimension size = new Dimension(original);
size.width *= factor;
size.height *= factor;
return size;
}
public Dimension getSizeToFill(Dimension original, Dimension toFit) {
double factor = getScaleFactorToFill(original, toFit);
Dimension size = new Dimension(original);
size.width *= factor;
size.height *= factor;
return size;
}
public double getScaleFactor(int iMasterSize, int iTargetSize) {
return (double) iTargetSize / (double) iMasterSize;
}
public double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public double getScaleFactorToFill(Dimension masterSize, Dimension targetSize) {
double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width);
double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height);
return Math.max(dScaleHeight, dScaleWidth);
}
public BufferedImage createCompatibleImage(Dimension size) {
return createCompatibleImage(size.width, size.height);
}
public BufferedImage createCompatibleImage(int width, int height) {
GraphicsConfiguration gc = getGraphicsConfiguration();
if (gc == null) {
gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
BufferedImage image = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
image.coerceData(true);
return image;
}
protected BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
} else {
imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
}
return imgScale;
}
protected BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected BufferedImage getScaledUpInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
}
}
Is there a way to set the size of the label
Override getPreferredSize() of JLabel and return the Dimensions you want,
but because a JLabel will size itself to its content you will just need to resize the picture you add to the JLabel.
and then to autosize the image in the label?
You will have to resize your image according to the width and height you want (than simply add it to the JLabel and the JLabel will size to fit the image).
I do not recommend Image.getScaledInstance(..) have a read here for more:
The Perils of Image.getScaledInstance()
Mainly the problem outlined is:
Image.getScaledInstance() does not return a finished, scaled image. It
leaves much of the scaling work for a later time when the image pixels
are used.
Here is a custom method Ive been using to circumvent the issues created by getScaledInstance:
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
you would create an image to whatever size you want via:
BufferedImage image=ImageIO.read(..);
BufferedImage resizedImage=resize(image,100,100);//resize the image to 100x100
It can also be done by overriding the paintComponent method of JLabel and drawing the image having width and height as that of JLabel. And if you wish to resize the image when the parent container is resized you can apply the WindowListener on the parent container and repaint the Jlabel instance each time the parent container is resized.
Here is the Demo:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class LabelDemo extends JFrame
{
ImageIcon imageIcon;
MyJLabel jLabel ;
public LabelDemo ()
{
super("JLabel Demo");
}
public void createAndShowGUI()
{
imageIcon = new ImageIcon("apple.png");
jLabel = new MyJLabel(imageIcon);
getContentPane().add(jLabel);
addWindowListener( new WindowAdapter()
{
public void windowResized(WindowEvent evt)
{
jLabel.repaint();
}
});
setSize(300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
jLabel.repaint();
}
public static void main(String st[])
{
SwingUtilities.invokeLater( new Runnable()
{
#Override
public void run()
{
LabelDemo demo = new LabelDemo();
demo.createAndShowGUI();
}
});
}
}
class MyJLabel extends JLabel
{
ImageIcon imageIcon;
public MyJLabel(ImageIcon icon)
{
super();
this.imageIcon = icon;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(imageIcon.getImage(),0,0,getWidth(),getHeight(),this);
}
}
You can use the Stretch Icon.
The image will automatically be resized to fill the space available to the label. You can control whether the image is scaled proportionally or completely fills the area.
Using the StretchIcon is more flexible than doing custom painting as suggested in the other links as you can benefit from the automatic resizing on any component that supports an Icon.
StretchIcon.java:
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.net.URL;
import javax.swing.ImageIcon;
/**
* An <CODE>Icon</CODE> that scales its image to fill the component area, excluding any border or insets, optionally maintaining the image's
* aspect ratio by padding and centering the scaled image horizontally or vertically.
* <P>
* The class is a drop-in replacement for <CODE>ImageIcon</CODE>, except that the no-argument constructor is not supported.
* <P>
* As the size of the Icon is determined by the size of the component in which it is displayed, <CODE>StretchIcon</CODE> must only be used
* in conjunction with a component and layout that does not depend on the size of the component's Icon.
*
* #version 1.1 01/15/2016
* #author Darryl
*/
public class StretchIcon extends ImageIcon
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Determines whether the aspect ratio of the image is maintained. Set to <code>false</code> to allow th image to distort to fill the
* component.
*/
protected boolean proportionate = true;
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes.
*
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
*
* #see ImageIcon#ImageIcon(byte[])
*/
public StretchIcon(byte[] imageData)
{
super(imageData);
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior.
*
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(byte[])
*/
public StretchIcon(byte[] imageData, boolean proportionate)
{
super(imageData);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes.
*
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(byte[], java.lang.String)
*/
public StretchIcon(byte[] imageData, String description)
{
super(imageData, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior.
*
* #see ImageIcon#ImageIcon(byte[])
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(byte[], java.lang.String)
*/
public StretchIcon(byte[] imageData, String description, boolean proportionate)
{
super(imageData, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image.
*
* #param image the image
*
* #see ImageIcon#ImageIcon(java.awt.Image)
*/
public StretchIcon(Image image)
{
super(image);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior.
*
* #param image the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.awt.Image)
*/
public StretchIcon(Image image, boolean proportionate)
{
super(image);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image.
*
* #param image the image
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(java.awt.Image, java.lang.String)
*/
public StretchIcon(Image image, String description)
{
super(image, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior.
*
* #param image the image
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.awt.Image, java.lang.String)
*/
public StretchIcon(Image image, String description, boolean proportionate)
{
super(image, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file.
*
* #param filename a String specifying a filename or path
*
* #see ImageIcon#ImageIcon(java.lang.String)
*/
public StretchIcon(String filename)
{
super(filename);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior.
*
* #param filename a String specifying a filename or path
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.lang.String)
*/
public StretchIcon(String filename, boolean proportionate)
{
super(filename);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file.
*
* #param filename a String specifying a filename or path
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(java.lang.String, java.lang.String)
*/
public StretchIcon(String filename, String description)
{
super(filename, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior.
*
* #param filename a String specifying a filename or path
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.awt.Image, java.lang.String)
*/
public StretchIcon(String filename, String description, boolean proportionate)
{
super(filename, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL.
*
* #param location the URL for the image
*
* #see ImageIcon#ImageIcon(java.net.URL)
*/
public StretchIcon(URL location)
{
super(location);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior.
*
* #param location the URL for the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.net.URL)
*/
public StretchIcon(URL location, boolean proportionate)
{
super(location);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL.
*
* #param location the URL for the image
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(java.net.URL, java.lang.String)
*/
public StretchIcon(URL location, String description)
{
super(location, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior.
*
* #param location the URL for the image
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.net.URL, java.lang.String)
*/
public StretchIcon(URL location, String description, boolean proportionate)
{
super(location, description);
this.proportionate = proportionate;
}
/**
* Paints the icon. The image is reduced or magnified to fit the component to which it is painted.
* <P>
* If the proportion has not been specified, or has been specified as <code>true</code>, the aspect ratio of the image will be preserved
* by padding and centering the image horizontally or vertically. Otherwise the image may be distorted to fill the component it is
* painted to.
* <P>
* If this icon has no image observer,this method uses the <code>c</code> component as the observer.
*
* #param c the component to which the Icon is painted. This is used as the observer if this icon has no image observer
* #param g the graphics context
* #param x not used.
* #param y not used.
*
* #see ImageIcon#paintIcon(java.awt.Component, java.awt.Graphics, int, int)
*/
#Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y)
{
Image image = getImage();
if (image == null)
{
return;
}
Insets insets = ((Container) c).getInsets();
x = insets.left;
y = insets.top;
int w = c.getWidth() - x - insets.right;
int h = c.getHeight() - y - insets.bottom;
if (proportionate)
{
int iw = image.getWidth(c);
int ih = image.getHeight(c);
if ((iw * h) < (ih * w))
{
iw = (h * iw) / ih;
x += (w - iw) / 2;
w = iw;
}
else
{
ih = (w * ih) / iw;
y += (h - ih) / 2;
h = ih;
}
}
ImageObserver io = getImageObserver();
/*
* Added this code to generate nicer looking results when scaling. - bspkrs
* BEGIN CHANGES
*/
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, w, h, io == null ? c : io);
g2d.dispose();
/*
* END CHANGES
*/
g.drawImage(bi, x, y, w, h, io == null ? c : io);
}
/**
* Overridden to return 0. The size of this Icon is determined by the size of the component.
*
* #return 0
*/
#Override
public int getIconWidth()
{
return 0;
}
/**
* Overridden to return 0. The size of this Icon is determined by the size of the component.
*
* #return 0
*/
#Override
public int getIconHeight()
{
return 0;
}
}
Try this function:
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
BufferedImage image1=ImageIO.read(url.openStream());
BufferedImage resizedImage=resize(image,100,100);
System.out.println("Load image into frame...");
icon=new ImageIcon(resizedImage);
private Image fitimage(Image img, int w, int h) {
int width = img.getWidth(this);
int height = img.getHeight(this);
BufferedImage resizedimage;
if (width > w && height > h) {
resizedimage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedimage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0, w, h, null);
g2.dispose();
} else {
resizedimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedimage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0, width, height, null);
g2.dispose();
}
return resizedimage;
}
easywayprogramming.com how to resize imageicon in java
When we apply image icon to any component like button, label or panel, it not apply properly because of size of that image. We can resize that image icon in two ways.
first way:
Image img = myIcon2.getImage(); Image newimg = img.getScaledInstance(230, 310, java.awt.Image.SCALE_SMOOTH);
newIcon = new ImageIcon(newimg);
second way:
Image img = myIcon2.getImage(); BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
newIcon = new ImageIcon(bi);
Try following link easywayprogramming.blogspot.in:
easywayprogramming.blogspot.in ho to resize image icon in java
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I try to draw a basic texture in LWJGL, but I can't.
My main class:
package worldofportals;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
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 static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;
import worldofportals.texture.TextureLoader;
/**
* Initialize the program, handle the rendering, updating, the mouse and the
* keyboard events.
*
* #author Laxika
*/
public class WorldOfPortals {
/**
* Time at the last frame.
*/
private long lastFrame;
/**
* Frames per second.
*/
private int fps;
/**
* Last FPS time.
*/
private long lastFPS;
public static final int DISPLAY_HEIGHT = 1024;
public static final int DISPLAY_WIDTH = 768;
public static final Logger LOGGER = Logger.getLogger(WorldOfPortals.class.getName());
int tileId = 0;
static {
try {
LOGGER.addHandler(new FileHandler("errors.log", true));
} catch (IOException ex) {
LOGGER.log(Level.WARNING, ex.toString(), ex);
}
}
public static void main(String[] args) {
WorldOfPortals main = null;
try {
main = new WorldOfPortals();
main.create();
main.run();
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, ex.toString(), ex);
} finally {
if (main != null) {
main.destroy();
}
}
}
/**
* Create a new lwjgl frame.
*
* #throws LWJGLException
*/
public void create() throws LWJGLException {
//Display
Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH, DISPLAY_HEIGHT));
Display.setFullscreen(false);
Display.setTitle("World of Portals FPS: 0");
Display.create();
//Keyboard
Keyboard.create();
//Mouse
Mouse.setGrabbed(false);
Mouse.create();
//OpenGL
initGL();
resizeGL();
getDelta(); // call once before loop to initialise lastFrame
lastFPS = getTime();
glEnable(GL_TEXTURE_2D); //Enable texturing
tileId = TextureLoader.getInstance().loadTexture("img/tile1.png");
}
/**
* Destroy the game.
*/
public void destroy() {
//Methods already check if created before destroying.
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
}
/**
* Initialize the GL.
*/
public void initGL() {
//2D Initialization
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
}
/**
* Handle the keyboard events.
*/
public void processKeyboard() {
}
/**
* Handle the mouse events.
*/
public void processMouse() {
}
/**
* Handle the rendering.
*/
public void render() {
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < 30; i++) {
for (int j = 30; j >= 0; j--) { // Changed loop condition here.
glBindTexture(GL_TEXTURE_2D, tileId);
// translate to the right location and prepare to draw
GL11.glTranslatef(20, 20, 0);
GL11.glColor3f(0, 0, 0);
// draw a quad textured to match the sprite
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, 64);
GL11.glVertex2f(0, DISPLAY_HEIGHT);
GL11.glTexCoord2f(64, 64);
GL11.glVertex2f(DISPLAY_WIDTH, DISPLAY_HEIGHT);
GL11.glTexCoord2f(64, 0);
GL11.glVertex2f(DISPLAY_WIDTH, 0);
}
GL11.glEnd();
}
}
// restore the model view matrix to prevent contamination
GL11.glPopMatrix();
}
/**
* Resize the GL.
*/
public void resizeGL() {
//2D Scene
glViewport(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f, DISPLAY_WIDTH, 0.0f, DISPLAY_HEIGHT);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
}
public void run() {
while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
if (Display.isVisible()) {
processKeyboard();
processMouse();
update(getDelta());
render();
} else {
if (Display.isDirty()) {
render();
}
}
Display.update();
Display.sync(60);
}
}
/**
* Game update before render.
*/
public void update(int delta) {
updateFPS();
}
/**
* Get the time in milliseconds
*
* #return The system time in milliseconds
*/
public long getTime() {
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}
/**
* Calculate how many milliseconds have passed since last frame.
*
* #return milliseconds passed since last frame
*/
public int getDelta() {
long time = getTime();
int delta = (int) (time - lastFrame);
lastFrame = time;
return delta;
}
/**
* Calculate the FPS and set it in the title bar
*/
public void updateFPS() {
if (getTime() - lastFPS > 1000) {
Display.setTitle("World of Portals FPS: " + fps);
fps = 0;
lastFPS += 1000;
}
fps++;
}
}
And my texture loader:
package worldofportals.texture;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.opengl.GL12;
public class TextureLoader {
private static final int BYTES_PER_PIXEL = 4;//3 for RGB, 4 for RGBA
private static TextureLoader instance;
private TextureLoader() {
}
public static TextureLoader getInstance() {
if (instance == null) {
instance = new TextureLoader();
}
return instance;
}
/**
* Load a texture from file.
*
* #param loc the location of the file
* #return the id of the texture
*/
public int loadTexture(String loc) {
BufferedImage image = loadImage(loc);
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip();
int textureID = glGenTextures(); //Generate texture ID
glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup texture scaling filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Send texel data to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
//Return the texture ID so we can bind it later again
return textureID;
}
/**
* Load an image from disc.
*
* #param loc the location of the image
* #return the image
*/
private BufferedImage loadImage(String loc) {
try {
return ImageIO.read(new File(loc));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
It's not an actual game, just a test to learn and practice openGL in java. Also anyone can suggest me a good book on OpenGL?
Have you tried:
BufferedImage image = loadImage(loc);
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
Color c;
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
c = new Color(image.getRGB(x, y));
buffer.put((byte) c.getRed()); // Red component
buffer.put((byte) c.getGreen()); // Green component
buffer.put((byte) c.getBlue()); // Blue component
buffer.put((byte) c.getAlpha()); // Alpha component. Only for RGBA
}
}
Also, if you are going to put the Alpha component, you should either check the number of components, and add the alpha only if there is 4, or ALWAYS use 4. Also, do GL_RGBA instead of GL_RGBA8.
shouldn't you be calling the
Display.swapBuffers() after render?
** Why is the class CanvasPane not included in the Java API?.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
/**
* Class Canvas - a class to allow for simple graphical
* drawing on a canvas.
*
* #author Michael Kolling (mik)
* #author Bruce Quig
*
* #version 2008.03.30
*/
public class Canvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColor;
private Image canvasImage;
/**
* Create a Canvas with default height, width and background color
* (300, 300, white)
* #param title title to appear in Canvas Frame
*/
public Canvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a Canvas with default background color (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public Canvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a Canvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background color of the canvas
*/
public Canvas(String title, int width, int height, Color bgColor)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColor = bgColor;
frame.pack();
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background color
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColor);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw the outline of a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground color of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
canvas.repaint();
}
/**
* Fill the internal dimensions of the given circle with the current
* foreground color of the canvas.
*/
public void fillCircle(int xPos, int yPos, int diameter)
{
Ellipse2D.Double circle = new Ellipse2D.Double(xPos, yPos, diameter, diameter);
fill(circle);
}
/**
* Fill the internal dimensions of the given rectangle with the current
* foreground color of the canvas. This is a convenience method. A similar
* effect can be achieved with the "fill" method.
*/
public void fillRectangle(int xPos, int yPos, int width, int height)
{
fill(new Rectangle(xPos, yPos, width, height));
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
canvas.repaint();
}
/**
* Erase the internal dimensions of the given circle. This is a
* convenience method. A similar effect can be achieved with
* the "erase" method.
*/
public void eraseCircle(int xPos, int yPos, int diameter)
{
Ellipse2D.Double circle = new Ellipse2D.Double(xPos, yPos, diameter, diameter);
erase(circle);
}
/**
* Erase the internal dimensions of the given rectangle. This is a
* convenience method. A similar effect can be achieved with
* the "erase" method.
*/
public void eraseRectangle(int xPos, int yPos, int width, int height)
{
erase(new Rectangle(xPos, yPos, width, height));
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.fill(shape); // erase by filling background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.draw(shape); // erase by drawing background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.drawString(text, x, y);
graphic.setColor(original);
canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
canvas.repaint();
}
/**
* Sets the foreground color of the Canvas.
* #param newColor the new color for the foreground of the Canvas
*/
public void setForegroundColor(Color newColor)
{
graphic.setColor(newColor);
}
/**
* Returns the current color of the foreground.
* #return the color of the foreground of the Canvas
*/
public Color getForegroundColor()
{
return graphic.getColor();
}
/**
* Sets the background color of the Canvas.
* #param newColor the new color for the background of the Canvas
*/
public void setBackgroundColor(Color newColor)
{
backgroundColor = newColor;
graphic.setBackground(newColor);
}
/**
* Returns the current color of the background
* #return the color of the background of the Canvas
*/
public Color getBackgroundColor()
{
return backgroundColor;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Inner class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
Why it should be? I mean its a BlueJ extension class, AFAIK. Similar questions may come to the mind regarding StringUtils, or NumberUtils. IMHO, these two really qualifies to be there in the original Java API. :)
One huge reason is that it has one of the worst named methods I have ever seen in a Java class:
public void wait(int milliseconds)
Try calling wait(100) on it and watch it work without synchronisation and obviously do something completely different from java.lang.Object.wait(long). This would be a nightmare to do in production.
What on earth is such a method doing in a class named Canvas?