summaryrefslogtreecommitdiffstats
path: root/progs
diff options
context:
space:
mode:
authormichal <michal@michal-laptop.(none)>2007-07-06 17:53:44 +0200
committermichal <michal@michal-laptop.(none)>2007-07-06 17:53:44 +0200
commit3b8bc1f46758d4da9155419fcf558a493e729501 (patch)
tree0dbfb4ae1ed6b49caaed3e662b27db30fe2e8801 /progs
parentffe58739da9eee2e99682747cc8f26e412c87430 (diff)
parentffa2659204121f703208782ff225a22e0c21b173 (diff)
downloadexternal_mesa3d-3b8bc1f46758d4da9155419fcf558a493e729501.zip
external_mesa3d-3b8bc1f46758d4da9155419fcf558a493e729501.tar.gz
external_mesa3d-3b8bc1f46758d4da9155419fcf558a493e729501.tar.bz2
Merge branch 'master' of git+ssh://michal@git.freedesktop.org/git/mesa/mesa into softpipe_0_1_branch
Diffstat (limited to 'progs')
-rw-r--r--progs/demos/shadowtex.c311
-rw-r--r--progs/demos/spriteblast.c22
-rw-r--r--progs/fbdev/glfbdevtest.c105
-rw-r--r--progs/tests/Makefile8
-rw-r--r--progs/tests/arraytexture.c337
-rw-r--r--progs/tests/drawbuffers.c21
-rw-r--r--progs/tests/random.c457
-rw-r--r--progs/xdemos/Makefile1
-rw-r--r--progs/xdemos/texture_from_pixmap.c396
9 files changed, 1580 insertions, 78 deletions
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
index b11c6f5..59253e8 100644
--- a/progs/demos/shadowtex.c
+++ b/progs/demos/shadowtex.c
@@ -9,6 +9,7 @@
* Added GL_EXT_packed_depth_stencil support on 15 March 2006.
* Added GL_EXT_framebuffer_object support on 27 March 2006.
* Removed old SGIX extension support on 5 April 2006.
+ * Added vertex / fragment program support on 7 June 2007 (Ian Romanick).
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
@@ -34,6 +35,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <math.h>
#include <GL/glut.h>
#include "showbuffer.h"
@@ -67,8 +69,27 @@ static GLboolean NeedNewShadowMap = GL_FALSE;
static GLuint ShadowTexture, GrayTexture;
static GLuint ShadowFBO;
+static GLfloat lightModelview[16];
+static GLfloat lightProjection[16];
+
+static GLuint vert_prog;
+static GLuint frag_progs[3];
+static GLuint curr_frag = 0;
+static GLuint max_frag = 1;
+
+#define NUM_FRAG_MODES 3
+static const char *FragProgNames[] = {
+ "fixed-function",
+ "program without \"OPTION ARB_fragment_program_shadow\"",
+ "program with \"OPTION ARB_fragment_program_shadow\"",
+};
+
static GLboolean HaveFBO = GL_FALSE;
static GLboolean UseFBO = GL_FALSE;
+static GLboolean HaveVP = GL_FALSE;
+static GLboolean HaveFP = GL_FALSE;
+static GLboolean HaveFP_Shadow = GL_FALSE;
+static GLboolean UseVP = GL_FALSE;
static GLboolean HavePackedDepthStencil = GL_FALSE;
static GLboolean UsePackedDepthStencil = GL_FALSE;
static GLboolean HaveEXTshadowFuncs = GL_FALSE;
@@ -91,6 +112,103 @@ static GLuint DisplayMode;
+#define MAT4_MUL(dest_vec, src_mat, src_vec) \
+ "DP4 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
+ "DP4 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
+ "DP4 " dest_vec ".z, " src_mat "[2], " src_vec ";\n" \
+ "DP4 " dest_vec ".w, " src_mat "[3], " src_vec ";\n"
+
+#define MAT3_MUL(dest_vec, src_mat, src_vec) \
+ "DP3 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
+ "DP3 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
+ "DP3 " dest_vec ".z, " src_mat "[2], " src_vec ";\n"
+
+#define NORMALIZE(dest, src) \
+ "DP3 " dest ".w, " src ", " src ";\n" \
+ "RSQ " dest ".w, " dest ".w;\n" \
+ "MUL " dest ", " src ", " dest ".w;\n"
+
+/**
+ * Vertex program for shadow mapping.
+ */
+static const char vert_code[] =
+ "!!ARBvp1.0\n"
+ "ATTRIB iPos = vertex.position;\n"
+ "ATTRIB iNorm = vertex.normal;\n"
+
+ "PARAM mvinv[4] = { state.matrix.modelview.invtrans };\n"
+ "PARAM mvp[4] = { state.matrix.mvp };\n"
+ "PARAM mv[4] = { state.matrix.modelview };\n"
+ "PARAM texmat[4] = { state.matrix.texture[0] };\n"
+ "PARAM lightPos = state.light[0].position;\n"
+ "PARAM ambientCol = state.lightprod[0].ambient;\n"
+ "PARAM diffuseCol = state.lightprod[0].diffuse;\n"
+
+ "TEMP n, lightVec;\n"
+ "ALIAS V = lightVec;\n"
+ "ALIAS NdotL = n;\n"
+
+ "OUTPUT oPos = result.position;\n"
+ "OUTPUT oColor = result.color;\n"
+ "OUTPUT oTex = result.texcoord[0];\n"
+
+ /* Transform the vertex to clip coordinates. */
+ MAT4_MUL("oPos", "mvp", "iPos")
+
+ /* Transform the vertex to eye coordinates. */
+ MAT4_MUL("V", "mv", "iPos")
+
+ /* Transform the vertex to projected light coordinates. */
+ MAT4_MUL("oTex", "texmat", "iPos")
+
+ /* Transform the normal to eye coordinates. */
+ MAT3_MUL("n", "mvinv", "iNorm")
+
+ /* Calculate the vector from the vertex to the light in eye
+ * coordinates.
+ */
+ "SUB lightVec, lightPos, V;\n"
+ NORMALIZE("lightVec", "lightVec")
+
+ /* Compute diffuse lighting coefficient.
+ */
+ "DP3 NdotL.x, n, lightVec;\n"
+ "MAX NdotL.x, NdotL.x, {0.0};\n"
+ "MIN NdotL.x, NdotL.x, {1.0};\n"
+
+ /* Accumulate color contributions.
+ */
+ "MOV oColor, diffuseCol;\n"
+ "MAD oColor.xyz, NdotL.x, diffuseCol, ambientCol;\n"
+ "END\n"
+ ;
+
+static const char frag_code[] =
+ "!!ARBfp1.0\n"
+
+ "TEMP shadow, temp;\n"
+
+ "TXP shadow, fragment.texcoord[0], texture[0], 2D;\n"
+ "RCP temp.x, fragment.texcoord[0].w;\n"
+ "MUL temp.x, temp.x, fragment.texcoord[0].z;\n"
+ "SGE shadow, shadow.x, temp.x;\n"
+ "MUL result.color.rgb, fragment.color, shadow.x;\n"
+ "MOV result.color.a, fragment.color;\n"
+ "END\n"
+ ;
+
+static const char frag_shadow_code[] =
+ "!!ARBfp1.0\n"
+ "OPTION ARB_fragment_program_shadow;\n"
+
+ "TEMP shadow;\n"
+
+ "TXP shadow, fragment.texcoord[0], texture[0], SHADOW2D;\n"
+ "MUL result.color.rgb, fragment.color, shadow.x;\n"
+ "MOV result.color.a, fragment.color.a;\n"
+ "END\n"
+ ;
+
static void
DrawScene(void)
{
@@ -134,27 +252,56 @@ DrawScene(void)
}
-/*
- * Load the GL_TEXTURE matrix with the projection from the light
- * source's point of view.
+/**
+ * Calculate modelview and project matrices for the light
+ *
+ * Stores the results in \c lightProjection (projection matrix) and
+ * \c lightModelview (modelview matrix).
*/
static void
MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3],
GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar)
{
- GLfloat d;
-
- glMatrixMode(GL_TEXTURE);
+ /* compute frustum to enclose spot light cone */
+ const GLfloat d = shadowNear * tan(spotAngle);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
glLoadIdentity();
- glTranslatef(0.5, 0.5, 0.5 + Bias);
- glScalef(0.5, 0.5, 0.5);
- d = shadowNear * tan(spotAngle);
glFrustum(-d, d, -d, d, shadowNear, shadowFar);
+ glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
gluLookAt(lightPos[0], lightPos[1], lightPos[2],
lightPos[0] + spotDir[0],
lightPos[1] + spotDir[1],
lightPos[2] + spotDir[2],
- 0, 1, 0);
+ 0.0, 1.0, 0.0);
+ glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);
+ glPopMatrix();
+}
+
+
+/**
+ * Load \c GL_TEXTURE matrix with light's MVP matrix.
+ */
+static void SetShadowTextureMatrix(void)
+{
+ static const GLfloat biasMatrix[16] = {
+ 0.5, 0.0, 0.0, 0.0,
+ 0.0, 0.5, 0.0, 0.0,
+ 0.0, 0.0, 0.5, 0.0,
+ 0.5, 0.5, 0.5, 1.0,
+ };
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadMatrixf(biasMatrix);
+ glTranslatef(0.0, 0.0, Bias);
+ glMultMatrixf(lightProjection);
+ glMultMatrixf(lightModelview);
glMatrixMode(GL_MODELVIEW);
}
@@ -258,7 +405,6 @@ RenderShadowMap(void)
{
GLenum depthFormat; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */
GLenum depthType; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */
- float d;
if (WindowWidth >= 1024 && WindowHeight >= 1024) {
ShadowTexWidth = ShadowTexHeight = 1024;
@@ -283,17 +429,11 @@ RenderShadowMap(void)
depthType = GL_UNSIGNED_INT;
}
- /* compute frustum to enclose spot light cone */
- d = ShadowNear * tan(SpotAngle);
-
glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-d, d, -d, d, ShadowNear, ShadowFar);
+ glLoadMatrixf(lightProjection);
+
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(LightPos[0], LightPos[1], LightPos[2], /* from */
- 0, 0, 0, /* target */
- 0, 1, 0); /* up */
+ glLoadMatrixf(lightModelview);
if (UseFBO) {
GLenum fbo_status;
@@ -389,10 +529,8 @@ ShowShadowMap(void)
DisableTexgen();
/* interpret texture's depth values as luminance values */
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
-#endif
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_POLYGON);
@@ -420,6 +558,7 @@ Display(void)
LightPos, SpotDir);
if (NeedNewShadowMap) {
+ MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
RenderShadowMap();
NeedNewShadowMap = GL_FALSE;
}
@@ -457,12 +596,11 @@ Display(void)
}
if (DisplayMode == SHOW_DEPTH_MAPPING) {
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
-#endif
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
+
+ SetShadowTextureMatrix();
EnableIdentityTexgen();
}
else if (DisplayMode == SHOW_DISTANCE) {
@@ -476,20 +614,42 @@ Display(void)
}
else {
assert(DisplayMode == SHOW_SHADOWS);
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
-#endif
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ if (curr_frag > 0) {
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+ else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ }
glEnable(GL_TEXTURE_2D);
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
- EnableIdentityTexgen();
+
+ SetShadowTextureMatrix();
+
+ if (UseVP) {
+ glEnable(GL_VERTEX_PROGRAM_ARB);
+ }
+ else {
+ glEnable(GL_LIGHTING);
+ EnableIdentityTexgen();
+ }
}
DrawScene();
- DisableTexgen();
- glDisable(GL_TEXTURE_1D);
+ if (UseVP) {
+ glDisable(GL_VERTEX_PROGRAM_ARB);
+ }
+ else {
+ DisableTexgen();
+ glDisable(GL_LIGHTING);
+ }
+
+ if (curr_frag > 0) {
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+
glDisable(GL_TEXTURE_2D);
}
@@ -561,6 +721,14 @@ Key(unsigned char key, int x, int y)
case 'm':
DisplayMode = SHOW_DEPTH_MAPPING;
break;
+ case 'M':
+ curr_frag = (1 + curr_frag) % max_frag;
+ printf("Using fragment %s\n", FragProgNames[curr_frag]);
+
+ if (HaveFP) {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
+ }
+ break;
case 'n':
case 's':
case ' ':
@@ -572,10 +740,8 @@ Key(unsigned char key, int x, int y)
if (Operator >= 8)
Operator = 0;
printf("Operator: %s\n", OperatorName[Operator]);
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
OperatorFunc[Operator]);
-#endif
}
break;
case 'p':
@@ -592,6 +758,11 @@ Key(unsigned char key, int x, int y)
NeedNewShadowMap = GL_TRUE;
}
break;
+ case 'v':
+ UseVP = !UseVP && HaveVP;
+ printf("Using vertex %s mode.\n",
+ UseVP ? "program" : "fixed-function");
+ break;
case 'z':
Zrot -= step;
break;
@@ -646,28 +817,62 @@ SpecialKey(int key, int x, int y)
}
+/* A helper for finding errors in program strings */
+static int FindLine( const char *program, int position )
+{
+ int i, line = 1;
+ for (i = 0; i < position; i++) {
+ if (program[i] == '\n')
+ line++;
+ }
+ return line;
+}
+
+
+static GLuint
+compile_program(GLenum target, const char *code)
+{
+ GLuint p;
+ GLint errorPos;
+
+
+ glGenProgramsARB(1, & p);
+
+ glBindProgramARB(target, p);
+ glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(code), code);
+ glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
+ if (glGetError() != GL_NO_ERROR || errorPos != -1) {
+ int l = FindLine(code, errorPos);
+ printf("Fragment Program Error (pos=%d line=%d): %s\n", errorPos, l,
+ (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
+ exit(0);
+ }
+
+ glBindProgramARB(target, 0);
+ return p;
+}
+
static void
Init(void)
{
static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0};
-#if defined(GL_ARB_depth_texture) && defined(GL_ARB_shadow)
if (!glutExtensionSupported("GL_ARB_depth_texture") ||
!glutExtensionSupported("GL_ARB_shadow")) {
-#else
- if (1) {
-#endif
printf("Sorry, this demo requires the GL_ARB_depth_texture and GL_ARB_shadow extensions\n");
exit(1);
}
printf("Using GL_ARB_depth_texture and GL_ARB_shadow\n");
-#if defined(GL_ARB_shadow_ambient)
+ HaveVP = glutExtensionSupported("GL_ARB_vertex_program");
+ HaveFP = glutExtensionSupported("GL_ARB_fragment_program");
+ HaveFP_Shadow = glutExtensionSupported("GL_ARB_fragment_program_shadow");
+
HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient");
if (HaveShadowAmbient) {
printf("and GL_ARB_shadow_ambient\n");
}
-#endif
HaveEXTshadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
@@ -690,15 +895,12 @@ Init(void)
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-#if defined(GL_ARB_shadow)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
-#endif
+
if (HaveShadowAmbient) {
-#if defined(GL_ARB_shadow_ambient)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
-#endif
}
#if defined(GL_EXT_framebuffer_object)
@@ -733,6 +935,25 @@ Init(void)
256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
}
+ if (HaveVP) {
+ vert_prog = compile_program(GL_VERTEX_PROGRAM_ARB, vert_code);
+ glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vert_prog);
+ }
+
+ max_frag = 1;
+ frag_progs[0] = 0;
+
+ if (HaveFP) {
+ frag_progs[1] = compile_program(GL_FRAGMENT_PROGRAM_ARB, frag_code);
+ max_frag = 2;
+ }
+
+ if (HaveFP && HaveFP_Shadow) {
+ frag_progs[2] = compile_program(GL_FRAGMENT_PROGRAM_ARB,
+ frag_shadow_code);
+ max_frag = 3;
+ }
+
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
@@ -751,6 +972,8 @@ PrintHelp(void)
printf(" f = toggle nearest/bilinear texture filtering\n");
printf(" b/B = decrease/increase shadow map Z bias\n");
printf(" p = toggle use of packed depth/stencil\n");
+ printf(" M = cycle through fragment program modes\n");
+ printf(" v = toggle vertex program modes\n");
printf(" cursor keys = rotate scene\n");
printf(" <shift> + cursor keys = rotate light source\n");
if (HaveEXTshadowFuncs)
diff --git a/progs/demos/spriteblast.c b/progs/demos/spriteblast.c
index f0d3d0d..5ad8e4d 100644
--- a/progs/demos/spriteblast.c
+++ b/progs/demos/spriteblast.c
@@ -333,13 +333,13 @@ menu(int option)
smooth = 0;
break;
case 10:
- glPointSize(4.0);
+ glPointSize(16.0);
break;
case 11:
- glPointSize(8.0);
+ glPointSize(32.0);
break;
case 12:
- glPointSize(16.0);
+ glPointSize(64.0);
break;
case 13:
spin = 1 - spin;
@@ -411,19 +411,19 @@ key(unsigned char c, int x, int y)
glutPostRedisplay();
break;
case '1':
- glPointSize(2.0);
+ glPointSize(16.0);
glutPostRedisplay();
break;
case '2':
- glPointSize(4.0);
+ glPointSize(32.0);
glutPostRedisplay();
break;
case '3':
- glPointSize(8.0);
+ glPointSize(64.0);
glutPostRedisplay();
break;
case '4':
- glPointSize(16.0);
+ glPointSize(128.0);
glutPostRedisplay();
break;
case 27:
@@ -526,9 +526,9 @@ main(int argc, char **argv)
glutAddMenuEntry("Threshold 10", 7);
glutAddMenuEntry("Point smooth on", 8);
glutAddMenuEntry("Point smooth off", 9);
- glutAddMenuEntry("Point size 4", 10);
- glutAddMenuEntry("Point size 8", 11);
- glutAddMenuEntry("Point size 16", 12);
+ glutAddMenuEntry("Point size 16", 10);
+ glutAddMenuEntry("Point size 32", 11);
+ glutAddMenuEntry("Point size 64", 12);
glutAddMenuEntry("Toggle spin", 13);
glutAddMenuEntry("200 points ", 14);
glutAddMenuEntry("500 points ", 15);
@@ -544,7 +544,7 @@ main(int argc, char **argv)
glEnable(GL_DEPTH_TEST);
glEnable(GL_POINT_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPointSize(16.0);
+ glPointSize(32.0);
#ifdef GL_ARB_point_parameters
glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, theQuad);
#endif
diff --git a/progs/fbdev/glfbdevtest.c b/progs/fbdev/glfbdevtest.c
index a461c55..6d9f807 100644
--- a/progs/fbdev/glfbdevtest.c
+++ b/progs/fbdev/glfbdevtest.c
@@ -23,11 +23,21 @@
#include <GL/glfbdev.h>
#include <math.h>
-#define DEFAULT_DEPTH 8
+
+/**
+ * Choose one of these modes
+ */
+/*static const int XRes = 1280, YRes = 1024, Hz = 75;*/
+/*static const int XRes = 1280, YRes = 1024, Hz = 70;*/
+/*static const int XRes = 1280, YRes = 1024, Hz = 60;*/
+static const int XRes = 1024, YRes = 768, Hz = 70;
+
+static int DesiredDepth = 32;
+
+static int NumFrames = 100;
static struct fb_fix_screeninfo FixedInfo;
static struct fb_var_screeninfo VarInfo, OrigVarInfo;
-static int DesiredDepth = 0;
static int OriginalVT = -1;
static int ConsoleFD = -1;
static int FrameBufferFD = -1;
@@ -227,7 +237,6 @@ initialize_fbdev( void )
VarInfo = OrigVarInfo;
/* set the depth, resolution, etc */
- DesiredDepth = 32;
if (DesiredDepth)
VarInfo.bits_per_pixel = DesiredDepth;
@@ -251,16 +260,60 @@ initialize_fbdev( void )
VarInfo.blue.length = 8;
VarInfo.transp.length = 8;
}
- /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
- VarInfo.xres_virtual = VarInfo.xres = 1280;
- VarInfo.yres_virtual = VarInfo.yres = 1024;
- VarInfo.pixclock = 7408;
- VarInfo.left_margin = 248;
- VarInfo.right_margin = 16;
- VarInfo.upper_margin = 38;
- VarInfo.lower_margin = 1;
- VarInfo.hsync_len = 144;
- VarInfo.vsync_len = 3;
+
+ /* timing values taken from /etc/fb.modes */
+ if (XRes == 1280 && YRes == 1024) {
+ VarInfo.xres_virtual = VarInfo.xres = XRes;
+ VarInfo.yres_virtual = VarInfo.yres = YRes;
+ if (Hz == 75) {
+ VarInfo.pixclock = 7408;
+ VarInfo.left_margin = 248;
+ VarInfo.right_margin = 16;
+ VarInfo.upper_margin = 38;
+ VarInfo.lower_margin = 1;
+ VarInfo.hsync_len = 144;
+ VarInfo.vsync_len = 3;
+ }
+ else if (Hz == 70) {
+ VarInfo.pixclock = 7937;
+ VarInfo.left_margin = 216;
+ VarInfo.right_margin = 80;
+ VarInfo.upper_margin = 36;
+ VarInfo.lower_margin = 1;
+ VarInfo.hsync_len = 112;
+ VarInfo.vsync_len = 5;
+ }
+ else if (Hz == 60) {
+ VarInfo.pixclock = 9260;
+ VarInfo.left_margin = 248;
+ VarInfo.right_margin = 48;
+ VarInfo.upper_margin = 38;
+ VarInfo.lower_margin = 1;
+ VarInfo.hsync_len = 112;
+ VarInfo.vsync_len = 3;
+ }
+ else {
+ fprintf(stderr, "invalid rate for 1280x1024\n");
+ exit(1);
+ }
+ }
+ else if (XRes == 1024 && YRes == 768 && Hz == 70) {
+ VarInfo.xres_virtual = VarInfo.xres = XRes;
+ VarInfo.yres_virtual = VarInfo.yres = YRes;
+ if (Hz == 70) {
+ VarInfo.pixclock = 13334;
+ VarInfo.left_margin = 144;
+ VarInfo.right_margin = 24;
+ VarInfo.upper_margin = 29;
+ VarInfo.lower_margin = 3;
+ VarInfo.hsync_len = 136;
+ VarInfo.vsync_len = 6;
+ }
+ else {
+ fprintf(stderr, "invalid rate for 1024x768\n");
+ exit(1);
+ }
+ }
VarInfo.xoffset = 0;
VarInfo.yoffset = 0;
@@ -338,7 +391,7 @@ initialize_fbdev( void )
printf("MMIOAddress = %p\n", MMIOAddress);
/* try out some simple MMIO register reads */
- if (1)
+ if (0)
{
typedef unsigned int CARD32;
typedef unsigned char CARD8;
@@ -452,6 +505,7 @@ gltest( void )
GLFBDevVisualPtr vis;
int bytes, r, g, b, a;
float ang;
+ int i;
printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
@@ -491,13 +545,17 @@ gltest( void )
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
- for (ang = 0; ang <= 180; ang += 15) {
+ printf("Drawing %d frames...\n", NumFrames);
+
+ ang = 0.0;
+ for (i = 0; i < NumFrames; i++) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(ang, 1, 0, 0);
doughnut(1, 3, 40, 20);
glPopMatrix();
glFBDevSwapBuffers(buf);
+ ang += 15.0;
}
/* clean up */
@@ -510,12 +568,29 @@ gltest( void )
}
+static void
+parse_args(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-f") == 0) {
+ NumFrames = atoi(argv[i+1]);
+ i++;
+ }
+ }
+}
+
+
int
main( int argc, char *argv[] )
{
signal(SIGUSR1, signal_handler); /* exit if someone tries a vt switch */
signal(SIGSEGV, signal_handler); /* catch segfaults */
+ parse_args(argc, argv);
+
+ printf("Setting mode to %d x %d @ %d Hz, %d bpp\n", XRes, YRes, Hz, DesiredDepth);
initialize_fbdev();
gltest();
shutdown_fbdev();
diff --git a/progs/tests/Makefile b/progs/tests/Makefile
index 9edef74..9016efe 100644
--- a/progs/tests/Makefile
+++ b/progs/tests/Makefile
@@ -23,6 +23,7 @@ SOURCES = \
arbvptest3.c \
arbvptorus.c \
arbvpwarpmesh.c \
+ arraytexture.c \
blendminmax.c \
blendsquare.c \
bufferobj.c \
@@ -54,6 +55,7 @@ SOURCES = \
pbo.c \
prog_parameter.c \
projtex.c \
+ random.c \
readrate.c \
seccolor.c \
sharedtex.c \
@@ -117,6 +119,12 @@ getprocaddress: getprocaddress.c getproclist.h
getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress.py
python getprocaddress.py > getproclist.h
+arraytexture: arraytexture.o readtex.o
+ $(CC) $(CFLAGS) arraytexture.o readtex.o $(LIBS) -o $@
+
+arraytexture.o: arraytexture.c readtex.h
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
afsmultiarb: afsmultiarb.o readtex.o
$(CC) $(CFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@
diff --git a/progs/tests/arraytexture.c b/progs/tests/arraytexture.c
new file mode 100644
index 0000000..48c622b
--- /dev/null
+++ b/progs/tests/arraytexture.c
@@ -0,0 +1,337 @@
+/*
+ * (C) Copyright IBM Corporation 2007
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * \file arraytexture.c
+ *
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+
+#if !defined(GL_EXT_texture_array) && !defined(GL_MESA_texture_array)
+# error "This demo requires enums for either GL_EXT_texture_array or GL_MESA_texture_array to build."
+#endif
+
+#include "readtex.h"
+
+#define GL_CHECK_ERROR() \
+ do { \
+ GLenum err = glGetError(); \
+ if (err) { \
+ printf("%s:%u: %s (0x%04x)\n", __FILE__, __LINE__, \
+ gluErrorString(err), err); \
+ } \
+ } while (0)
+
+static const char *const textures[] = {
+ "../images/girl.rgb",
+ "../images/girl2.rgb",
+ "../images/arch.rgb",
+ "../images/s128.rgb",
+
+ "../images/tree3.rgb",
+ "../images/bw.rgb",
+ "../images/reflect.rgb",
+ "../images/wrs_logo.rgb",
+ NULL
+};
+
+static const char frag_prog[] =
+ "!!ARBfp1.0\n"
+ "OPTION MESA_texture_array;\n"
+ "TEX result.color, fragment.texcoord[0], texture[0], ARRAY2D;\n"
+ "END\n";
+
+static GLfloat Xrot = 0, Yrot = -30, Zrot = 0;
+static GLfloat texZ = 0.0;
+static GLfloat texZ_dir = 0.01;
+static GLint num_layers;
+
+static PFNGLBINDPROGRAMARBPROC bind_program;
+static PFNGLPROGRAMSTRINGARBPROC program_string;
+static PFNGLGENPROGRAMSARBPROC gen_programs;
+
+
+static void
+PrintString(const char *s)
+{
+ while (*s) {
+ glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
+ s++;
+ }
+}
+
+
+static void Idle(void)
+{
+ static int lastTime = 0;
+ int t = glutGet(GLUT_ELAPSED_TIME);
+
+ if (lastTime == 0)
+ lastTime = t;
+ else if (t - lastTime < 10)
+ return;
+
+ lastTime = t;
+
+ texZ += texZ_dir;
+ if ((texZ < 0.0) || ((GLint) texZ > num_layers)) {
+ texZ_dir = -texZ_dir;
+ }
+
+ glutPostRedisplay();
+}
+
+
+static void Display(void)
+{
+ char str[100];
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1, 1, -1, 1, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, 0);
+ glColor3f(1,1,1);
+ glRasterPos3f(-0.9, -0.9, 0.0);
+ sprintf(str, "Texture Z coordinate = %4.1f", texZ);
+ PrintString(str);
+
+ (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, 1);
+ GL_CHECK_ERROR();
+ glEnable(GL_TEXTURE_2D_ARRAY_EXT);
+ GL_CHECK_ERROR();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -8.0);
+
+ glPushMatrix();
+ glRotatef(Xrot, 1, 0, 0);
+ glRotatef(Yrot, 0, 1, 0);
+ glRotatef(Zrot, 0, 0, 1);
+
+ glBegin(GL_QUADS);
+ glTexCoord3f(0.0, 0.0, texZ); glVertex2f(-1.0, -1.0);
+ glTexCoord3f(2.0, 0.0, texZ); glVertex2f(1.0, -1.0);
+ glTexCoord3f(2.0, 2.0, texZ); glVertex2f(1.0, 1.0);
+ glTexCoord3f(0.0, 2.0, texZ); glVertex2f(-1.0, 1.0);
+ glEnd();
+
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D_ARRAY_EXT);
+ GL_CHECK_ERROR();
+ (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, 0);
+ GL_CHECK_ERROR();
+
+ glutSwapBuffers();
+}
+
+
+static void Reshape(int width, int height)
+{
+ glViewport(0, 0, width, height);
+}
+
+
+static void Key(unsigned char key, int x, int y)
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ 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 int FindLine(const char *program, int position)
+{
+ int i, line = 1;
+ for (i = 0; i < position; i++) {
+ if (program[i] == '\n')
+ line++;
+ }
+ return line;
+}
+
+
+static void
+compile_fragment_program(GLuint id, const char *prog)
+{
+ int errorPos;
+ int err;
+
+ err = glGetError();
+ (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, id);
+ (*program_string)(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(prog), (const GLubyte *) prog);
+
+ glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
+ err = glGetError();
+ if (err != GL_NO_ERROR || errorPos != -1) {
+ int l = FindLine(prog, errorPos);
+
+ printf("Fragment Program Error (err=%d, pos=%d line=%d): %s\n",
+ err, errorPos, l,
+ (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
+ exit(0);
+ }
+}
+
+
+static void require_extension(const char *ext)
+{
+ if (!glutExtensionSupported(ext)) {
+ printf("Sorry, %s not supported by this renderer.\n", ext);
+ exit(1);
+ }
+}
+
+
+static void Init(void)
+{
+ const char *const ver_string = (const char *const) glGetString(GL_VERSION);
+ unsigned i;
+
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", ver_string);
+
+ require_extension("GL_ARB_fragment_program");
+ require_extension("GL_MESA_texture_array");
+ require_extension("GL_SGIS_generate_mipmap");
+
+ bind_program = glutGetProcAddress("glBindProgramARB");
+ program_string = glutGetProcAddress("glProgramStringARB");
+ gen_programs = glutGetProcAddress("glGenProgramsARB");
+
+
+ for (num_layers = 0; textures[num_layers] != NULL; num_layers++)
+ /* empty */ ;
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 1);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8,
+ 256, 256, num_layers, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ GL_CHECK_ERROR();
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS,
+ GL_TRUE);
+
+ for (i = 0; textures[i] != NULL; i++) {
+ GLint width, height;
+ GLenum format;
+
+ GLubyte *image = LoadRGBImage(textures[i], &width, &height, &format);
+ if (!image) {
+ printf("Error: could not load texture image %s\n", textures[i]);
+ exit(1);
+ }
+
+ /* resize to 256 x 256 */
+ if (width != 256 || height != 256) {
+ GLubyte *newImage = malloc(256 * 256 * 4);
+ gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
+ 256, 256, GL_UNSIGNED_BYTE, newImage);
+ free(image);
+ image = newImage;
+ }
+
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0,
+ 0, 0, i, 256, 256, 1,
+ format, GL_UNSIGNED_BYTE, image);
+ free(image);
+ }
+ GL_CHECK_ERROR();
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ GL_CHECK_ERROR();
+ glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ GL_CHECK_ERROR();
+
+ compile_fragment_program(1, frag_prog);
+ GL_CHECK_ERROR();
+}
+
+
+int main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(350, 350);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ glutCreateWindow("Array texture test");
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Display);
+ glutIdleFunc(Idle);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/tests/drawbuffers.c b/progs/tests/drawbuffers.c
index 8583bac..5e89569 100644
--- a/progs/tests/drawbuffers.c
+++ b/progs/tests/drawbuffers.c
@@ -19,6 +19,7 @@ static int Win;
static int Width = 400, Height = 400;
static GLuint FBobject, RBobjects[3];
static GLfloat Xrot = 0.0, Yrot = 0.0;
+static GLuint Program;
static void
@@ -40,6 +41,8 @@ Display(void)
GL_COLOR_ATTACHMENT1_EXT
};
+ glUseProgram_func(Program);
+
/* draw to user framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
@@ -71,10 +74,12 @@ Display(void)
buffer);
/* top half = colorbuffer 1 */
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
- glReadPixels(0, Height/2, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE,
- buffer + Width * Height / 2 * 4);
+ glReadPixels(0, Height/2, Width, Height - Height / 2,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ buffer + Width * (Height / 2) * 4);
/* draw to window */
+ glUseProgram_func(0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glWindowPos2iARB(0, 0);
glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
@@ -243,15 +248,15 @@ SetupShaders(void)
" gl_FragData[1] = vec4(1.0) - gl_Color; \n"
"}\n";
- GLuint fragShader, program;
+ GLuint fragShader;
fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText);
- program = glCreateProgram_func();
+ Program = glCreateProgram_func();
- glAttachShader_func(program, fragShader);
- glLinkProgram_func(program);
- CheckLink(program);
- glUseProgram_func(program);
+ glAttachShader_func(Program, fragShader);
+ glLinkProgram_func(Program);
+ CheckLink(Program);
+ glUseProgram_func(Program);
}
diff --git a/progs/tests/random.c b/progs/tests/random.c
new file mode 100644
index 0000000..d52c338
--- /dev/null
+++ b/progs/tests/random.c
@@ -0,0 +1,457 @@
+/**
+ * Random rendering, to check for crashes, hangs, etc.
+ *
+ * Brian Paul
+ * 21 June 2007
+ */
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+
+static int Win;
+static GLboolean Anim = GL_TRUE;
+static int Width = 200, Height = 200;
+static int DB = 0;
+static int MinVertexCount = 0, MaxVertexCount = 1000;
+static int Count = 0;
+
+struct vertex
+{
+ int type;
+ float v[4];
+};
+
+static int BufferSize = 10000;
+static struct vertex *Vbuffer = NULL;
+static int Vcount, Vprim;
+
+enum {
+ BEGIN,
+ END,
+ VERTEX2,
+ VERTEX3,
+ VERTEX4,
+ COLOR3,
+ COLOR4,
+ TEX2,
+ TEX3,
+ TEX4,
+ SECCOLOR3,
+ NORMAL3
+};
+
+
+
+/**
+ * This can be called from within gdb after a crash:
+ * (gdb) call ReportState()
+ */
+static void
+ReportState(void)
+{
+ static const struct {
+ GLenum token;
+ char *str;
+ GLenum type;
+ } state [] = {
+ { GL_ALPHA_TEST, "GL_ALPHA_TEST", GL_INT },
+ { GL_BLEND, "GL_BLEND", GL_INT },
+ { GL_CLIP_PLANE0, "GL_CLIP_PLANE0", GL_INT },
+ { GL_DEPTH_TEST, "GL_DEPTH_TEST", GL_INT },
+ { GL_LIGHTING, "GL_LIGHTING", GL_INT },
+ { GL_LINE_WIDTH, "GL_LINE_WIDTH", GL_FLOAT },
+ { GL_POINT_SIZE, "GL_POINT_SIZE", GL_FLOAT },
+ { GL_SHADE_MODEL, "GL_SHADE_MODEL", GL_INT },
+ { GL_SCISSOR_TEST, "GL_SCISSOR_TEST", GL_INT },
+ { 0, NULL, 0 }
+ };
+
+ GLint i;
+
+ for (i = 0; state[i].token; i++) {
+ if (state[i].type == GL_INT) {
+ GLint v;
+ glGetIntegerv(state[i].token, &v);
+ printf("%s = %d\n", state[i].str, v);
+ }
+ else {
+ GLfloat v;
+ glGetFloatv(state[i].token, &v);
+ printf("%s = %f\n", state[i].str, v);
+ }
+ }
+}
+
+static void
+PrintVertex(const char *f, const struct vertex *v, int sz)
+{
+ int i;
+ printf("%s(", f);
+ for (i = 0; i < sz; i++) {
+ printf("%g%s", v->v[i], (i == sz-1) ? "" : ", ");
+ }
+ printf(");\n");
+}
+
+/**
+ * This can be called from within gdb after a crash:
+ * (gdb) call ReportState()
+ */
+static void
+LastPrim(void)
+{
+ int i;
+ for (i = 0; i < Vcount; i++) {
+ switch (Vbuffer[i].type) {
+ case BEGIN:
+ printf("glBegin(%d);\n", (int) Vbuffer[i].v[0]);
+ break;
+ case END:
+ printf("glEnd();\n");
+ break;
+ case VERTEX2:
+ PrintVertex("glVertex2f", Vbuffer + i, 2);
+ break;
+ case VERTEX3:
+ PrintVertex("glVertex3f", Vbuffer + i, 3);
+ break;
+ case VERTEX4:
+ PrintVertex("glVertex4f", Vbuffer + i, 4);
+ break;
+ case COLOR3:
+ PrintVertex("glColor3f", Vbuffer + i, 3);
+ break;
+ case COLOR4:
+ PrintVertex("glColor4f", Vbuffer + i, 4);
+ break;
+ case TEX2:
+ PrintVertex("glTexCoord2f", Vbuffer + i, 2);
+ break;
+ case TEX3:
+ PrintVertex("glTexCoord3f", Vbuffer + i, 3);
+ break;
+ case TEX4:
+ PrintVertex("glTexCoord4f", Vbuffer + i, 4);
+ break;
+ case SECCOLOR3:
+ PrintVertex("glSecondaryColor3f", Vbuffer + i, 3);
+ break;
+ case NORMAL3:
+ PrintVertex("glNormal3f", Vbuffer + i, 3);
+ break;
+ default:
+ abort();
+ }
+ }
+}
+
+
+static int
+RandomInt(int max)
+{
+ if (max == 0)
+ return 0;
+ return rand() % max;
+}
+
+static float
+RandomFloat(float min, float max)
+{
+ int k = rand() % 10000;
+ float x = min + (max - min) * k / 10000.0;
+ return x;
+}
+
+/*
+ * Return true if random number in [0,1] is <= percentile.
+ */
+static GLboolean
+RandomChoice(float percentile)
+{
+ return RandomFloat(0.0, 1.0) <= percentile;
+}
+
+static void
+RandomStateChange(void)
+{
+ int k = RandomInt(19);
+ switch (k) {
+ case 0:
+ glEnable(GL_BLEND);
+ break;
+ case 1:
+ glDisable(GL_BLEND);
+ break;
+ case 2:
+ glEnable(GL_ALPHA_TEST);
+ break;
+ case 3:
+ glEnable(GL_ALPHA_TEST);
+ break;
+ case 4:
+ glEnable(GL_DEPTH_TEST);
+ break;
+ case 5:
+ glEnable(GL_DEPTH_TEST);
+ break;
+ case 6:
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ break;
+ case 7:
+ glPointSize(10.0);
+ break;
+ case 8:
+ glPointSize(1.0);
+ break;
+ case 9:
+ glLineWidth(10.0);
+ break;
+ case 10:
+ glLineWidth(1.0);
+ break;
+ case 11:
+ glEnable(GL_LIGHTING);
+ break;
+ case 12:
+ glDisable(GL_LIGHTING);
+ break;
+ case 13:
+ glEnable(GL_SCISSOR_TEST);
+ break;
+ case 14:
+ glDisable(GL_SCISSOR_TEST);
+ break;
+ case 15:
+ glEnable(GL_CLIP_PLANE0);
+ break;
+ case 16:
+ glDisable(GL_CLIP_PLANE0);
+ break;
+ case 17:
+ glShadeModel(GL_FLAT);
+ break;
+ case 18:
+ glShadeModel(GL_SMOOTH);
+ break;
+ }
+}
+
+
+static void
+RandomPrimitive(void)
+{
+ int i;
+ int len = MinVertexCount + RandomInt(MaxVertexCount - MinVertexCount);
+
+ Vprim = RandomInt(10);
+
+ glBegin(Vprim);
+ Vbuffer[Vcount].type = BEGIN;
+ Vbuffer[Vcount].v[0] = Vprim;
+ Vcount++;
+
+ for (i = 0; i < len; i++) {
+ Vbuffer[Vcount].v[0] = RandomFloat(-3, 3);
+ Vbuffer[Vcount].v[1] = RandomFloat(-3, 3);
+ Vbuffer[Vcount].v[2] = RandomFloat(-3, 3);
+ Vbuffer[Vcount].v[3] = RandomFloat(-3, 3);
+ int k = RandomInt(9);
+ switch (k) {
+ case 0:
+ glVertex2fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = VERTEX2;
+ break;
+ case 1:
+ glVertex3fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = VERTEX3;
+ break;
+ case 2:
+ glVertex4fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = VERTEX4;
+ break;
+ case 3:
+ glColor3fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = COLOR3;
+ break;
+ case 4:
+ glColor4fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = COLOR4;
+ break;
+ case 5:
+ glTexCoord2fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = TEX2;
+ break;
+ case 6:
+ glTexCoord3fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = TEX3;
+ break;
+ case 7:
+ glTexCoord4fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = TEX4;
+ break;
+ case 8:
+ glSecondaryColor3fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = SECCOLOR3;
+ break;
+ case 9:
+ glNormal3fv(Vbuffer[Vcount].v);
+ Vbuffer[Vcount].type = NORMAL3;
+ break;
+ default:
+ abort();
+ }
+ Vcount++;
+
+ if (Vcount >= BufferSize - 2) {
+ /* reset */
+ Vcount = 0;
+ }
+ }
+
+ Vbuffer[Vcount++].type = END;
+
+ glEnd();
+}
+
+
+static void
+RandomDraw(void)
+{
+ int i;
+ GLboolean dlist = RandomChoice(0.1);
+ if (dlist)
+ glNewList(1, GL_COMPILE);
+ for (i = 0; i < 3; i++) {
+ RandomStateChange();
+ }
+ RandomPrimitive();
+
+ if (dlist) {
+ glEndList();
+ glCallList(1);
+ }
+}
+
+
+static void
+Idle(void)
+{
+ glutPostRedisplay();
+}
+
+
+static void
+Draw(void)
+{
+#if 1
+ RandomDraw();
+ Count++;
+#else
+ /* cut & paste temp code here */
+#endif
+
+ assert(glGetError() == 0);
+
+ if (DB)
+ glutSwapBuffers();
+ else
+ glFinish();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ Width = width;
+ Height = height;
+ glViewport(0, 0, width, height);
+ glScissor(20, 20, Width-40, Height-40);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.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 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+Init(void)
+{
+ static const GLdouble plane[4] = {1, 1, 0, 0};
+ glDrawBuffer(GL_FRONT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_LIGHT0);
+ glClipPlane(GL_CLIP_PLANE0, plane);
+
+ Vbuffer = (struct vertex *)
+ malloc(BufferSize * sizeof(struct vertex));
+
+ /* silence warnings */
+ (void) ReportState;
+ (void) LastPrim;
+}
+
+
+static void
+ParseArgs(int argc, char *argv[])
+{
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-s") == 0) {
+ int j = atoi(argv[i + 1]);
+ printf("Random seed value: %d\n", j);
+ srand(j);
+ i++;
+ }
+ else if (strcmp(argv[i], "-a") == 0) {
+ i++;
+ MinVertexCount = atoi(argv[i]);
+ }
+ else if (strcmp(argv[i], "-b") == 0) {
+ i++;
+ MaxVertexCount = atoi(argv[i]);
+ }
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(Width, Height);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ Win = glutCreateWindow(argv[0]);
+ ParseArgs(argc, argv);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Draw);
+ if (Anim)
+ glutIdleFunc(Idle);
+ Init();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile
index ec85464..d1d7fec 100644
--- a/progs/xdemos/Makefile
+++ b/progs/xdemos/Makefile
@@ -23,6 +23,7 @@ PROGS = glthreads \
overlay \
pbinfo \
pbdemo \
+ texture_from_pixmap \
wincopy \
xfont \
xrotfontdemo \
diff --git a/progs/xdemos/texture_from_pixmap.c b/progs/xdemos/texture_from_pixmap.c
new file mode 100644
index 0000000..ab215b0
--- /dev/null
+++ b/progs/xdemos/texture_from_pixmap.c
@@ -0,0 +1,396 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Test the GLX_EXT_texture_from_pixmap extension
+ * Brian Paul
+ * 19 May 2007
+ */
+
+
+#define GL_GLEXT_PROTOTYPES
+#define GLX_GLXEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <X11/keysym.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static float top, bottom;
+
+static PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_func = NULL;
+static PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_func = NULL;
+
+
+static Display *
+OpenDisplay(void)
+{
+ int screen;
+ Display *dpy;
+ const char *ext;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ printf("Couldn't open default display!\n");
+ exit(1);
+ }
+
+ screen = DefaultScreen(dpy);
+ ext = glXQueryExtensionsString(dpy, screen);
+ if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) {
+ fprintf(stderr, "GLX_EXT_texture_from_pixmap not supported.\n");
+ exit(1);
+ }
+
+ glXBindTexImageEXT_func = (PFNGLXBINDTEXIMAGEEXTPROC)
+ glXGetProcAddress((GLubyte *) "glXBindTexImageEXT");
+ glXReleaseTexImageEXT_func = (PFNGLXRELEASETEXIMAGEEXTPROC)
+ glXGetProcAddress((GLubyte*) "glXReleaseTexImageEXT");
+
+ if (!glXBindTexImageEXT_func || !glXReleaseTexImageEXT_func) {
+ fprintf(stderr, "glXGetProcAddress failed!\n");
+ exit(1);
+ }
+
+ return dpy;
+}
+
+
+static GLXFBConfig
+ChoosePixmapFBConfig(Display *display)
+{
+ int screen = DefaultScreen(display);
+ GLXFBConfig *fbconfigs;
+ int i, nfbconfigs, value;
+
+ fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs);
+ for (i = 0; i < nfbconfigs; i++) {
+
+ glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
+ if (!(value & GLX_PIXMAP_BIT))
+ continue;
+
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value);
+ if (!(value & GLX_TEXTURE_2D_BIT_EXT))
+ continue;
+
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
+ if (value == False) {
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
+ if (value == False)
+ continue;
+ }
+
+ glXGetFBConfigAttrib(display, fbconfigs[i],
+ GLX_Y_INVERTED_EXT, &value);
+ if (value == True) {
+ top = 0.0f;
+ bottom = 1.0f;
+ }
+ else {
+ top = 1.0f;
+ bottom = 0.0f;
+ }
+
+ break;
+ }
+
+ if (i == nfbconfigs) {
+ printf("Unable to find FBconfig for texturing\n");
+ exit(1);
+ }
+
+ return fbconfigs[i];
+}
+
+
+static GLXPixmap
+CreatePixmap(Display *dpy, GLXFBConfig config, int w, int h, Pixmap *p)
+{
+ GLXPixmap gp;
+ const int pixmapAttribs[] = {
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+ None
+ };
+ Window root = RootWindow(dpy, 0);
+
+ *p = XCreatePixmap(dpy, root, w, h, 24);
+ XSync(dpy, 0);
+ gp = glXCreatePixmap(dpy, config, *p, pixmapAttribs);
+ XSync(dpy, 0);
+
+ return gp;
+}
+
+
+static void
+DrawPixmapImage(Display *dpy, Pixmap pm, int w, int h)
+{
+ XGCValues gcvals;
+ GC gc;
+
+ gcvals.background = 0;
+ gc = XCreateGC(dpy, pm, GCBackground, &gcvals);
+
+ XSetForeground(dpy, gc, 0x0);
+ XFillRectangle(dpy, pm, gc, 0, 0, w, h);
+
+ XSetForeground(dpy, gc, 0xff0000);
+ XFillRectangle(dpy, pm, gc, 0, 0, 50, 50);
+
+ XSetForeground(dpy, gc, 0x00ff00);
+ XFillRectangle(dpy, pm, gc, w - 50, 0, 50, 50);
+
+ XSetForeground(dpy, gc, 0x0000ff);
+ XFillRectangle(dpy, pm, gc, 0, h - 50, 50, 50);
+
+ XSetForeground(dpy, gc, 0xffffff);
+ XFillRectangle(dpy, pm, gc, h - 50, h - 50, 50, 50);
+
+ XSetForeground(dpy, gc, 0xffff00);
+ XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel);
+ XDrawLine(dpy, pm, gc, 0, 0, w, h);
+ XDrawLine(dpy, pm, gc, 0, h, w, 0);
+
+ XFreeGC(dpy, gc);
+}
+
+
+static XVisualInfo *
+ChooseWindowVisual(Display *dpy)
+{
+ int screen = DefaultScreen(dpy);
+ XVisualInfo *visinfo;
+ int attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+
+ visinfo = glXChooseVisual(dpy, screen, attribs);
+ if (!visinfo) {
+ printf("Unable to find RGB, double-buffered visual\n");
+ exit(1);
+ }
+
+ return visinfo;
+}
+
+
+static Window
+CreateWindow(Display *dpy, XVisualInfo *visinfo,
+ int width, int height, const char *name)
+{
+ int screen = DefaultScreen(dpy);
+ Window win;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+
+ root = RootWindow(dpy, screen);
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow(dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr);
+ if (win) {
+ XSizeHints sizehints;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize;
+ XSetNormalHints(dpy, win, &sizehints);
+ XSetStandardProperties(dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+
+ XMapWindow(dpy, win);
+ }
+ return win;
+}
+
+
+static void
+BindPixmapTexture(Display *dpy, GLXPixmap gp)
+{
+ GLuint texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glXBindTexImageEXT_func(dpy, gp, GLX_FRONT_LEFT_EXT, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glEnable(GL_TEXTURE_2D);
+ /*
+ glXReleaseTexImageEXT_func(display, glxpixmap, GLX_FRONT_LEFT_EXT);
+ */
+}
+
+
+static void
+Resize(Window win, unsigned int width, unsigned int height)
+{
+ float sz = 1.5;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-sz, sz, -sz, sz, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+}
+
+
+static void
+Redraw(Display *dpy, Window win, float rot)
+{
+ glClearColor(0.25, 0.25, 0.25, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glPushMatrix();
+ glRotatef(rot, 0, 0, 1);
+ glRotatef(2.0 * rot, 1, 0, 0);
+
+ glBegin(GL_QUADS);
+ glTexCoord2d(0.0, bottom);
+ glVertex2f(-1, -1);
+ glTexCoord2d(1.0, bottom);
+ glVertex2f( 1, -1);
+ glTexCoord2d(1.0, top);
+ glVertex2d(1.0, 1.0);
+ glTexCoord2d(0.0, top);
+ glVertex2f(-1.0, 1.0);
+ glEnd();
+
+ glPopMatrix();
+
+ glXSwapBuffers(dpy, win);
+}
+
+
+static void
+EventLoop(Display *dpy, Window win)
+{
+ GLfloat rot = 0.0;
+ int anim = 0;
+
+ while (1) {
+ if (!anim || XPending(dpy) > 0) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ Redraw(dpy, win, rot);
+ break;
+ case ConfigureNotify:
+ Resize(event.xany.window,
+ event.xconfigure.width,
+ event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buf[100];
+ KeySym keySym;
+ XComposeStatus stat;
+ XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
+ if (keySym == XK_Escape) {
+ return; /* exit */
+ }
+ else if (keySym == XK_r) {
+ rot += 1.0;
+ Redraw(dpy, win, rot);
+ }
+ else if (keySym == XK_a) {
+ anim = !anim;
+ }
+ else if (keySym == XK_R) {
+ rot -= 1.0;
+ Redraw(dpy, win, rot);
+ }
+ }
+ break;
+ default:
+ ; /*no-op*/
+ }
+ }
+ else {
+ /* animate */
+ rot += 1.0;
+ Redraw(dpy, win, rot);
+ }
+ }
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+ Display *dpy;
+ GLXFBConfig pixmapConfig;
+ XVisualInfo *windowVis;
+ GLXPixmap gp;
+ Window win;
+ GLXContext ctx;
+ Pixmap p;
+
+ dpy = OpenDisplay();
+
+ pixmapConfig = ChoosePixmapFBConfig(dpy);
+ windowVis = ChooseWindowVisual(dpy);
+ win = CreateWindow(dpy, windowVis, 500, 500, "Texture From Pixmap");
+
+ gp = CreatePixmap(dpy, pixmapConfig, 512, 512, &p);
+ DrawPixmapImage(dpy, p, 512, 512);
+
+ ctx = glXCreateContext(dpy, windowVis, NULL, True);
+ if (!ctx) {
+ printf("Couldn't create GLX context\n");
+ exit(1);
+ }
+
+ glXMakeCurrent(dpy, win, ctx);
+
+ BindPixmapTexture(dpy, gp);
+
+ EventLoop(dpy, win);
+
+ return 0;
+}