summaryrefslogtreecommitdiffstats
path: root/src/demos/hdr/ARBFPPipeline.java
blob: a27d4cef46a6fa7ce830dad9ae185028a94a9ab6 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package demos.hdr;

import demos.util.FileUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.jogamp.opengl.GL2ES1;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLException;


public class ARBFPPipeline implements Pipeline {

  private int textureFormat;

  public ARBFPPipeline(int textureFormat) {
    this.textureFormat = textureFormat;
  }

  public void init() {
  }

  public void initFloatingPointTexture(GL2 gl, int textureObject, int w, int h) {
    gl.glBindTexture(GL2.GL_TEXTURE_RECTANGLE_ARB, textureObject);
    gl.glCopyTexImage2D(GL2.GL_TEXTURE_RECTANGLE_ARB, 0, textureFormat, 0, 0, w, h, 0);
  }

  public void initTexture(GL2 gl, int textureObject, int w, int h) {
    gl.glBindTexture(GL2.GL_TEXTURE_RECTANGLE_ARB, textureObject);
    gl.glCopyTexImage2D(GL2.GL_TEXTURE_RECTANGLE_ARB, 0, GL2.GL_RGBA, 0, 0, w, h, 0);
  }

  public void copyToTexture(GL2 gl, int textureObject, int w, int h) {
    gl.glBindTexture(GL2.GL_TEXTURE_RECTANGLE_ARB, textureObject);
    gl.glCopyTexSubImage2D(GL2.GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 0, 0, w, h);
  }

  public void bindTexture(GL2 gl, int textureObject) {
    gl.glBindTexture(GL2.GL_TEXTURE_RECTANGLE_ARB, textureObject);
  }

  private List programs = new ArrayList();
  public int loadVertexProgram(GL2 gl, String filename) throws IOException {
    return loadProgram(gl, filename, GL2.GL_VERTEX_PROGRAM_ARB);
  }

  public int loadFragmentProgram(GL2 gl, String filename) throws IOException {
    return loadProgram(gl, filename, GL2.GL_FRAGMENT_PROGRAM_ARB);
  }

  private int loadProgram(GL2 gl, String fileName, int profile) throws IOException {
    String programBuffer = FileUtils.loadStreamIntoString(getClass().getClassLoader().getResourceAsStream(fileName));
    int[] tmpInt = new int[1];
    gl.glGenProgramsARB(1, tmpInt, 0);
    int res = tmpInt[0];
    gl.glBindProgramARB(profile, res);
    gl.glProgramStringARB(profile, GL2.GL_PROGRAM_FORMAT_ASCII_ARB, programBuffer.length(), programBuffer);
    int[] errPos = new int[1];
    gl.glGetIntegerv(GL2.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0);
    if (errPos[0] >= 0) {
      String kind = "Program";
      if (profile == GL2.GL_VERTEX_PROGRAM_ARB) {
        kind = "Vertex program";
      } else if (profile == GL2.GL_FRAGMENT_PROGRAM_ARB) {
        kind = "Fragment program";
      }
      System.out.println(kind + " failed to load:");
      String errMsg = gl.glGetString(GL2.GL_PROGRAM_ERROR_STRING_ARB);
      if (errMsg == null) {
        System.out.println("[No error message available]");
      } else {
        System.out.println("Error message: \"" + errMsg + "\"");
      }
      System.out.println("Error occurred at position " + errPos[0] + " in program:");
      int endPos = errPos[0];
      while (endPos < programBuffer.length() && programBuffer.charAt(endPos) != '\n') {
        ++endPos;
      }
      System.out.println(programBuffer.substring(errPos[0], endPos));
      throw new GLException("Error loading " + kind);
    } else {
      if (profile == GL2.GL_FRAGMENT_PROGRAM_ARB) {
        int[] isNative = new int[1];
        gl.glGetProgramiv(GL2.GL_FRAGMENT_PROGRAM_ARB,
                             GL2.GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB,
                             isNative, 0);
        if (isNative[0] != 1) {
          System.out.println("WARNING: fragment program is over native resource limits");
          Thread.dumpStack();
        }
      }
    }
    return res;
  }

  public void enableVertexProgram(GL2 gl, int program) {
    gl.glBindProgramARB(GL2.GL_VERTEX_PROGRAM_ARB, program);
    gl.glEnable(GL2.GL_VERTEX_PROGRAM_ARB);
  }

  public void enableFragmentProgram(GL2 gl, int program) {
    gl.glBindProgramARB(GL2.GL_FRAGMENT_PROGRAM_ARB, program);
    gl.glEnable(GL2.GL_FRAGMENT_PROGRAM_ARB);
  }

  public void disableVertexProgram(GL2 gl) {
    gl.glDisable(GL2.GL_VERTEX_PROGRAM_ARB);
  }

  public void disableFragmentProgram(GL2 gl) {
    gl.glDisable(GL2.GL_FRAGMENT_PROGRAM_ARB);
  }

  public int getNamedParameter(int program, String name) {
    throw new RuntimeException("Not supported");
  }

  public void setVertexProgramParameter1f(GL2 gl, int param, float val) {
    if (param < 0) return;
    gl.glProgramLocalParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, param, val, 0, 0, 0);
  }

  public void setVertexProgramParameter3f(GL2 gl, int param, float x, float y, float z) {
    if (param < 0) return;
    gl.glProgramLocalParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, param, x, y, z, 0);
  }

  public void setVertexProgramParameter4f(GL2 gl, int param, float x, float y, float z, float w) {
    if (param < 0) return;
    gl.glProgramLocalParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, param, x, y, z, w);
  }

  public void setFragmentProgramParameter1f(GL2 gl, int param, float val) {
    if (param < 0) return;
    gl.glProgramLocalParameter4fARB(GL2.GL_FRAGMENT_PROGRAM_ARB, param, val, 0, 0, 0);
  }

  public void setFragmentProgramParameter3f(GL2 gl, int param, float x, float y, float z) {
    if (param < 0) return;
    gl.glProgramLocalParameter4fARB(GL2.GL_FRAGMENT_PROGRAM_ARB, param, x, y, z, 0);
  }

  public void setFragmentProgramParameter4f(GL2 gl, int param, float x, float y, float z, float w) {
    if (param < 0) return;
    gl.glProgramLocalParameter4fARB(GL2.GL_FRAGMENT_PROGRAM_ARB, param, x, y, z, w);
  }

  public void trackModelViewProjectionMatrix(GL2 gl, int param) {
    float[] modelView  = new float[16];
    float[] projection = new float[16];
    float[] mvp        = new float[16];

    // Get matrices
    gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX, projection, 0);
    gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, modelView, 0);
    // Multiply together
    for (int i = 0; i < 4; i++) {
      for (int j = 0; j < 4; j++) {
        float sum = 0;
        for (int k = 0; k < 4; k++) {
          sum += modelView[4 * i + k] * projection[4 * k + j];
        }
        mvp[4 * i + j] = sum;
      }
    }

    setMatrixParameterfc(gl, param, mvp);
  }
  
  public void setMatrixParameterfc(GL2 gl, int param, float[] matrix) {
    // Correct for row-major vs. column-major differences
    for (int i = 0; i < 4; i++) {
      gl.glProgramLocalParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, param + i, matrix[i],  matrix[4+i],  matrix[8+i],  matrix[12+i]);
    }
  }
}