mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-01-25 15:13:48 +08:00
test program for GL_MESA_program_debug extension
This commit is contained in:
parent
08ff059f20
commit
5366b01d86
350
progs/tests/debugger.c
Normal file
350
progs/tests/debugger.c
Normal file
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Test the GL_MESA_program_debug extension
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/glut.h>
|
||||
|
||||
|
||||
|
||||
static const GLubyte *
|
||||
find_line_column(const GLubyte *string, const GLubyte *pos,
|
||||
GLint *line, GLint *col)
|
||||
{
|
||||
const GLubyte *lineStart = string;
|
||||
const GLubyte *p = string;
|
||||
GLubyte *s;
|
||||
int len;
|
||||
|
||||
*line = 1;
|
||||
|
||||
while (p != pos) {
|
||||
if (*p == (GLubyte) '\n') {
|
||||
(*line)++;
|
||||
lineStart = p + 1;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
*col = (pos - lineStart) + 1;
|
||||
|
||||
/* return copy of this line */
|
||||
while (*p != 0 && *p != '\n')
|
||||
p++;
|
||||
len = p - lineStart;
|
||||
s = (GLubyte *) malloc(len + 1);
|
||||
memcpy(s, lineStart, len);
|
||||
s[len] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void Debugger(GLenum target, GLvoid *data)
|
||||
{
|
||||
GLint pos;
|
||||
const GLubyte *ln;
|
||||
GLint line, column;
|
||||
GLfloat v[4];
|
||||
|
||||
assert(target == GL_FRAGMENT_PROGRAM_NV);
|
||||
|
||||
glGetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos);
|
||||
|
||||
ln = find_line_column((const GLubyte *) data, (const GLubyte *) data + pos,
|
||||
&line, &column);
|
||||
printf("%d:%d: %s\n", line, column, (char *) ln);
|
||||
|
||||
glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
|
||||
2, (const GLubyte *) "R0", v);
|
||||
printf(" R0 = %g, %g, %g, %g\n", v[0], v[1], v[2], v[3]);
|
||||
glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
|
||||
7, (const GLubyte *) "f[WPOS]", v);
|
||||
printf(" o[WPOS] = %g, %g, %g, %g\n", v[0], v[1], v[2], v[3]);
|
||||
glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
|
||||
7, (const GLubyte *) "o[COLR]", v);
|
||||
printf(" o[COLR] = %g, %g, %g, %g\n", v[0], v[1], v[2], v[3]);
|
||||
|
||||
free((void *) ln);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
static GLfloat Diffuse[4] = { 0.5, 0.5, 1.0, 1.0 };
|
||||
static GLfloat Specular[4] = { 0.8, 0.8, 0.8, 1.0 };
|
||||
static GLfloat LightPos[4] = { 0.0, 10.0, 20.0, 1.0 };
|
||||
static GLfloat Delta = 1.0;
|
||||
|
||||
static GLuint FragProg;
|
||||
static GLuint VertProg;
|
||||
static GLboolean Anim = GL_TRUE;
|
||||
static GLboolean Wire = GL_FALSE;
|
||||
static GLboolean PixelLight = GL_TRUE;
|
||||
|
||||
static GLfloat Xrot = 0, Yrot = 0;
|
||||
|
||||
|
||||
#define NAMED_PARAMETER4FV(prog, name, v) \
|
||||
glProgramNamedParameter4fvNV(prog, strlen(name), (const GLubyte *) name, v)
|
||||
|
||||
|
||||
static void Display( void )
|
||||
{
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
if (PixelLight) {
|
||||
NAMED_PARAMETER4FV(FragProg, "LightPos", LightPos);
|
||||
glEnable(GL_FRAGMENT_PROGRAM_NV);
|
||||
glEnable(GL_VERTEX_PROGRAM_NV);
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
else {
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
|
||||
glDisable(GL_FRAGMENT_PROGRAM_NV);
|
||||
glDisable(GL_VERTEX_PROGRAM_NV);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(Xrot, 1, 0, 0);
|
||||
glRotatef(Yrot, 0, 1, 0);
|
||||
|
||||
#if 1
|
||||
glutSolidSphere(2.0, 10, 5);
|
||||
#else
|
||||
{
|
||||
GLUquadricObj *q = gluNewQuadric();
|
||||
gluQuadricNormals(q, GL_SMOOTH);
|
||||
gluQuadricTexture(q, GL_TRUE);
|
||||
glRotatef(90, 1, 0, 0);
|
||||
glTranslatef(0, 0, -1);
|
||||
gluCylinder(q, 1.0, 1.0, 2.0, 24, 1);
|
||||
gluDeleteQuadric(q);
|
||||
}
|
||||
#endif
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void Idle(void)
|
||||
{
|
||||
LightPos[0] += Delta;
|
||||
if (LightPos[0] > 25.0)
|
||||
Delta = -1.0;
|
||||
else if (LightPos[0] <- 25.0)
|
||||
Delta = 1.0;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void Reshape( int width, int height )
|
||||
{
|
||||
glViewport( 0, 0, width, height );
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
|
||||
/*glOrtho( -2.0, 2.0, -2.0, 2.0, 5.0, 25.0 );*/
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
glTranslatef( 0.0, 0.0, -15.0 );
|
||||
}
|
||||
|
||||
|
||||
static void Key( unsigned char key, int x, int y )
|
||||
{
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (key) {
|
||||
case ' ':
|
||||
Anim = !Anim;
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 'x':
|
||||
LightPos[0] -= 1.0;
|
||||
break;
|
||||
case 'X':
|
||||
LightPos[0] += 1.0;
|
||||
break;
|
||||
case 'w':
|
||||
Wire = !Wire;
|
||||
if (Wire)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
break;
|
||||
case 'p':
|
||||
PixelLight = !PixelLight;
|
||||
if (PixelLight) {
|
||||
printf("Per-pixel lighting\n");
|
||||
}
|
||||
else {
|
||||
printf("Conventional lighting\n");
|
||||
}
|
||||
break;
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void SpecialKey( int key, int x, int y )
|
||||
{
|
||||
const GLfloat step = 3.0;
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (key) {
|
||||
case GLUT_KEY_UP:
|
||||
Xrot -= step;
|
||||
break;
|
||||
case GLUT_KEY_DOWN:
|
||||
Xrot += step;
|
||||
break;
|
||||
case GLUT_KEY_LEFT:
|
||||
Yrot -= step;
|
||||
break;
|
||||
case GLUT_KEY_RIGHT:
|
||||
Yrot += step;
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void Init( void )
|
||||
{
|
||||
static const char *fragProgramText =
|
||||
"!!FP1.0\n"
|
||||
"DECLARE Diffuse; \n"
|
||||
"DECLARE Specular; \n"
|
||||
"DECLARE LightPos; \n"
|
||||
|
||||
"# Compute normalized LightPos, put it in R0\n"
|
||||
"DP3 R0.x, LightPos, LightPos;\n"
|
||||
"RSQ R0.y, R0.x;\n"
|
||||
"MUL R0, LightPos, R0.y;\n"
|
||||
|
||||
"# Compute normalized normal, put it in R1\n"
|
||||
"DP3 R1, f[TEX0], f[TEX0]; \n"
|
||||
"RSQ R1.y, R1.x;\n"
|
||||
"MUL R1, f[TEX0], R1.y;\n"
|
||||
|
||||
"# Compute dot product of light direction and normal vector\n"
|
||||
"DP3 R2, R0, R1;\n"
|
||||
|
||||
"MUL R3, Diffuse, R2; # diffuse attenuation\n"
|
||||
|
||||
"POW R4, R2.x, {20.0}.x; # specular exponent\n"
|
||||
|
||||
"MUL R5, Specular, R4; # specular attenuation\n"
|
||||
|
||||
"ADD o[COLR], R3, R5; # add diffuse and specular colors\n"
|
||||
"END \n"
|
||||
;
|
||||
|
||||
static const char *vertProgramText =
|
||||
"!!VP1.0\n"
|
||||
"# typical modelview/projection transform\n"
|
||||
"DP4 o[HPOS].x, c[0], v[OPOS] ;\n"
|
||||
"DP4 o[HPOS].y, c[1], v[OPOS] ;\n"
|
||||
"DP4 o[HPOS].z, c[2], v[OPOS] ;\n"
|
||||
"DP4 o[HPOS].w, c[3], v[OPOS] ;\n"
|
||||
"# transform normal by inv transpose of modelview, put in tex0\n"
|
||||
"DP4 o[TEX0].x, c[4], v[NRML] ;\n"
|
||||
"DP4 o[TEX0].y, c[5], v[NRML] ;\n"
|
||||
"DP4 o[TEX0].z, c[6], v[NRML] ;\n"
|
||||
"DP4 o[TEX0].w, c[7], v[NRML] ;\n"
|
||||
"END\n";
|
||||
;
|
||||
|
||||
if (!glutExtensionSupported("GL_NV_vertex_program")) {
|
||||
printf("Sorry, this demo requires GL_NV_vertex_program\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!glutExtensionSupported("GL_NV_fragment_program")) {
|
||||
printf("Sorry, this demo requires GL_NV_fragment_program\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glGenProgramsNV(1, &FragProg);
|
||||
assert(FragProg > 0);
|
||||
glGenProgramsNV(1, &VertProg);
|
||||
assert(VertProg > 0);
|
||||
|
||||
/*
|
||||
* Fragment program
|
||||
*/
|
||||
glLoadProgramNV(GL_FRAGMENT_PROGRAM_NV, FragProg,
|
||||
strlen(fragProgramText),
|
||||
(const GLubyte *) fragProgramText);
|
||||
assert(glIsProgramNV(FragProg));
|
||||
glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, FragProg);
|
||||
|
||||
NAMED_PARAMETER4FV(FragProg, "Diffuse", Diffuse);
|
||||
NAMED_PARAMETER4FV(FragProg, "Specular", Specular);
|
||||
|
||||
/*
|
||||
* Vertex program
|
||||
*/
|
||||
glLoadProgramNV(GL_VERTEX_PROGRAM_NV, VertProg,
|
||||
strlen(vertProgramText),
|
||||
(const GLubyte *) vertProgramText);
|
||||
assert(glIsProgramNV(VertProg));
|
||||
glBindProgramNV(GL_VERTEX_PROGRAM_NV, VertProg);
|
||||
glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
|
||||
glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV);
|
||||
|
||||
/*
|
||||
* Misc init
|
||||
*/
|
||||
glClearColor(0.3, 0.3, 0.3, 0.0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_LIGHTING);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0);
|
||||
|
||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||
printf("Press p to toggle between per-pixel and per-vertex lighting\n");
|
||||
|
||||
#ifdef GL_MESA_program_debug
|
||||
glProgramCallbackMESA(GL_FRAGMENT_PROGRAM_ARB, Debugger,
|
||||
(GLvoid *) fragProgramText);
|
||||
glEnable(GL_FRAGMENT_PROGRAM_CALLBACK_MESA);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
glutInit( &argc, argv );
|
||||
glutInitWindowPosition( 0, 0 );
|
||||
glutInitWindowSize( 200, 200 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
|
||||
glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc( Reshape );
|
||||
glutKeyboardFunc( Key );
|
||||
glutSpecialFunc( SpecialKey );
|
||||
glutDisplayFunc( Display );
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
Init();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user