I use jogl to read the two fragment programs. It seems the simple fragment program can pass the native resource limit test. However, the more complicated fragment program can not pass the native resource limits test. Can someone give me some suggestions on the error causation and work around? If I use C and OpenGL, both of the fragment programs work all right. What the “native resource limits” means in Jogl?
Hopefully, Ken can give me certain input on this.
Thanks.
I post my jogl testing code and the two fragment programs below,
/************** Jogl testing code ****************/
// profile = GL.GL_FRAGMENT_PROGRAM_ARB
// FileUtils as given in the jogl.demo.util
private int loadProgram(GL gl, int profile) throws IOException {
String fileNm = “isosurface_sm3.fp”;
FileInputStream in;
fileNm = “VolumeRenderPyramidF.ocg”;
in = new FileInputStream(fileNm);
String programBuffer = FileUtils.loadStreamIntoString(in);
int[] tmpInt = new int[1];
gl.glGenProgramsARB(1, tmpInt, 0);
int res = tmpInt[0];
gl.glBindProgramARB(profile, res);
gl.glProgramStringARB(profile, GL.GL_PROGRAM_FORMAT_ASCII_ARB,
programBuffer.length(), programBuffer);
int[] errPos = new int[1];
gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0);
if (errPos[0] >= 0) {
String kind = "Program";
if (profile == GL.GL_VERTEX_PROGRAM_ARB) {
kind = "Vertex program";
}
else if (profile == GL.GL_FRAGMENT_PROGRAM_ARB) {
kind = "Fragment program";
}
System.out.println(kind + " failed to load:");
String errMsg = gl.glGetString(GL.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 == GL.GL_FRAGMENT_PROGRAM_ARB) {
int[] isNative = new int[1];
gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB,
GL.GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB,
isNative, 0);
if (isNative[0] != 1) {
/******************************* Native limit test *******************/
System.out.println(
"WARNING: fragment program is over native resource limits");
Thread.dumpStack();
}
}
}
return res;
}
/***** simple fragment code: “VolumeRenderPyramidF.ocg” ****************************/
!!FP1.0
NV_fragment_program generated by NVIDIA Cg compiler
cgc version 1.1.0003, build date Mar 4 2003 12:32:10
command line args: -q -profile fp30 -entry FragmentProgram
#vendor NVIDIA Corporation
#version 1.0.02
#profile fp30
#program FragmentProgram
#semantic FragmentProgram.USTexture
#semantic FragmentProgram.ColorMap
#var float4 inTex : $vin.TEXCOORD0 : TEXCOORD0 : 0 : 1
#var float4 sColor0 : $vout.COLOR0 : COLOR0 : 1 : 1
#var sampler3D USTexture : : texunit 0 : 2 : 1
#var sampler1D ColorMap : : texunit 1 : 3 : 1
MOVX H0, f[TEX0];
MULX H0.z, H0.z, H0.w;
TXP R0, H0, TEX0, 3D;
TEX o[COLR], R0.x, TEX1, 1D;
If you get artifacts, try this instead:
MOVR R0, f[TEX0];
MULR R0.z, R0.z, R0.w;
TXP R0, R0, TEX0, 3D;
TEX o[COLR], R0.x, TEX1, 1D;
END
4 instructions, 1 R-regs, 1 H-regs.
End of program
/*** complicated fragment program: isosurface_sm3.fp *************************/
!!ARBfp1.0
OPTION NV_fragment_program2;
Filename: volume_sm3.fp
#! VOLUME = 0
#! TRANSFERFUNCTION = 1
#! BACKGROUND = 2
r = step
g = gradient scale
b = gradient offset
a = z-value of background plane
PARAM params = program.local[0];
r = texture coordinate scale
g = number of iterations
b = isovalue of isosurface
PARAM params2 = program.local[1];
PARAM center = program.local[2];
PARAM texMax = program.local[3];
PARAM scaleFactors = program.local[5];
TEMP geomDir;
TEMP geomPos;
TEMP texblen;
TEMP diffVec;
TEMP scalar;
TEMP camera;
TEMP normal;
TEMP temp1;
TEMP temp2;
TEMP temp;
TEMP pos;
TEMP src;
TEMP dst;
TEMP dir;
TEMP tex;
Compute the ray’s starting point
MOV geomPos, fragment.texcoord[0];
MUL pos, geomPos, scaleFactors;
MOV pos.a, 0.0;
Compute the camera position by translating the origin to the center of the
volume
MOV camera, state.matrix.modelview.invtrans.row[3];
Compute the ray direction
SUB geomDir, geomPos, camera;
Normalize the direction (done manually instead of with NRM to improve
accuracy)
DP3 geomDir.w, geomDir, geomDir;
RSQ geomDir.w, geomDir.w;
MUL geomDir, geomDir, geomDir.w;
MOV geomDir.w, 0.0;
MUL dir, geomDir, scaleFactors;
Initialize scalar value
RGB = gradient, alpha = scalar value
TXL scalar, pos, texture[0], 3D;
MOV scalar.g, scalar.a;
MOV scalar.a, 0.0;
Initialize destination color
MOV dst, 0.0;
Move one step forward
MAD pos, dir, params.r, pos;
REP params2.g;
REP params2.g;
# Lookup new scalar value
TXL tex, pos, texture[0], 3D;
MOV scalar.r, tex.a;
# Lookup color in pre-int texture
TXL src, scalar, texture[1], 2D;
# TODO Early ray termination (no gain of speed so far)
#SUBC texblen.r, 1.0, dst.a;
#BRK (LE.x);
# Perform blending
SUB texblen.r, 1.0, dst.a;
MAD_SAT dst, src, texblen.r, dst;
# Move one step forward
MAD pos, dir, params.r, pos;
# Terminate loop if outside volume
SGE temp1, pos, 0.0;
SLE temp2, pos, texMax;
DP3 temp1.r, temp1, temp2;
SEQC temp1.r, temp1.r, 3.0;
BRK (EQ.x);
# Save current scalar value
MOV scalar.g, scalar.r;
ENDREP;
BRK (LE.x);
ENDREP;
Compute the normal of the background plane (this is just the negative view
direction which initially is (0, 0, -1))
MOV normal, state.matrix.modelview.row[2];
Compute the plane constant (we want the plane to be located in the volume
center)
DP3 temp1.r, normal, center;
Move the plane behind the volume: d’ = <n,(x - l n)> = <n, x> - l <n, n>;
l = 0.71 is chosen since it is greater than half the cube diagonal
DP3 temp1.g, normal, normal;
MAD temp1.r, temp1.g, -.71, temp1.r;
Compute ray parameter
DP3 temp1.g, normal, geomPos;
SUB temp1.g, temp1.r, temp1.g;
DP3 temp1.b, normal, geomDir;
DIV temp.r, temp1.g, temp1.b;
Compute ray/plane intersection
MAD temp.rgb, temp.r, geomDir, geomPos;
Compute the difference vector
SUB diffVec, temp, center;
Compute the texture coordinates
DP3 temp.r, diffVec, state.matrix.modelview.row[0];
DP3 temp.g, diffVec, state.matrix.modelview.row[1];
MUL temp.rg, temp, params2.r;
Center background image
ADD temp.rg, temp, .5;
Look up the texel value
TEX temp.rgb, temp, texture[2], 2D;
MOV temp.a, 1.0;
Blend the background pixel
SUB texblen, 1.0, dst.a;
MAD dst, temp, texblen.x, dst;
Write the output color
MOV result.color, dst;
END