diff options
author | Thierry Reding <[email protected]> | 2006-11-18 17:59:25 +0000 |
---|---|---|
committer | Thierry Reding <[email protected]> | 2006-11-18 17:59:25 +0000 |
commit | bb44a8ae1f392d44b2f588c831101c865485bcfd (patch) | |
tree | 3c5e6aa649975c46d68c3f7745f6410ddac1f174 /progs | |
parent | b5a5062176ffae31566f55db4eee6099d15ccf1f (diff) |
Update to latest upstream release candidate.
Update patches.
Diffstat (limited to 'progs')
-rw-r--r-- | progs/demos/Makefile | 2 | ||||
-rw-r--r-- | progs/demos/cubemap.c | 1 | ||||
-rw-r--r-- | progs/demos/fslight.c | 334 | ||||
-rw-r--r-- | progs/demos/readpix.c | 31 | ||||
-rw-r--r-- | progs/demos/streaming_rect.c | 322 | ||||
-rw-r--r-- | progs/demos/texdown.c | 133 | ||||
-rw-r--r-- | progs/osdemos/osdemo.c | 45 | ||||
-rw-r--r-- | progs/xdemos/wincopy.c | 35 |
8 files changed, 824 insertions, 79 deletions
diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 43d0f17c85f..4623d6c8d91 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -25,6 +25,7 @@ PROGS = \ fire \ fogcoord \ fplight \ + fslight \ gamma \ gearbox \ gears \ @@ -47,6 +48,7 @@ PROGS = \ renormal \ shadowtex \ singlebuffer \ + streaming_rect \ spectex \ spriteblast \ stex3d \ diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c index 0a59b989835..ef5d2355509 100644 --- a/progs/demos/cubemap.c +++ b/progs/demos/cubemap.c @@ -454,6 +454,7 @@ static void usage(void) int main( int argc, char *argv[] ) { + glutInit(&argc, argv); glutInitWindowPosition(0, 0); glutInitWindowSize(600, 500); glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c new file mode 100644 index 00000000000..1c016cc75e9 --- /dev/null +++ b/progs/demos/fslight.c @@ -0,0 +1,334 @@ +/** + * Test OpenGL 2.0 vertex/fragment shaders. + * Brian Paul + * 1 November 2006 + * + * Based on ARB version by: + * Michal Krol + * 20 February 2006 + * + * Based on the original demo by: + * Brian Paul + * 17 April 2003 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> + +static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f }; +static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f }; +static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f }; +static GLfloat delta = 1.0f; + +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + +static GLint uLightPos; +static GLint uDiffuse; +static GLint uSpecular; + +static GLint win = 0; +static GLboolean anim = GL_TRUE; +static GLboolean wire = GL_FALSE; +static GLboolean pixelLight = GL_TRUE; + +static GLint t0 = 0; +static GLint frames = 0; + +static GLfloat xRot = 0.0f, yRot = 0.0f; + +static PFNGLCREATESHADERPROC glCreateShader_func = NULL; +static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL; +static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL; +static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL; +static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL; +static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL; +static PFNGLDELETESHADERPROC glDeleteShader_func = NULL; +static PFNGLATTACHSHADERPROC glAttachShader_func = NULL; +static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL; +static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL; +static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL; +static PFNGLISPROGRAMPROC glIsProgram_func = NULL; +static PFNGLISSHADERPROC glIsShader_func = NULL; +static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL; +static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL; + + + +static void +normalize(GLfloat *dst, const GLfloat *src) +{ + GLfloat len = sqrtf(src[0] * src[0] + src[1] * src[1] + src[2] * src[2]); + dst[0] = src[0] / len; + dst[1] = src[1] / len; + dst[2] = src[2] / len; +} + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (pixelLight) { + GLfloat vec[3]; + glUseProgram_func(program); + normalize(vec, lightPos); + glUniform3fv_func(uLightPos, 1, vec); + glDisable(GL_LIGHTING); + } + else { + glUseProgram_func(0); + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glEnable(GL_LIGHTING); + } + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glutSolidSphere(2.0, 10, 5); + glPopMatrix(); + + glutSwapBuffers(); + frames++; + + if (anim) { + GLint t = glutGet(GLUT_ELAPSED_TIME); + if (t - t0 >= 5000) { + GLfloat seconds =(GLfloat)(t - t0) / 1000.0f; + GLfloat fps = frames / seconds; + printf("%d frames in %6.3f seconds = %6.3f FPS\n", + frames, seconds, fps); + t0 = t; + frames = 0; + } + } +} + + +static void +Idle(void) +{ + lightPos[0] += delta; + if (lightPos[0] > 25.0f || lightPos[0] < -25.0f) + delta = -delta; + 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); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case ' ': + case 'a': + anim = !anim; + if (anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'x': + lightPos[0] -= 1.0f; + break; + case 'X': + lightPos[0] += 1.0f; + 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: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0f; + + (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 *fragShaderText = + "uniform vec3 lightPos;\n" + "uniform vec4 diffuse;\n" + "uniform vec4 specular;\n" + "varying vec3 normal;\n" + "void main() {\n" + " // Compute dot product of light direction and normal vector\n" + " float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n" + " // Compute diffuse and specular contributions\n" + " gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n" + "}\n"; + static const char *vertShaderText = + "varying vec3 normal;\n" + "void main() {\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " normal = gl_NormalMatrix * gl_Normal;\n" + "}\n"; + + + const char *version; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + + + glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader"); + glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader"); + glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram"); + glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource"); + glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource"); + glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader"); + glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram"); + glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader"); + glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram"); + glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram"); + glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation"); + glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram"); + glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader"); + glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv"); + glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv"); + + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + glShaderSource_func(fragShader, 1, &fragShaderText, NULL); + glCompileShader_func(fragShader); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + glShaderSource_func(vertShader, 1, &vertShaderText, NULL); + glCompileShader_func(vertShader); + + program = glCreateProgram_func(); + glAttachShader_func(program, fragShader); + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + glUseProgram_func(program); + + uLightPos = glGetUniformLocation_func(program, "lightPos"); + uDiffuse = glGetUniformLocation_func(program, "diffuse"); + uSpecular = glGetUniformLocation_func(program, "specular"); + + glUniform4fv_func(uDiffuse, 1, diffuse); + glUniform4fv_func(uSpecular, 1, specular); + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + 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.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + printf("Press p to toggle between per-pixel and per-vertex lighting\n"); + + /* test glGetShaderSource() */ + { + GLsizei len = strlen(fragShaderText) + 1; + GLsizei lenOut; + GLchar *src =(GLchar *) malloc(len * sizeof(GLchar)); + glGetShaderSource_func(fragShader, 0, NULL, src); + glGetShaderSource_func(fragShader, len, &lenOut, src); + assert(len == lenOut + 1); + assert(strcmp(src, fragShaderText) == 0); + free(src); + } + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(200, 200); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + if (anim) + glutIdleFunc(Idle); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/demos/readpix.c b/progs/demos/readpix.c index 75ba45c1e5f..c0aac2272f7 100644 --- a/progs/demos/readpix.c +++ b/progs/demos/readpix.c @@ -29,33 +29,32 @@ static GLboolean ScaleAndBias = GL_FALSE; static GLboolean Benchmark = GL_FALSE; static GLubyte *TempImage = NULL; -#if 0 +#define COMBO 1 +#if COMBO == 0 #define ReadFormat ImgFormat #define ReadType GL_UNSIGNED_BYTE -#endif -#if 1 +#elif COMBO == 1 static GLenum ReadFormat = GL_RGBA; static GLenum ReadType = GL_UNSIGNED_BYTE; -#endif -#if 0 +#elif COMBO == 2 static GLenum ReadFormat = GL_RGB; static GLenum ReadType = GL_UNSIGNED_BYTE; -#endif -#if 0 +#elif COMBO == 3 static GLenum ReadFormat = GL_RGB; static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5; -#endif -#if 0 +#elif COMBO == 4 static GLenum ReadFormat = GL_RGBA; static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV; -#endif -#if 0 +#elif COMBO == 5 static GLenum ReadFormat = GL_BGRA; static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1; -#endif -#if 0 +#elif COMBO == 6 static GLenum ReadFormat = GL_BGRA; static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV; +#elif COMBO == 7 +static GLenum ReadFormat = GL_RGBA; +static GLenum ReadType = GL_HALF_FLOAT_ARB; +#undef GL_OES_read_format #endif @@ -313,8 +312,10 @@ Init( GLboolean ciMode ) Reset(); - /* allocate an extra 1KB in case we're tinkering with pack alignment */ - TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte) + /* allocate large TempImage to store and image data type, plus an + * extra 1KB in case we're tinkering with pack alignment. + */ + TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * 4 + 1000); assert(TempImage); } diff --git a/progs/demos/streaming_rect.c b/progs/demos/streaming_rect.c new file mode 100644 index 00000000000..86e00803c01 --- /dev/null +++ b/progs/demos/streaming_rect.c @@ -0,0 +1,322 @@ + +/* + * GL_ARB_multitexture demo + * + * Command line options: + * -info print GL implementation information + * + * + * Brian Paul November 1998 This program is in the public domain. + * Modified on 12 Feb 2002 for > 2 texture units. + */ + +#define GL_GLEXT_PROTOTYPES + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <GL/glut.h> + +#include "readtex.h" + + +#define ANIMATE 10 +#define PBO 11 +#define QUIT 100 + +static GLboolean Animate = GL_TRUE; +static GLboolean use_pbo = 1; +static GLboolean whole_rect = 1; + +static GLfloat Drift = 0.0; +static GLfloat drift_increment = 1/255.0; +static GLfloat Xrot = 20.0, Yrot = 30.0; + +static GLuint Width = 1024; +static GLuint Height = 512; + + +static void Idle( void ) +{ + if (Animate) { + + Drift += drift_increment; + if (Drift >= 1.0) + Drift = 0.0; + + glutPostRedisplay(); + } +} + +static int max( int a, int b ) { return a > b ? a : b; } +static int min( int a, int b ) { return a < b ? a : b; } + +static void DrawObject() +{ + GLint size = Width * Height * 4; + + if (use_pbo) { + /* XXX: This is extremely important - semantically makes the buffer + * contents undefined, but in practice means that the driver can + * release the old copy of the texture and allocate a new one + * without waiting for outstanding rendering to complete. + */ + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB); + + { + char *image = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY_ARB); + + printf("char %d\n", (unsigned char)(Drift * 255)); + + memset(image, size, (unsigned char)(Drift * 255)); + + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + } + + + /* BGRA is required for most hardware paths: + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else { + static char *image = NULL; + + if (image == NULL) + image = malloc(size); + + memset(image, size, (unsigned char)(Drift * 255)); + + /* BGRA should be the fast path for regular uploads as well. + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, image); + } + + { + int x,y,w,h; + + if (whole_rect) { + x = y = 0; + w = Width; + h = Height; + } + else { + x = y = 0; + w = min(10, Width); + h = min(10, Height); + } + + glBegin(GL_QUADS); + + glTexCoord2f( x, y); + glVertex2f( x, y ); + + glTexCoord2f( x, y + h); + glVertex2f( x, y + h); + + glTexCoord2f( x + w + .5, y + h); + glVertex2f( x + w, y + h ); + + glTexCoord2f( x + w, y + .5); + glVertex2f( x + w, y ); + + glEnd(); + } +} + + + +static void Display( void ) +{ + static GLint T0 = 0; + static GLint Frames = 0; + GLint t; + + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); + + Frames++; + + t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 1000) { + GLfloat seconds = (t - T0) / 1000.0; + + GLfloat fps = Frames / seconds; + printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps); + + drift_increment = 2.2 * seconds / Frames; + T0 = t; + Frames = 0; + } +} + + +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, 10.0, 100.0 ); */ + gluOrtho2D( 0, width, height, 0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef(0.375, 0.375, 0); +} + + +static void ModeMenu(int entry) +{ + if (entry==ANIMATE) { + Animate = !Animate; + } + else if (entry==PBO) { + use_pbo = !use_pbo; + } + else if (entry==QUIT) { + exit(0); + } + + glutPostRedisplay(); +} + + +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 ) +{ + float 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( int argc, char *argv[] ) +{ + const char *exten = (const char *) glGetString(GL_EXTENSIONS); + GLuint texObj, DrawPBO; + GLint size; + + + if (!strstr(exten, "GL_ARB_multitexture")) { + printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n"); + exit(1); + } + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + printf("%d x %d max texture size\n", size, size); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + /* allocate two texture objects */ + glGenTextures(1, &texObj); + + /* setup the texture objects */ + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glGenBuffersARB(1, &DrawPBO); + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + Width * Height * 4, NULL, GL_STREAM_DRAW); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + glShadeModel(GL_SMOOTH); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } +} + + +int main( int argc, char *argv[] ) +{ + GLint i; + + glutInit( &argc, argv ); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-w") == 0) { + Width = atoi(argv[i+1]); + if (Width <= 0) { + printf("Error, bad width\n"); + exit(1); + } + i++; + } + else if (strcmp(argv[i], "-h") == 0) { + Height = atoi(argv[i+1]); + if (Height <= 0) { + printf("Error, bad height\n"); + exit(1); + } + i++; + } + } + + glutInitWindowSize( Width, Height ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutIdleFunc( Idle ); + + glutCreateMenu(ModeMenu); + glutAddMenuEntry("Toggle Animation", ANIMATE); + glutAddMenuEntry("Toggle PBO", PBO); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; +} diff --git a/progs/demos/texdown.c b/progs/demos/texdown.c index 79525a0395e..fc98fddb310 100644 --- a/progs/demos/texdown.c +++ b/progs/demos/texdown.c @@ -38,8 +38,8 @@ #include <GL/glut.h> -static GLsizei MaxSize = 1024; -static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0; +static GLsizei MaxSize = 2048; +static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0; static GLboolean ScaleAndBias = GL_FALSE; static GLboolean SubImage = GL_FALSE; static GLdouble DownloadRate = 0.0; /* texels/sec */ @@ -47,6 +47,32 @@ static GLdouble DownloadRate = 0.0; /* texels/sec */ static GLuint Mode = 0; +/* Try and avoid L2 cache effects by cycling through a small number of + * textures. + * + * At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will + * keep us out of most caches at 32mb total. + * + * This turns into a fairly interesting question of what exactly you + * expect to be in cache in normal usage, and what you think should be + * outside. There's no rules for this, no reason to favour one usage + * over another except what the application you care about happens to + * resemble most closely. + * + * - Should the client texture image be in L2 cache? Has it just been + * generated or read from disk? + * - Does the application really use >1 texture, or is it constantly + * updating one image in-place? + * + * Different answers will favour different texture upload mechanisms. + * To upload an image that is purely outside of cache, a DMA-based + * upload will probably win, whereas for small, in-cache textures, + * copying looks good. + */ +#define NR_TEXOBJ 4 +static GLuint TexObj[NR_TEXOBJ]; + + struct FormatRec { GLenum Format; GLenum Type; @@ -116,25 +142,57 @@ TypeStr(GLenum type) } } +/* On x86, there is a performance cliff for memcpy to texture memory + * for sources below 64 byte alignment. We do our best with this in + * the driver, but it is better if the images are correctly aligned to + * start with: + */ +#define ALIGN (1<<12) + +static unsigned align(unsigned value, unsigned a) +{ + return (value + a - 1) & ~(a-1); +} + +static int MIN2(int a, int b) +{ + return a < b ? a : b; +} static void MeasureDownloadRate(void) { const int w = TexWidth + 2 * TexBorder; const int h = TexHeight + 2 * TexBorder; - const int bytes = w * h * BytesPerTexel(Format); + const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN); + const int bytes = image_bytes * NR_TEXOBJ; + GLubyte *orig_texImage, *orig_getImage; GLubyte *texImage, *getImage; GLdouble t0, t1, time; int count; int i; + int offset = 0; + GLdouble total = 0; /* ints will tend to overflow */ + + printf("allocating %d bytes for %d %dx%d images\n", + bytes, NR_TEXOBJ, w, h); - texImage = (GLubyte *) malloc(bytes); - getImage = (GLubyte *) malloc(bytes); - if (!texImage || !getImage) { + orig_texImage = (GLubyte *) malloc(bytes + ALIGN); + orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN); + if (!orig_texImage || !orig_getImage) { DownloadRate = 0.0; return; } + printf("alloc %p %p\n", orig_texImage, orig_getImage); + + texImage = (GLubyte *)align((unsigned)orig_texImage, ALIGN); + getImage = (GLubyte *)align((unsigned)orig_getImage, ALIGN); + + for (i = 1; !(((unsigned)texImage) & i); i<<=1) + ; + printf("texture image alignment: %d bytes (%p)\n", i, texImage); + for (i = 0; i < bytes; i++) { texImage[i] = i & 0xff; } @@ -166,16 +224,50 @@ MeasureDownloadRate(void) count = 0; t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; do { + int img = count%NR_TEXOBJ; + GLubyte *img_ptr = texImage + img * image_bytes; + + glBindTexture(GL_TEXTURE_2D, TexObj[img]); + if (SubImage && count > 0) { - glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h, + /* Only update a portion of the image each iteration. This + * is presumably why you'd want to use texsubimage, otherwise + * you may as well just call teximage again. + * + * A bigger question is whether to use a pointer that moves + * with each call, ie does the incoming data come from L2 + * cache under normal circumstances, or is it pulled from + * uncached memory? + * + * There's a good argument to say L2 cache, ie you'd expect + * the data to have been recently generated. It's possible + * that it could have come from a file read, which may or may + * not have gone through the cpu. + */ + glTexSubImage2D(GL_TEXTURE_2D, 0, + -TexBorder, + -TexBorder + offset * h/8, + w, + h/8, FormatTable[Format].Format, - FormatTable[Format].Type, texImage); + FormatTable[Format].Type, +#if 1 + texImage /* likely in L2$ */ +#else + img_ptr + offset * bytes/8 /* unlikely in L2$ */ +#endif + ); + offset += 1; + offset %= 8; + total += w * h / 8; } else { glTexImage2D(GL_TEXTURE_2D, 0, FormatTable[Format].IntFormat, w, h, TexBorder, FormatTable[Format].Format, - FormatTable[Format].Type, texImage); + FormatTable[Format].Type, + img_ptr); + total += w*h; } /* draw a tiny polygon to force texture into texram */ @@ -192,25 +284,12 @@ MeasureDownloadRate(void) glDisable(GL_TEXTURE_2D); - printf("w*h=%d count=%d time=%f\n", w*h, count, time); - DownloadRate = w * h * count / time; - -#if 0 - if (!ScaleAndBias) { - /* verify texture readback */ - glGetTexImage(GL_TEXTURE_2D, 0, - FormatTable[Format].Format, - FormatTable[Format].Type, getImage); - for (i = 0; i < w * h; i++) { - if (texImage[i] != getImage[i]) { - printf("[%d] %d != %d\n", i, texImage[i], getImage[i]); - } - } - } -#endif + printf("total texels=%f time=%f\n", total, time); + DownloadRate = total / time; + - free(texImage); - free(getImage); + free(orig_texImage); + free(orig_getImage); { GLint err = glGetError(); diff --git a/progs/osdemos/osdemo.c b/progs/osdemos/osdemo.c index f7ce121f702..bc0168fb97b 100644 --- a/progs/osdemos/osdemo.c +++ b/progs/osdemos/osdemo.c @@ -4,7 +4,7 @@ * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions. * * If you want to render BIG images you'll probably have to increase - * MAX_WIDTH and MAX_HEIGHT in src/config.h. + * MAX_WIDTH and MAX_Height in src/config.h. * * This program is in the public domain. * @@ -27,8 +27,8 @@ #define SAVE_TARGA -#define WIDTH 400 -#define HEIGHT 400 +static int Width = 400; +static int Height = 400; static void @@ -175,10 +175,10 @@ write_targa(const char *filename, const GLubyte *buffer, int width, int height) fputc (0x00, f); fputc (0x00, f); /* Y-origin of Image */ fputc (0x00, f); - fputc (WIDTH & 0xff, f); /* Image Width */ - fputc ((WIDTH>>8) & 0xff, f); - fputc (HEIGHT & 0xff, f); /* Image Height */ - fputc ((HEIGHT>>8) & 0xff, f); + fputc (Width & 0xff, f); /* Image Width */ + fputc ((Width>>8) & 0xff, f); + fputc (Height & 0xff, f); /* Image Height */ + fputc ((Height>>8) & 0xff, f); fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */ fputc (0x20, f); /* Image Descriptor */ fclose(f); @@ -248,36 +248,43 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height) int main(int argc, char *argv[]) { + OSMesaContext ctx; void *buffer; - int i; char *filename = NULL; + if (argc < 2) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " osdemo filename [width height]\n"); + return 0; + } + + filename = argv[1]; + if (argc == 4) { + Width = atoi(argv[2]); + Height = atoi(argv[3]); + } + /* Create an RGBA-mode context */ #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 /* specify Z, stencil, accum sizes */ - OSMesaContext ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL ); + ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL ); #else - OSMesaContext ctx = OSMesaCreateContext( OSMESA_RGBA, NULL ); + ctx = OSMesaCreateContext( OSMESA_RGBA, NULL ); #endif if (!ctx) { printf("OSMesaCreateContext failed!\n"); return 0; } - for (i = 1; i < argc; i++) { - if (argv[i][0] != '-') - filename = argv[i]; - } - /* Allocate the image buffer */ - buffer = malloc( WIDTH * HEIGHT * 4 * sizeof(GLubyte) ); + buffer = malloc( Width * Height * 4 * sizeof(GLubyte) ); if (!buffer) { printf("Alloc image buffer failed!\n"); return 0; } /* Bind the buffer to the context and make it current */ - if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT )) { + if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) { printf("OSMesaMakeCurrent failed!\n"); return 0; } @@ -295,9 +302,9 @@ main(int argc, char *argv[]) if (filename != NULL) { #ifdef SAVE_TARGA - write_targa(filename, buffer, WIDTH, HEIGHT); + write_targa(filename, buffer, Width, Height); #else - write_ppm(filename, buffer, WIDTH, HEIGHT); + write_ppm(filename, buffer, Width, Height); #endif } else { diff --git a/progs/xdemos/wincopy.c b/progs/xdemos/wincopy.c index 3ec67dc6724..f670983a0f7 100644 --- a/progs/xdemos/wincopy.c +++ b/progs/xdemos/wincopy.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.2 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 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"), @@ -32,6 +32,7 @@ */ +#define GL_GLEXT_PROTOTYPES #define GLX_GLXEXT_PROTOTYPES #include <GL/gl.h> #include <GL/glx.h> @@ -50,7 +51,7 @@ static int ScrNum; static GLXContext Context; static Window Win[2]; /* Win[0] = source, Win[1] = dest */ static GLint Width[2], Height[2]; - +static GLboolean TestClipping = GL_FALSE; static GLfloat Angle = 0.0; static GLboolean DrawFront = GL_FALSE; @@ -123,7 +124,7 @@ Redraw(void) glMatrixMode(GL_MODELVIEW); glShadeModel(GL_FLAT); - glClearColor(0.5, 0.5, 0.5, 1.0); + glClearColor(0.5, 0.5, 0.5, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* draw blue quad */ @@ -150,22 +151,18 @@ Redraw(void) return; } - /* raster pos setup */ - glViewport(0, 0, Width[1], Height[1]); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(-1, 1, -1, 1, -1, 1); - glRasterPos2f(-1, -1); - /* copy the image between windows */ - glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + if (TestClipping) { + glWindowPos2iARB(-2, -2); + glCopyPixels(-2, -2, Width[0] + 4, Height[0] + 4, GL_COLOR); + } + else { + glWindowPos2iARB(0, 0); + glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR); + } if (DrawFront) glFinish(); @@ -309,6 +306,8 @@ Init(void) int main(int argc, char *argv[]) { + if (argc > 1 && strcmp(argv[1], "-clip") == 0) + TestClipping = GL_TRUE; Init(); EventLoop(); return 0; |