aboutsummaryrefslogtreecommitdiffstats
path: root/gl4java/utils/textures/TextureGrabber.java
blob: d7d3bff2fb28f0f7638e9f6bf32864f5ee1c5a0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package gl4java.utils.textures;

import gl4java.*;

import java.io.*;
import java.net.*;

/**
 * This abstract Class defines the interface
 * for ALL texture Grabbers !
 * The TextureGrabber's implementations are used to
 * save the pixels of the GL Context to a file !
 *
 * @see TextureTool
 * @see	GLImageCanvas
 */   
public abstract class TextureGrabber
implements GLEnum, GLUEnum
{
  protected byte[] pixels=null;
  protected int xpos;
  protected int ypos;
  protected int width;
  protected int height;
  protected GLFunc gl;

  public TextureGrabber(GLFunc gl)
  {
    this.gl=gl;
  }

  /**
   * Grab the pixels outta the OpenGL Frambuffer
   *
   * @param source the frambuffer source (like glReadBuffer), 
   *		   can be: GL_FRONT, GL_BACK, ....
   * @param x      the xpos
   * @param y      the ypos
   * @param w      the width
   * @param h      the height
   *
   * @see GLFunc#glReadBuffer
   */
  public void grabPixels(int source, int x, int y, int w, int h) 
  {
	int swapbytes[]={0}, lsbfirst[]={0}, rowlength[]={0};
	int skiprows[]={0}, skippixels[]={0}, alignment[]={0};

    xpos=x;
    ypos=y;
    width=w;
    height=h;
    pixels=new byte[w * h * 3];
    
    /* Save current modes. */
    gl.glGetIntegerv(GL_PACK_SWAP_BYTES, swapbytes);
    gl.glGetIntegerv(GL_PACK_LSB_FIRST, lsbfirst);
    gl.glGetIntegerv(GL_PACK_ROW_LENGTH, rowlength);
    gl.glGetIntegerv(GL_PACK_SKIP_ROWS, skiprows);
    gl.glGetIntegerv(GL_PACK_SKIP_PIXELS, skippixels);
    gl.glGetIntegerv(GL_PACK_ALIGNMENT, alignment);

    /* Little endian machines (DEC Alpha, Intel 80x86, ... for example) could
    benefit from setting GL_PACK_LSB_FIRST to GL_TRUE
    instead of GL_FALSE, but this would require changing the
    generated bitmaps too. */
    gl.glPixelStorei(GL_PACK_SWAP_BYTES, 0);
    gl.glPixelStorei(GL_PACK_LSB_FIRST, 1);
    gl.glPixelStorei(GL_PACK_ROW_LENGTH, w);
    gl.glPixelStorei(GL_PACK_SKIP_ROWS, 0);
    gl.glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
    gl.glPixelStorei(GL_PACK_ALIGNMENT, 1);

    //get viewport data
    gl.glReadBuffer(source);
    gl.glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);    

    gl.glPixelStorei(GL_PACK_SWAP_BYTES, swapbytes[0]);
    gl.glPixelStorei(GL_PACK_LSB_FIRST, lsbfirst[0]);
    gl.glPixelStorei(GL_PACK_ROW_LENGTH, rowlength[0]);
    gl.glPixelStorei(GL_PACK_SKIP_ROWS, skiprows[0]);
    gl.glPixelStorei(GL_PACK_SKIP_PIXELS, skippixels[0]);
    gl.glPixelStorei(GL_PACK_ALIGNMENT, alignment[0]);

  }

  public boolean write2File(String fname)
  {
    try {
    	    OutputStream os= new java.io.FileOutputStream(fname);
	    return write2File(os);
    } catch (Exception ex) {
    	System.out.println("TGATextureGrabber.write2File <"+
		fname+"> failed !\n"+ex);
    }
    return false;
  }

  public boolean write2File(URL base, String uri)
  {
    try {
	    URL url = new URL (base, uri);
	    URLConnection urlcon = url.openConnection();
	    urlcon.setDoOutput(true);
	    OutputStream os = urlcon.getOutputStream();
	    return write2File(os);
    } catch (Exception ex) {
    	System.out.println("TGATextureGrabber.write2File <"+
		base+" / "+uri+"> failed !\n"+ex);
    }
    return false;
  }

  public abstract boolean write2File(OutputStream os);
}