diff options
Diffstat (limited to 'progs')
-rw-r--r-- | progs/SConscript | 1 | ||||
-rw-r--r-- | progs/demos/dissolve.c | 137 | ||||
-rw-r--r-- | progs/egl/Makefile | 6 | ||||
-rw-r--r-- | progs/gallium/python/samples/tri.py | 20 | ||||
-rw-r--r-- | progs/gallium/raw/SConscript | 17 | ||||
-rw-r--r-- | progs/gallium/raw/clear.c | 95 | ||||
-rw-r--r-- | progs/gallium/trivial/.gitignore | 3 | ||||
-rw-r--r-- | progs/gallium/trivial/Makefile | 44 | ||||
-rw-r--r-- | progs/gallium/trivial/quad-tex.c | 346 | ||||
-rw-r--r-- | progs/gallium/trivial/tri.c | 278 | ||||
-rw-r--r-- | progs/glsl/Makefile | 4 | ||||
-rw-r--r-- | progs/glsl/SConscript | 2 | ||||
-rw-r--r-- | progs/glsl/fsraytrace.c | 412 | ||||
-rw-r--r-- | progs/glsl/vsraytrace.c | 401 | ||||
-rw-r--r-- | progs/samples/copy.c | 27 | ||||
-rw-r--r-- | progs/samples/loadppm.c | 6 | ||||
-rw-r--r-- | progs/tests/Makefile | 1 | ||||
-rw-r--r-- | progs/tests/SConscript | 2 | ||||
-rw-r--r-- | progs/tests/cva_huge.c | 232 | ||||
-rw-r--r-- | progs/tests/stencil_twoside.c | 85 | ||||
-rw-r--r-- | progs/trivial/tri-stencil.c | 3 | ||||
-rw-r--r-- | progs/xdemos/Makefile | 2 |
22 files changed, 2070 insertions, 54 deletions
diff --git a/progs/SConscript b/progs/SConscript index aa6640cf7a..a90e13b4cb 100644 --- a/progs/SConscript +++ b/progs/SConscript @@ -56,4 +56,5 @@ SConscript([ 'wgl/SConscript', 'perf/SConscript', 'gallium/unit/SConscript', +# 'gallium/raw/SConscript', ]) diff --git a/progs/demos/dissolve.c b/progs/demos/dissolve.c index 0b8df1bb66..8ab5242d91 100644 --- a/progs/demos/dissolve.c +++ b/progs/demos/dissolve.c @@ -1,5 +1,5 @@ /** - * Dissolve between two images using randomized stencil buffer + * Dissolve between two images using randomized/patterned stencil buffer * and varying stencil ref. * * Brian Paul @@ -9,6 +9,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <math.h> #include <GL/glut.h> #include "readtex.h" @@ -28,6 +29,8 @@ static GLfloat ScaleX[2], ScaleY[2]; static GLubyte StencilRef = 0; +static int Mode = 0; + static void Idle(void) @@ -38,13 +41,114 @@ Idle(void) static void -RandomizeStencilBuffer(void) +FillRandomPixels(GLubyte *b) { - GLubyte *b = malloc(WinWidth * WinHeight); int i; for (i = 0; i < WinWidth * WinHeight; i++) { b[i] = rand() & 0xff; } +} + + +static void +FillRandomRects(GLubyte *b) +{ + int i; + + memset(b, 0, WinWidth * WinHeight); + + for (i = 0; i < 256; i++) { + int x = rand() % WinWidth; + int y = rand() % WinHeight; + int w = rand() % 60; + int h = rand() % 60; + int ix, iy; + + if (x + w > WinWidth) + w = WinWidth - x; + if (y + h > WinHeight) + h = WinHeight - y; + + for (iy = 0; iy < h; iy++) { + for (ix = 0; ix < w; ix++) { + int p = (y + iy) * WinWidth + x + ix; + b[p] = i; + } + } + } +} + + +static void +FillWipe(GLubyte *b) +{ + int iy, ix; + + memset(b, 0, WinWidth * WinHeight); + + for (iy = 0; iy < WinHeight; iy++) { + for (ix = 0; ix < WinWidth; ix++) { + int p = iy * WinWidth + ix; + b[p] = 2 * ix + iy / 2; + } + } +} + + +static void +FillMoire(GLubyte *b) +{ + int iy, ix; + + memset(b, 0, WinWidth * WinHeight); + + for (iy = 0; iy < WinHeight; iy++) { + for (ix = 0; ix < WinWidth; ix++) { + int p = iy * WinWidth + ix; + b[p] = (ix / 2) * (ix / 2) - (iy / 2) * (iy / 2); + } + } +} + + +static void +FillWaves(GLubyte *b) +{ + int iy, ix; + + memset(b, 0, WinWidth * WinHeight); + + for (iy = 0; iy < WinHeight; iy++) { + for (ix = 0; ix < WinWidth; ix++) { + int p = iy * WinWidth + ix; + float x = 8.0 * 3.1415 * ix / (float) WinWidth; + b[p] = (int) (25.0 * sin(x) ) - iy*2; + } + } +} + + +typedef void (*FillFunc)(GLubyte *b); + + +static FillFunc Funcs[] = { + FillRandomPixels, + FillRandomRects, + FillWipe, + FillMoire, + FillWaves +}; + +#define NUM_MODES (sizeof(Funcs) / sizeof(Funcs[0])) + + + +static void +InitStencilBuffer(void) +{ + GLubyte *b = malloc(WinWidth * WinHeight); + + Funcs[Mode](b); glStencilFunc(GL_ALWAYS, 0, ~0); glPixelZoom(1.0, 1.0); @@ -54,7 +158,6 @@ RandomizeStencilBuffer(void) } - static void Draw(void) { @@ -85,7 +188,7 @@ Reshape(int width, int height) glLoadIdentity(); glTranslatef(0.0, 0.0, -15.0); - RandomizeStencilBuffer(); + InitStencilBuffer(); ScaleX[0] = (float) width / ImgWidth[0]; ScaleY[0] = (float) height / ImgHeight[0]; @@ -102,12 +205,26 @@ Key(unsigned char key, int x, int y) (void) y; switch (key) { case 'a': + case ' ': Anim = !Anim; if (Anim) glutIdleFunc(Idle); else glutIdleFunc(NULL); break; + case 'i': + InitStencilBuffer(); + break; + case '-': + StencilRef--; + break; + case '+': + StencilRef++; + break; + case 'm': + Mode = (Mode + 1) % NUM_MODES; + InitStencilBuffer(); + break; case 27: glutDestroyWindow(Win); exit(0); @@ -143,8 +260,8 @@ Init(void) int main(int argc, char *argv[]) { - glutInit(&argc, argv); glutInitWindowSize(WinWidth, WinHeight); + glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); Win = glutCreateWindow(argv[0]); glutReshapeFunc(Reshape); @@ -153,6 +270,14 @@ main(int argc, char *argv[]) if (Anim) glutIdleFunc(Idle); Init(); + + printf("Keys:\n"); + printf(" a/SPACE toggle animation\n"); + printf(" +/- single step\n"); + printf(" i re-init pattern\n"); + printf(" m change pattern/dissolve mode\n"); + printf(" ESC exit\n"); + glutMainLoop(); return 0; } diff --git a/progs/egl/Makefile b/progs/egl/Makefile index 5f51104fed..890240f9a3 100644 --- a/progs/egl/Makefile +++ b/progs/egl/Makefile @@ -57,13 +57,13 @@ peglgears: peglgears.o $(HEADERS) $(LIB_DEP) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) -lm xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X11_LIBS) xeglthreads: xeglthreads.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lpthread -lm $(X11_LIBS) xegl_tri: xegl_tri.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X_LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X11_LIBS) clean: -rm -f *.o *~ diff --git a/progs/gallium/python/samples/tri.py b/progs/gallium/python/samples/tri.py index d7fbdb10ac..9f6d787dcb 100644 --- a/progs/gallium/python/samples/tri.py +++ b/progs/gallium/python/samples/tri.py @@ -30,19 +30,19 @@ from gallium import * -def make_image(surface): - data = surface.get_tile_rgba8(0, 0, surface.width, surface.height) +def make_image(ctx, surface): + data = ctx.surface_read_rgba8(surface, 0, 0, surface.width, surface.height) import Image outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1) return outimage -def save_image(filename, surface): - outimage = make_image(surface) +def save_image(ctx, surface, filename): + outimage = make_image(ctx, surface) outimage.save(filename, "PNG") -def show_image(surface): - outimage = make_image(surface) +def show_image(ctx, surface): + outimage = make_image(ctx, surface) import Tkinter as tk from PIL import Image, ImageTk @@ -216,10 +216,10 @@ def test(dev): ctx.flush() - show_image(cbuf) - #show_image(zbuf) - #save_image('cbuf.png', cbuf) - #save_image('zbuf.png', zbuf) + show_image(ctx, cbuf) + show_image(ctx, zbuf) + save_image(ctx, cbuf, 'cbuf.png') + save_image(ctx, zbuf, 'zbuf.png') diff --git a/progs/gallium/raw/SConscript b/progs/gallium/raw/SConscript new file mode 100644 index 0000000000..073b97951e --- /dev/null +++ b/progs/gallium/raw/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = env.Clone() + +env.Prepend(LIBPATH = [graw.dir]) +env.Prepend(LIBS = [graw.name]) + +progs = [ + 'clear' +] + +for prog in progs: + env.Program( + target = prog, + source = prog + '.c', + ) + diff --git a/progs/gallium/raw/clear.c b/progs/gallium/raw/clear.c new file mode 100644 index 0000000000..5ef5254edc --- /dev/null +++ b/progs/gallium/raw/clear.c @@ -0,0 +1,95 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include <unistd.h> /* for sleep() */ + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +int main( int argc, char *argv[] ) +{ + struct pipe_screen *screen; + struct pipe_context *pipe; + struct pipe_surface *surf; + struct pipe_framebuffer_state fb; + struct pipe_texture *tex, templat; + void *window = NULL; + float clear_color[4] = {1,0,1,1}; + int i; + + screen = graw_init(); + if (screen == NULL) + exit(1); + + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + window = graw_create_window(0,0,300,300, formats[i]); + } + + if (window == NULL) + exit(2); + + pipe = screen->context_create(screen, NULL); + if (pipe == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.tex_usage = (PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET); + + tex = screen->texture_create(screen, + &templat); + if (tex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + pipe->set_framebuffer_state(pipe, &fb); + pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + /* At the moment, libgraw includes/makes available all the symbols + * from gallium/auxiliary, including these debug helpers. Will + * eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + */ + if (0) + debug_dump_surface_bmp(pipe, "result.bmp", surf); + + screen->flush_frontbuffer(screen, surf, window); + + sleep(100); + return 0; +} diff --git a/progs/gallium/trivial/.gitignore b/progs/gallium/trivial/.gitignore new file mode 100644 index 0000000000..af6cdedbeb --- /dev/null +++ b/progs/gallium/trivial/.gitignore @@ -0,0 +1,3 @@ +tri +quad-tex +result.bmp diff --git a/progs/gallium/trivial/Makefile b/progs/gallium/trivial/Makefile new file mode 100644 index 0000000000..2b8af1ac06 --- /dev/null +++ b/progs/gallium/trivial/Makefile @@ -0,0 +1,44 @@ +# progs/gallium/simple/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys \ + $(PROG_INCLUDES) + +LINKS = \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/winsys/sw/null/libws_null.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(GALLIUM_AUXILIARIES) \ + $(PROG_LINKS) + +SOURCES = \ + tri.c \ + quad-tex.c + +OBJECTS = $(SOURCES:.c=.o) + +PROGS = $(OBJECTS:.o=) + +##### TARGETS ##### + +default: $(PROGS) + +clean: + -rm -f $(PROGS) + -rm -f *.o + -rm -f result.bmp + +##### RULES ##### + +$(OBJECTS): %.o: %.c + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@ + +$(PROGS): %: %.o + $(CC) $(LDFLAGS) $< $(LINKS) -lm -lpthread -o $@ diff --git a/progs/gallium/trivial/quad-tex.c b/progs/gallium/trivial/quad-tex.c new file mode 100644 index 0000000000..553f5582e7 --- /dev/null +++ b/progs/gallium/trivial/quad-tex.c @@ -0,0 +1,346 @@ +/************************************************************************** + * + * Copyright © 2010 Jakob Bornecrantz + * + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + **************************************************************************/ + + +#define USE_TRACE 0 +#define WIDTH 300 +#define HEIGHT 300 +#define NEAR 30 +#define FAR 1000 +#define FLIP 0 + +/* pipe_*_state structs */ +#include "pipe/p_state.h" +/* pipe_context */ +#include "pipe/p_context.h" +/* pipe_screen */ +#include "pipe/p_screen.h" +/* PIPE_* */ +#include "pipe/p_defines.h" +/* TGSI_SEMANTIC_{POSITION|GENERIC} */ +#include "pipe/p_shader_tokens.h" +/* pipe_buffer_* helpers */ +#include "util/u_inlines.h" + +/* constant state object helper */ +#include "cso_cache/cso_context.h" + +/* u_sampler_view_default_template */ +#include "util/u_sampler.h" +/* debug_dump_surface_bmp */ +#include "util/u_debug.h" +/* util_draw_vertex_buffer helper */ +#include "util/u_draw_quad.h" +/* FREE & CALLOC_STRUCT */ +#include "util/u_memory.h" +/* util_make_[fragment|vertex]_passthrough_shader */ +#include "util/u_simple_shaders.h" + +/* softpipe software driver */ +#include "softpipe/sp_public.h" + +/* null software winsys */ +#include "sw/null/null_sw_winsys.h" + +/* traceing support see src/gallium/drivers/trace/README for more info. */ +#if USE_TRACE +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + +struct program +{ + struct pipe_screen *screen; + struct pipe_context *pipe; + struct cso_context *cso; + + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_vertex_element velem[2]; + + void *vs; + void *fs; + + float clear_color[4]; + + struct pipe_buffer *vbuf; + struct pipe_texture *target; + struct pipe_texture *tex; + struct pipe_sampler_view *view; +}; + +static void init_prog(struct program *p) +{ + /* create the software rasterizer */ + p->screen = softpipe_create_screen(null_sw_create()); +#if USE_TRACE + p->screen = trace_screen_create(p->screen); +#endif + p->pipe = p->screen->context_create(p->screen, NULL); + p->cso = cso_create_context(p->pipe); + + /* set clear color */ + p->clear_color[0] = 0.3; + p->clear_color[1] = 0.1; + p->clear_color[2] = 0.3; + p->clear_color[3] = 1.0; + + /* vertex buffer */ + { + float vertices[4][2][4] = { + { + { 0.9f, 0.9f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f, 1.0f } + }, + { + { -0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { + { -0.9f, -0.9f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + }, + { + { 0.9f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 1.0f, 1.0f } + } + }; + + p->vbuf = pipe_buffer_create(p->screen, 16, PIPE_BUFFER_USAGE_VERTEX, sizeof(vertices)); + pipe_buffer_write(p->screen, p->vbuf, 0, sizeof(vertices), vertices); + } + + /* render target texture */ + { + struct pipe_texture tmplt; + memset(&tmplt, 0, sizeof(tmplt)); + tmplt.target = PIPE_TEXTURE_2D; + tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ + tmplt.width0 = WIDTH; + tmplt.height0 = HEIGHT; + tmplt.depth0 = 1; + tmplt.last_level = 0; + tmplt.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + p->target = p->screen->texture_create(p->screen, &tmplt); + } + + /* sampler texture */ + { + uint32_t *ptr; + struct pipe_transfer *t; + struct pipe_texture t_tmplt; + struct pipe_sampler_view v_tmplt; + + memset(&t_tmplt, 0, sizeof(t_tmplt)); + t_tmplt.target = PIPE_TEXTURE_2D; + t_tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ + t_tmplt.width0 = 2; + t_tmplt.height0 = 2; + t_tmplt.depth0 = 1; + t_tmplt.last_level = 0; + t_tmplt.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + p->tex = p->screen->texture_create(p->screen, &t_tmplt); + + t = p->pipe->get_tex_transfer(p->pipe, p->tex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_WRITE, + 0, 0, 2, 2); /* x, y, width, height */ + + ptr = p->pipe->transfer_map(p->pipe, t); + ptr[0] = 0xffff0000; + ptr[1] = 0xff0000ff; + ptr[2] = 0xff00ff00; + ptr[3] = 0xffffff00; + p->pipe->transfer_unmap(p->pipe, t); + + p->pipe->tex_transfer_destroy(p->pipe, t); + + u_sampler_view_default_template(&v_tmplt, p->tex, p->tex->format); + + p->view = p->pipe->create_sampler_view(p->pipe, p->tex, &v_tmplt); + } + + /* disabled blending/masking */ + memset(&p->blend, 0, sizeof(p->blend)); + p->blend.rt[0].colormask = PIPE_MASK_RGBA; + + /* no-op depth/stencil/alpha */ + memset(&p->depthstencil, 0, sizeof(p->depthstencil)); + + /* rasterizer */ + memset(&p->rasterizer, 0, sizeof(p->rasterizer)); + p->rasterizer.front_winding = PIPE_WINDING_CW; + p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.gl_rasterization_rules = 1; + + /* sampler */ + memset(&p->sampler, 0, sizeof(p->sampler)); + p->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + p->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + p->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + p->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + p->sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR; + p->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR; + p->sampler.normalized_coords = 1; + + /* drawing destination */ + memset(&p->framebuffer, 0, sizeof(p->framebuffer)); + p->framebuffer.width = WIDTH; + p->framebuffer.height = HEIGHT; + p->framebuffer.nr_cbufs = 1; + p->framebuffer.cbufs[0] = p->screen->get_tex_surface(p->screen, p->target, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); + + /* viewport, depth isn't really needed */ + { + float x = 0; + float y = 0; + float z = FAR; + float half_width = (float)WIDTH / 2.0f; + float half_height = (float)HEIGHT / 2.0f; + float half_depth = ((float)FAR - (float)NEAR) / 2.0f; + float scale, bias; + + if (FLIP) { + scale = -1.0f; + bias = (float)HEIGHT; + } else { + scale = 1.0f; + bias = 0.0f; + } + + p->viewport.scale[0] = half_width; + p->viewport.scale[1] = half_height * scale; + p->viewport.scale[2] = half_depth; + p->viewport.scale[3] = 1.0f; + + p->viewport.translate[0] = half_width + x; + p->viewport.translate[1] = (half_height + y) * scale + bias; + p->viewport.translate[2] = half_depth + z; + p->viewport.translate[3] = 0.0f; + } + + /* vertex elements state */ + memset(p->velem, 0, sizeof(p->velem)); + p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */ + p->velem[0].instance_divisor = 0; + p->velem[0].vertex_buffer_index = 0; + p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */ + p->velem[1].instance_divisor = 0; + p->velem[1].vertex_buffer_index = 0; + p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes); + } + + /* fragment shader */ + p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D); +} + +static void close_prog(struct program *p) +{ + /* unset bound textures as well */ + cso_set_fragment_sampler_views(p->cso, 0, NULL); + + /* unset all state */ + cso_release_all(p->cso); + + p->pipe->delete_vs_state(p->pipe, p->vs); + p->pipe->delete_fs_state(p->pipe, p->fs); + + pipe_surface_reference(&p->framebuffer.cbufs[0], NULL); + pipe_sampler_view_reference(&p->view, NULL); + pipe_texture_reference(&p->target, NULL); + pipe_texture_reference(&p->tex, NULL); + pipe_buffer_reference(&p->vbuf, NULL); + + cso_destroy_context(p->cso); + p->pipe->destroy(p->pipe); + p->screen->destroy(p->screen); + + FREE(p); +} + +static void draw(struct program *p) +{ + /* set the render target */ + cso_set_framebuffer(p->cso, &p->framebuffer); + + /* clear the render target */ + p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, p->clear_color, 0, 0); + + /* set misc state we care about */ + cso_set_blend(p->cso, &p->blend); + cso_set_depth_stencil_alpha(p->cso, &p->depthstencil); + cso_set_rasterizer(p->cso, &p->rasterizer); + cso_set_viewport(p->cso, &p->viewport); + + /* sampler */ + cso_single_sampler(p->cso, 0, &p->sampler); + cso_single_sampler_done(p->cso); + + /* texture sampler view */ + cso_set_fragment_sampler_views(p->cso, 1, &p->view); + + /* shaders */ + cso_set_fragment_shader_handle(p->cso, p->fs); + cso_set_vertex_shader_handle(p->cso, p->vs); + + /* vertex element data */ + cso_set_vertex_elements(p->cso, 2, p->velem); + + util_draw_vertex_buffer(p->pipe, + p->vbuf, 0, + PIPE_PRIM_QUADS, + 4, /* verts */ + 2); /* attribs/vert */ + + p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]); +} + +int main(int argc, char** argv) +{ + struct program *p = CALLOC_STRUCT(program); + + init_prog(p); + draw(p); + close_prog(p); + + return 0; +} diff --git a/progs/gallium/trivial/tri.c b/progs/gallium/trivial/tri.c new file mode 100644 index 0000000000..cae1bdb1b1 --- /dev/null +++ b/progs/gallium/trivial/tri.c @@ -0,0 +1,278 @@ +/************************************************************************** + * + * Copyright © 2010 Jakob Bornecrantz + * + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + **************************************************************************/ + + +#define USE_TRACE 0 +#define WIDTH 300 +#define HEIGHT 300 +#define NEAR 30 +#define FAR 1000 +#define FLIP 0 + +/* pipe_*_state structs */ +#include "pipe/p_state.h" +/* pipe_context */ +#include "pipe/p_context.h" +/* pipe_screen */ +#include "pipe/p_screen.h" +/* PIPE_* */ +#include "pipe/p_defines.h" +/* TGSI_SEMANTIC_{POSITION|GENERIC} */ +#include "pipe/p_shader_tokens.h" +/* pipe_buffer_* helpers */ +#include "util/u_inlines.h" + +/* constant state object helper */ +#include "cso_cache/cso_context.h" + +/* debug_dump_surface_bmp */ +#include "util/u_debug.h" +/* util_draw_vertex_buffer helper */ +#include "util/u_draw_quad.h" +/* FREE & CALLOC_STRUCT */ +#include "util/u_memory.h" +/* util_make_[fragment|vertex]_passthrough_shader */ +#include "util/u_simple_shaders.h" + +/* softpipe software driver */ +#include "softpipe/sp_public.h" + +/* null software winsys */ +#include "sw/null/null_sw_winsys.h" + +/* traceing support see src/gallium/drivers/trace/README for more info. */ +#if USE_TRACE +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + +struct program +{ + struct pipe_screen *screen; + struct pipe_context *pipe; + struct cso_context *cso; + + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_vertex_element velem[2]; + + void *vs; + void *fs; + + float clear_color[4]; + + struct pipe_buffer *vbuf; + struct pipe_texture *target; +}; + +static void init_prog(struct program *p) +{ + /* create the software rasterizer */ + p->screen = softpipe_create_screen(null_sw_create()); +#if USE_TRACE + p->screen = trace_screen_create(p->screen); +#endif + p->pipe = p->screen->context_create(p->screen, NULL); + p->cso = cso_create_context(p->pipe); + + /* set clear color */ + p->clear_color[0] = 0.3; + p->clear_color[1] = 0.1; + p->clear_color[2] = 0.3; + p->clear_color[3] = 1.0; + + /* vertex buffer */ + { + float vertices[4][2][4] = { + { + { 0.0f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f } + }, + { + { -0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { + { 0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + } + }; + + p->vbuf = pipe_buffer_create(p->screen, 16, PIPE_BUFFER_USAGE_VERTEX, sizeof(vertices)); + pipe_buffer_write(p->screen, p->vbuf, 0, sizeof(vertices), vertices); + } + + /* render target texture */ + { + struct pipe_texture tmplt; + memset(&tmplt, 0, sizeof(tmplt)); + tmplt.target = PIPE_TEXTURE_2D; + tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ + tmplt.width0 = WIDTH; + tmplt.height0 = HEIGHT; + tmplt.depth0 = 1; + tmplt.last_level = 0; + tmplt.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + p->target = p->screen->texture_create(p->screen, &tmplt); + } + + /* disabled blending/masking */ + memset(&p->blend, 0, sizeof(p->blend)); + p->blend.rt[0].colormask = PIPE_MASK_RGBA; + + /* no-op depth/stencil/alpha */ + memset(&p->depthstencil, 0, sizeof(p->depthstencil)); + + /* rasterizer */ + memset(&p->rasterizer, 0, sizeof(p->rasterizer)); + p->rasterizer.front_winding = PIPE_WINDING_CW; + p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.gl_rasterization_rules = 1; + + /* drawing destination */ + memset(&p->framebuffer, 0, sizeof(p->framebuffer)); + p->framebuffer.width = WIDTH; + p->framebuffer.height = HEIGHT; + p->framebuffer.nr_cbufs = 1; + p->framebuffer.cbufs[0] = p->screen->get_tex_surface(p->screen, p->target, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); + + /* viewport, depth isn't really needed */ + { + float x = 0; + float y = 0; + float z = FAR; + float half_width = (float)WIDTH / 2.0f; + float half_height = (float)HEIGHT / 2.0f; + float half_depth = ((float)FAR - (float)NEAR) / 2.0f; + float scale, bias; + + if (FLIP) { + scale = -1.0f; + bias = (float)HEIGHT; + } else { + scale = 1.0f; + bias = 0.0f; + } + + p->viewport.scale[0] = half_width; + p->viewport.scale[1] = half_height * scale; + p->viewport.scale[2] = half_depth; + p->viewport.scale[3] = 1.0f; + + p->viewport.translate[0] = half_width + x; + p->viewport.translate[1] = (half_height + y) * scale + bias; + p->viewport.translate[2] = half_depth + z; + p->viewport.translate[3] = 0.0f; + } + + /* vertex elements state */ + memset(p->velem, 0, sizeof(p->velem)); + p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */ + p->velem[0].instance_divisor = 0; + p->velem[0].vertex_buffer_index = 0; + p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */ + p->velem[1].instance_divisor = 0; + p->velem[1].vertex_buffer_index = 0; + p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_COLOR }; + const uint semantic_indexes[] = { 0, 0 }; + p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes); + } + + /* fragment shader */ + p->fs = util_make_fragment_passthrough_shader(p->pipe); +} + +static void close_prog(struct program *p) +{ + /* unset all state */ + cso_release_all(p->cso); + + p->pipe->delete_vs_state(p->pipe, p->vs); + p->pipe->delete_fs_state(p->pipe, p->fs); + + pipe_surface_reference(&p->framebuffer.cbufs[0], NULL); + pipe_texture_reference(&p->target, NULL); + pipe_buffer_reference(&p->vbuf, NULL); + + cso_destroy_context(p->cso); + p->pipe->destroy(p->pipe); + p->screen->destroy(p->screen); + + FREE(p); +} + +static void draw(struct program *p) +{ + /* set the render target */ + cso_set_framebuffer(p->cso, &p->framebuffer); + + /* clear the render target */ + p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, p->clear_color, 0, 0); + + /* set misc state we care about */ + cso_set_blend(p->cso, &p->blend); + cso_set_depth_stencil_alpha(p->cso, &p->depthstencil); + cso_set_rasterizer(p->cso, &p->rasterizer); + cso_set_viewport(p->cso, &p->viewport); + + /* shaders */ + cso_set_fragment_shader_handle(p->cso, p->fs); + cso_set_vertex_shader_handle(p->cso, p->vs); + + /* vertex element data */ + cso_set_vertex_elements(p->cso, 2, p->velem); + + util_draw_vertex_buffer(p->pipe, + p->vbuf, 0, + PIPE_PRIM_TRIANGLES, + 3, /* verts */ + 2); /* attribs/vert */ + + p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]); +} + +int main(int argc, char** argv) +{ + struct program *p = CALLOC_STRUCT(program); + + init_prog(p); + draw(p); + close_prog(p); + + return 0; +} diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 3b5a5959ae..6030c8002f 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -26,6 +26,7 @@ PROG_SOURCES = \ convolutions.c \ deriv.c \ fragcoord.c \ + fsraytrace.c \ identity.c \ linktest.c \ mandelbrot.c \ @@ -46,7 +47,8 @@ PROG_SOURCES = \ trirast.c \ twoside.c \ vert-or-frag-only.c \ - vert-tex.c + vert-tex.c \ + vsraytrace.c UTIL_HEADERS = \ extfuncs.h \ diff --git a/progs/glsl/SConscript b/progs/glsl/SConscript index 8f2ebcf69c..02884e5a71 100644 --- a/progs/glsl/SConscript +++ b/progs/glsl/SConscript @@ -8,6 +8,7 @@ progs = [ 'convolutions', 'deriv', 'fragcoord', + 'fsraytrace', 'identity', 'linktest', 'mandelbrot', @@ -27,6 +28,7 @@ progs = [ 'twoside', 'vert-or-frag-only', 'vert-tex', + 'vsraytrace', ] for prog in progs: diff --git a/progs/glsl/fsraytrace.c b/progs/glsl/fsraytrace.c new file mode 100644 index 0000000000..af72a99099 --- /dev/null +++ b/progs/glsl/fsraytrace.c @@ -0,0 +1,412 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; coding: utf-8-unix -*- */ +/* + Copyright (c) 2010 Kristóf Ralovich + + 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 THE + AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <GL/glew.h> +#include <GL/glut.h> +#include "shaderutil.h" +#include <math.h> + +static int Win; +static int WinWidth = 512, WinHeight = 512; +static int mouseGrabbed = 0; +static GLuint vertShader; +static GLuint fragShader; +static GLuint program; +static float rot[9] = {1,0,0, 0,1,0, 0,0,1}; + +static const char* vsSource = + "varying vec2 rayDir; \n" + " \n" + "void main() \n" + "{ \n" + " rayDir = gl_MultiTexCoord0.xy - vec2(0.5,0.5); \n" + " gl_Position = gl_ProjectionMatrix * gl_Vertex; \n" + "}\n"; + +static const char* fsSource = + "const float INF = 9999.9; \n" + "const float EPSILON = 0.00001; \n" + "const vec3 lightPos = vec3(0.0, 8.0, 1.0); \n" + "const vec4 backgroundColor = vec4(0.2,0.3,0.4,1); \n" + " \n" + "varying vec2 rayDir; \n" + " \n" + "uniform mat3 rot; \n" + " \n" + "struct Ray \n" + "{ \n" + "vec3 orig; \n" + "vec3 dir; \n" + "}; \n" + " \n" + "struct Sphere \n" + "{ \n" + " vec3 c; \n" + " float r; \n" + "}; \n" + " \n" + "struct Isec \n" + "{ \n" + " float t; \n" + " int idx; \n" + " vec3 hit; \n" + " vec3 n; \n" + "}; \n" + " \n" +#ifdef __APPLE__ + "Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 ); \n" + "Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 ); \n" + "Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 ); \n" + "Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 ); \n" +#else + "const Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 ); \n" + "const Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 ); \n" + "const Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 ); \n" + "const Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 ); \n" +#endif + " \n" + "// Mesa intel gen4 generates \"unsupported IR in fragment shader 13\" for\n" + "// sqrt, let's work around. \n" + "float \n" + "sqrt_hack(float f2) \n" + "{ \n" + " vec3 v = vec3(f2,0.0,0.0); \n" + " return length(v); \n" + "} \n" + " \n" + "void \n" + "intersect(const in Ray ray, \n" + " const in Sphere sph, \n" + " const in int idx, \n" + " inout Isec isec) \n" + "{ \n" + " // Project both o and the sphere to the plane perpendicular to d \n" + " // and containing c. Let x be the point where the ray intersects \n" + " // the plane. If |x-c| < r, the ray intersects the sphere. \n" + " vec3 o = ray.orig; \n" + " vec3 d = ray.dir; \n" + " vec3 n = -d; \n" + " vec3 c = sph.c; \n" + " float r = sph.r; \n" + " float t = dot(c-o,n)/dot(n,d); \n" + " vec3 x = o+d*t; \n" + " float e = length(x-c); \n" + " if(e > r) \n" + " { \n" + " // no intersection \n" + " return; \n" + " } \n" + " \n" + " // Apply Pythagorean theorem on the (intersection,x,c) triangle \n" + " // to get the distance between c and the intersection. \n" + "#ifndef BUGGY_INTEL_GEN4_GLSL \n" + " float f = sqrt(r*r - e*e); \n" + "#else \n" + " float f = sqrt_hack(r*r - e*e); \n" + "#endif \n" + " float dist = t - f; \n" + " if(dist < 0.0) \n" + " { \n" + " // inside the sphere \n" + " return; \n" + " } \n" + " \n" + " if(dist < EPSILON) \n" + " return; \n" + " \n" + " if(dist > isec.t) \n" + " return; \n" + " \n" + " isec.t = dist; \n" + " isec.idx = idx; \n" + " \n" + " isec.hit = ray.orig + ray.dir * isec.t; \n" + " isec.n = (isec.hit - c) / r; \n" + "} \n" + " \n" + "Isec \n" + "intersect(const in Ray ray, \n" + " const in float max_t /*= INF*/) \n" + "{ \n" + " Isec nearest; \n" + " nearest.t = max_t; \n" + " nearest.idx = -1; \n" + " \n" + " intersect(ray, spheres0, 0, nearest); \n" + " intersect(ray, spheres1, 1, nearest); \n" + " intersect(ray, spheres2, 2, nearest); \n" + " intersect(ray, spheres3, 3, nearest); \n" + " \n" + " return nearest; \n" + "} \n" + " \n" + "vec4 \n" + "idx2color(const in int idx) \n" + "{ \n" + " vec4 diff; \n" + " if(idx == 0) \n" + " diff = vec4(1.0, 0.0, 0.0, 0.0); \n" + " else if(idx == 1) \n" + " diff = vec4(0.0, 1.0, 0.0, 0.0); \n" + " else if(idx == 2) \n" + " diff = vec4(0.0, 0.0, 1.0, 0.0); \n" + " else if(idx == 3) \n" + " diff = vec4(1.0, 1.0, 0.0, 0.0); \n" + " return diff; \n" + "} \n" + " \n" + "vec4 \n" + "trace0(const in Ray ray) \n" + "{ \n" + " Isec isec = intersect(ray, INF); \n" + " \n" + " if(isec.idx == -1) \n" + " { \n" + " return backgroundColor; \n" + " } \n" + " \n" + " vec4 diff = idx2color(isec.idx); \n" + " \n" + " vec3 N = isec.n; \n" + " vec3 L = normalize(lightPos-isec.hit); \n" + " vec3 camera_dir = normalize(ray.orig - isec.hit); \n" + " return dot(N,L)*diff + pow( \n" + " clamp(dot(reflect(-L,N),camera_dir),0.0,1.0),16.0); \n" + "} \n" + " \n" + "vec4 \n" + "trace1(const in Ray ray) \n" + "{ \n" + " Isec isec = intersect(ray, INF); \n" + " \n" + " if(isec.idx == -1) \n" + " { \n" + " return backgroundColor; \n" + " } \n" + " \n" + " Ray reflRay = Ray(isec.hit, reflect(ray.dir, isec.n)); \n" + " \n" + " vec4 reflCol = trace0(reflRay); \n" + " \n" + " vec4 diff = idx2color(isec.idx) + reflCol; \n" + " \n" + " vec3 N = isec.n; \n" + " vec3 L = normalize(lightPos-isec.hit); \n" + " vec3 camera_dir = normalize(ray.orig - isec.hit); \n" + " return dot(N,L)*diff + pow( \n" + " clamp(dot(reflect(-L,N),camera_dir),0.0,1.0),16.0); \n" + "} \n" + " \n" + "void main() \n" + "{ \n" + " const float z = -0.5; \n" + " const vec3 cameraPos = vec3(0,0,3); \n" + " Ray r = Ray(cameraPos, normalize(vec3(rayDir, z) * rot)); \n" + " gl_FragColor = trace1(r); \n" + "}\n"; + +static +float +deg2rad(const float degree) +{ + return( degree * 0.017453292519943295769236907684886F); +} + +static void +rotate_xy(float* mat3, const float degreesAroundX, const float degreesAroundY) +{ + const float rad1 = deg2rad(degreesAroundX); + const float c1 = cosf(rad1); + const float s1 = sinf(rad1); + const float rad2 = deg2rad(degreesAroundY); + const float c2 = cosf(rad2); + const float s2 = sinf(rad2); + mat3[0] = c2; mat3[3] = 0.0F; mat3[6] = s2; + mat3[1] = s1*s2; mat3[4] = c1; mat3[7] = -s1*c2; + mat3[2] = -c1*s2;mat3[5] = s1; mat3[8] = c1*c2; +} + +static void +identity(float* mat3) +{ + mat3[0] = 1.0F; mat3[3] = 0.0F; mat3[6] = 0.0F; + mat3[1] = 0.0F; mat3[4] = 1.0F; mat3[7] = 0.0F; + mat3[2] = 0.0F; mat3[5] = 0.0F; mat3[8] = 1.0F; +} + +static void +Draw(void) +{ + GLint location = glGetUniformLocation(program, "rot"); + static const float m = -10.F; + static const float p = 10.F; + static const float d = -0.5F; + + glUseProgram(program); + glUniformMatrix3fv(location, 1, 0, rot); + + glBegin(GL_QUADS); + { + glTexCoord2f(0.0F, 0.0F); glVertex3f(m, m, d); + glTexCoord2f(1.0F, 0.0F); glVertex3f(p, m, d); + glTexCoord2f(1.0F, 1.0F); glVertex3f(p, p, d); + glTexCoord2f(0.0F, 1.0F); glVertex3f(m, p, d); + } + glEnd(); + glUseProgram(0); + + glutSwapBuffers(); + + { + static int frames = 0; + static int t0 = 0; + static int t1 = 0; + float dt; + frames++; + t1 = glutGet(GLUT_ELAPSED_TIME); + dt = (float)(t1-t0)/1000.0F; + if(dt >= 5.0F) + { + float fps = (float)frames / dt; + printf("%f FPS (%d frames in %f seconds)\n", fps, frames, dt); + frames = 0; + t0 = t1; + } + } +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-10, 10, -10, 10, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +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 +drag(int x, int y) +{ + float scale = 1.5F; + if(mouseGrabbed) + { + static GLfloat xRot = 0, yRot = 0; + xRot = (float)(x - WinWidth/2) / scale; + yRot = (float)(y - WinHeight/2) / scale; + identity(rot); + rotate_xy(rot, yRot, xRot); + glutPostRedisplay(); + } +} + + +static +void +mouse(int button, int state, int x, int y) +{ + mouseGrabbed = (state == GLUT_DOWN); +} + + +static void +Init(void) +{ + glDisable(GL_DEPTH_TEST); + + if(!ShadersSupported()) + { + fprintf(stderr, "Shaders are not supported!\n"); + exit(-1); + } + + vertShader = CompileShaderText(GL_VERTEX_SHADER, vsSource); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fsSource); + program = LinkShaders(vertShader, fragShader); + glUseProgram(0); + + if(glGetError() != 0) + { + fprintf(stderr, "Shaders were not loaded!\n"); + exit(-1); + } + + if(!glIsShader(vertShader)) + { + fprintf(stderr, "Vertex shader failed!\n"); + exit(-1); + } + + if(!glIsProgram(program)) + { + fprintf(stderr, "Shader program failed!\n"); + exit(-1); + } + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); +} + + +int +main(int argc, char *argv[]) +{ + glutInitWindowSize(WinWidth, WinHeight); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMouseFunc(mouse); + glutMotionFunc(drag); + glutIdleFunc(Draw); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/vsraytrace.c b/progs/glsl/vsraytrace.c new file mode 100644 index 0000000000..64d928883e --- /dev/null +++ b/progs/glsl/vsraytrace.c @@ -0,0 +1,401 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; coding: utf-8-unix -*- */ +/* + Copyright (c) 2010 Kristóf Ralovich + + 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 THE + AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <GL/glew.h> +#include <GL/glut.h> +#include "shaderutil.h" +#include <math.h> + +static int Win; +static int WinWidth = 256, WinHeight = 256; +static GLboolean mouseGrabbed = GL_FALSE; +static GLuint vertShader; +static GLuint program; +float rot[9] = {1,0,0, 0,1,0, 0,0,1}; + +static const char* vsSource = + "const float INF = 9999.9; \n" + "const float EPSILON = 0.00001; \n" + "const vec3 lightPos = vec3(0.0, 8.0, 1.0); \n" + "const vec4 backgroundColor = vec4(0.2,0.3,0.4,1); \n" + " \n" + "uniform mat3 rot; \n" + " \n" + "struct Ray \n" + "{ \n" + "vec3 orig; \n" + "vec3 dir; \n" + "}; \n" + " \n" + "struct Sphere \n" + "{ \n" + " vec3 c; \n" + " float r; \n" + "}; \n" + " \n" + "struct Isec \n" + "{ \n" + " float t; \n" + " int idx; \n" + " vec3 hit; \n" + " vec3 n; \n" + "}; \n" + " \n" +#ifdef __APPLE__ + "Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 ); \n" + "Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 ); \n" + "Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 ); \n" + "Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 ); \n" +#else + "const Sphere spheres0 = Sphere( vec3(0.0,0.0,-1.0), 0.5 ); \n" + "const Sphere spheres1 = Sphere( vec3(-3.0,0.0,-1.0), 1.5 ); \n" + "const Sphere spheres2 = Sphere( vec3(0.0,3.0,-1.0), 0.5 ); \n" + "const Sphere spheres3 = Sphere( vec3(2.0,0.0,-1.0), 1.0 ); \n" +#endif + " \n" + "// Mesa intel gen4 generates \"unsupported IR in fragment shader 13\" for\n" + "// sqrt, let's work around. \n" + "float \n" + "sqrt_hack(float f2) \n" + "{ \n" + " vec3 v = vec3(f2,0.0,0.0); \n" + " return length(v); \n" + "} \n" + " \n" + "void \n" + "intersect(const in Ray ray, \n" + " const in Sphere sph, \n" + " const in int idx, \n" + " inout Isec isec) \n" + "{ \n" + " // Project both o and the sphere to the plane perpendicular to d \n" + " // and containing c. Let x be the point where the ray intersects \n" + " // the plane. If |x-c| < r, the ray intersects the sphere. \n" + " vec3 o = ray.orig; \n" + " vec3 d = ray.dir; \n" + " vec3 n = -d; \n" + " vec3 c = sph.c; \n" + " float r = sph.r; \n" + " float t = dot(c-o,n)/dot(n,d); \n" + " vec3 x = o+d*t; \n" + " float e = length(x-c); \n" + " if(e > r) \n" + " { \n" + " // no intersection \n" + " return; \n" + " } \n" + " \n" + " // Apply Pythagorean theorem on the (intersection,x,c) triangle \n" + " // to get the distance between c and the intersection. \n" + "#define BUGGY_INTEL_GEN4_GLSL 1 \n" + "#ifndef BUGGY_INTEL_GEN4_GLSL \n" + " float f = sqrt(r*r - e*e); \n" + "#else \n" + " float f = sqrt_hack(r*r - e*e); \n" + "#endif \n" + " float dist = t - f; \n" + " if(dist < 0.0) \n" + " { \n" + " // inside the sphere \n" + " return; \n" + " } \n" + " \n" + " if(dist < EPSILON) \n" + " return; \n" + " \n" + " if(dist > isec.t) \n" + " return; \n" + " \n" + " isec.t = dist; \n" + " isec.idx = idx; \n" + " \n" + " isec.hit = ray.orig + ray.dir * isec.t; \n" + " isec.n = (isec.hit - c) / r; \n" + "} \n" + " \n" + "Isec \n" + "intersect(const in Ray ray, \n" + " const in float max_t /*= INF*/) \n" + "{ \n" + " Isec nearest; \n" + " nearest.t = max_t; \n" + " nearest.idx = -1; \n" + " \n" + " intersect(ray, spheres0, 0, nearest); \n" + " intersect(ray, spheres1, 1, nearest); \n" + " intersect(ray, spheres2, 2, nearest); \n" + " intersect(ray, spheres3, 3, nearest); \n" + " \n" + " return nearest; \n" + "} \n" + " \n" + "vec4 \n" + "idx2color(const in int idx) \n" + "{ \n" + " vec4 diff; \n" + " if(idx == 0) \n" + " diff = vec4(1.0, 0.0, 0.0, 0.0); \n" + " else if(idx == 1) \n" + " diff = vec4(0.0, 1.0, 0.0, 0.0); \n" + " else if(idx == 2) \n" + " diff = vec4(0.0, 0.0, 1.0, 0.0); \n" + " else if(idx == 3) \n" + " diff = vec4(1.0, 1.0, 0.0, 0.0); \n" + " return diff; \n" + "} \n" + " \n" + "vec4 \n" + "trace0(const in Ray ray) \n" + "{ \n" + " Isec isec = intersect(ray, INF); \n" + " \n" + " if(isec.idx == -1) \n" + " { \n" + " return backgroundColor; \n" + " } \n" + " \n" + " vec4 diff = idx2color(isec.idx); \n" + " \n" + " vec3 N = isec.n; \n" + " vec3 L = normalize(lightPos-isec.hit); \n" + " vec3 camera_dir = normalize(ray.orig - isec.hit); \n" + " return dot(N,L)*diff + pow( \n" + " clamp(dot(reflect(-L,N),camera_dir),0.0,1.0),16.0); \n" + "} \n" + " \n" + "vec4 \n" + "trace1(const in Ray ray) \n" + "{ \n" + " Isec isec = intersect(ray, INF); \n" + " \n" + " if(isec.idx == -1) \n" + " { \n" + " return backgroundColor; \n" + " } \n" + " \n" + " Ray reflRay = Ray(isec.hit, reflect(ray.dir, isec.n)); \n" + " \n" + " vec4 reflCol = trace0(reflRay); \n" + " \n" + " vec4 diff = idx2color(isec.idx) + reflCol; \n" + " \n" + " vec3 N = isec.n; \n" + " vec3 L = normalize(lightPos-isec.hit); \n" + " vec3 camera_dir = normalize(ray.orig - isec.hit); \n" + " return dot(N,L)*diff + pow( \n" + " clamp(dot(reflect(-L,N),camera_dir),0.0,1.0),16.0); \n" + "} \n" + " \n" + "void main() \n" + "{ \n" + " const vec3 cameraPos = vec3(0,0,3); \n" + " vec3 rayDir = normalize(vec3(gl_Vertex.x, gl_Vertex.y, -1.0) * rot);\n" + " Ray ray = Ray(cameraPos, rayDir); \n" + " gl_Position = gl_Vertex; \n" + " gl_FrontColor = trace1(ray); \n" + "}\n"; + + +static +float +deg2rad(const float degree) +{ + return( degree * 0.017453292519943295769236907684886F); +} + +static void +rotate_xy(float* mat3, const float degreesAroundX, const float degreesAroundY) +{ + const float rad1 = deg2rad(degreesAroundX); + const float c1 = cosf(rad1); + const float s1 = sinf(rad1); + const float rad2 = deg2rad(degreesAroundY); + const float c2 = cosf(rad2); + const float s2 = sinf(rad2); + mat3[0] = c2; mat3[3] = 0.0F; mat3[6] = s2; + mat3[1] = s1*s2; mat3[4] = c1; mat3[7] = -s1*c2; + mat3[2] = -c1*s2;mat3[5] = s1; mat3[8] = c1*c2; +} + +static void +identity(float* mat3) +{ + mat3[0] = 1.0F; mat3[3] = 0.0F; mat3[6] = 0.0F; + mat3[1] = 0.0F; mat3[4] = 1.0F; mat3[7] = 0.0F; + mat3[2] = 0.0F; mat3[5] = 0.0F; mat3[8] = 1.0F; +} + +static void +Draw(void) +{ + const float w = 0.5F * WinWidth; + const float h = 0.5F * WinHeight; + int x,y; + + GLint location = glGetUniformLocation(program, "rot"); + + glUseProgram(program); + glUniformMatrix3fv(location, 1, 0, rot); + glBegin(GL_POINTS); + for(y = 0; y < WinHeight; y++) + { + for(x = 0; x < WinWidth; x++) + { + const float posx = x / w - 1.0F; + const float posy = y / h - 1.0F; + glVertex2f(posx, posy); + } + } + glEnd(); + glUseProgram(0); + + glutSwapBuffers(); + + { + static int frames = 0; + static int t0 = 0; + static int t1 = 0; + float dt; + frames++; + t1 = glutGet(GLUT_ELAPSED_TIME); + dt = (float)(t1-t0)/1000.0F; + if (dt >= 5.0F) + { + float fps = (float)frames / dt; + printf("%f FPS (%d frames in %f seconds)\n", fps, frames, dt); + frames = 0; + t0 = t1; + } + } +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +Key(unsigned char key, int x, int y) +{ + if(key == 27) + { + glutDestroyWindow(Win); + exit(0); + } + glutPostRedisplay(); +} + + +static +void +drag(int x, int y) +{ + float scale = 1.5F; + if(mouseGrabbed) + { + static GLfloat xRot = 0, yRot = 0; + xRot = (float)(x - WinWidth/2) / scale; + yRot = (float)(y - WinHeight/2) / scale; + identity(rot); + rotate_xy(rot, yRot, xRot); + glutPostRedisplay(); + } +} + + +static +void +mouse(int button, int state, int x, int y) +{ + mouseGrabbed = (state == GLUT_DOWN); +} + + +static void +Init(void) +{ + glDisable(GL_DEPTH_TEST); + + if(!ShadersSupported()) + { + fprintf(stderr, "Shaders are not supported!\n"); + exit(-1); + } + + vertShader = CompileShaderText(GL_VERTEX_SHADER, vsSource); + program = LinkShaders(vertShader, 0); + glUseProgram(0); + + if(glGetError() != 0) + { + fprintf(stderr, "Shaders were not loaded!\n"); + exit(-1); + } + + if(!glIsShader(vertShader)) + { + fprintf(stderr, "Vertex shader failed!\n"); + exit(-1); + } + + if(!glIsProgram(program)) + { + fprintf(stderr, "Shader program failed!\n"); + exit(-1); + } + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); +} + + +int +main(int argc, char *argv[]) +{ + glutInitWindowSize(WinWidth, WinHeight); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutIdleFunc(Draw); + glutMouseFunc(mouse); + glutMotionFunc(drag); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/samples/copy.c b/progs/samples/copy.c index 391c637d6f..353a3a2e1a 100644 --- a/progs/samples/copy.c +++ b/progs/samples/copy.c @@ -25,6 +25,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <GL/glew.h> #include <GL/glut.h> @@ -35,7 +36,6 @@ GLint windW, windH; char *fileName = 0; PPMImage *image; -float point[3]; float zoom; GLint x, y; @@ -97,27 +97,27 @@ static void Mouse(int button, int state, int mouseX, int mouseY) static void Draw(void) { + GLint src[3], dst[3]; glClear(GL_COLOR_BUFFER_BIT); - point[0] = (windW / 2) - (image->sizeX / 2); - point[1] = (windH / 2) - (image->sizeY / 2); - point[2] = 0; - glRasterPos3fv(point); + src[0] = (int) ((windW / 2.0) - (image->sizeX / 2.0)); + src[1] = (int) ((windH / 2.0) - (image->sizeY / 2.0)); + src[2] = 0; + glWindowPos3ivARB(src); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelZoom(1.0, 1.0); glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image->data); - point[0] = (float)x; - point[1] = windH - (float)y; - point[2] = 0.0; - glRasterPos3fv(point); + dst[0] = x; + dst[1] = windH - y; + dst[2] = 0; + glWindowPos3ivARB(dst); glPixelZoom(zoom, zoom); - glCopyPixels((windW/2)-(image->sizeX/2), - (windH/2)-(image->sizeY/2), + glCopyPixels(src[0], src[1], image->sizeX, image->sizeY, GL_COLOR); glFlush(); @@ -170,8 +170,8 @@ int main(int argc, char **argv) image = LoadPPM(fileName); - windW = 300; - windH = 300; + windW = 2*300; + windH = 2*300; glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH); type = GLUT_RGB; @@ -182,6 +182,7 @@ int main(int argc, char **argv) exit(1); } + glewInit(); Init(); glutReshapeFunc(Reshape); diff --git a/progs/samples/loadppm.c b/progs/samples/loadppm.c index be056d6294..adae9b491e 100644 --- a/progs/samples/loadppm.c +++ b/progs/samples/loadppm.c @@ -9,7 +9,7 @@ static PPMImage *LoadPPM(const char *filename) char buff[16]; PPMImage *result; FILE *fp; - int maxval; + int maxval, w, h; fp = fopen(filename, "rb"); if (!fp) @@ -37,11 +37,13 @@ static PPMImage *LoadPPM(const char *filename) exit(1); } - if (fscanf(fp, "%lu %lu", &result->sizeX, &result->sizeY) != 2) + if (fscanf(fp, "%d %d", &w, &h) != 2) { fprintf(stderr, "Error loading image `%s'\n", filename); exit(1); } + result->sizeX = w; + result->sizeY = h; if (fscanf(fp, "%d", &maxval) != 1) { diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 67efc3b7a9..6bb0249e17 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -41,6 +41,7 @@ SOURCES = \ copypixrate.c \ crossbar.c \ cva.c \ + cva_huge.c \ cylwrap.c \ drawbuffers.c \ drawbuffers2.c \ diff --git a/progs/tests/SConscript b/progs/tests/SConscript index 3580ba914d..037a0c35da 100644 --- a/progs/tests/SConscript +++ b/progs/tests/SConscript @@ -9,7 +9,6 @@ glx_progs = [ 'getprocaddress', 'jkrahntest', 'sharedtex', - 'texcompress2', 'texobjshare', ] @@ -45,6 +44,7 @@ progs = [ 'copypixrate', 'crossbar', 'cva', + 'cva_huge', 'cylwrap', 'drawbuffers', 'drawbuffers2', diff --git a/progs/tests/cva_huge.c b/progs/tests/cva_huge.c new file mode 100644 index 0000000000..88ec2af2a8 --- /dev/null +++ b/progs/tests/cva_huge.c @@ -0,0 +1,232 @@ +/* + * Copyright © 2010 Pauli Nieminen + * + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 case for huge cva arrays. Mesa code has to split this to multiple VBOs + * which had memory access error. + * This test case doesn't render incorrectly but valgrind showed the memory + * access error. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stddef.h> /* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ +#ifdef _WIN32 +#include <windows.h> +#endif +#define GL_GLEXT_LEGACY +#include <GL/glut.h> + +GLfloat *verts; + +GLubyte *color; + +GLuint *indices; + +#define rows 1000 /* Create 1000x1000 vertex grid */ +#define row_width 5000.0 +#define grid_depth -50.0 +GLuint nr_verts_in_row = rows; +GLuint nr_indices_in_strip = rows * 2; + +GLboolean double_buffer; +GLboolean compiled = GL_TRUE; + +static void generate_verts( void ) +{ + unsigned x, y; + GLfloat step = row_width /(GLfloat)(nr_verts_in_row - 1); + verts = malloc(sizeof(verts[0]) * 4 * nr_verts_in_row * nr_verts_in_row); + + for (y = 0; y < nr_verts_in_row; ++y) { + for (x = 0; x < nr_verts_in_row; ++x) { + unsigned idx = 4*(x + y * nr_verts_in_row); + verts[idx + 0] = step * x - row_width/2.0; + verts[idx + 1] = step * y - row_width/2.0; + /* deep enough not to be vissible */ + verts[idx + 2] = grid_depth; + verts[idx + 3] = 0.0; + } + } + glVertexPointer( 3, GL_FLOAT, sizeof(verts[0])*4, verts ); +} + +static void generate_colors( void ) +{ + unsigned x, y; + GLfloat step = 255.0/(GLfloat)(nr_verts_in_row - 1); + color = malloc(sizeof(color[0]) * 4 * nr_verts_in_row * nr_verts_in_row); + + for (y = 0; y < nr_verts_in_row; ++y) { + for (x = 0; x < nr_verts_in_row; ++x) { + unsigned idx = 4*(x + y * nr_verts_in_row); + color[idx + 0] = (GLubyte)(step * x); + color[idx + 1] = 0x00; + color[idx + 2] = (GLubyte)(step * y); + color[idx + 3] = 0x00; + } + } + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, color ); +} + +static void generate_indices( void ) +{ + unsigned strip, i; + + /* indice size * number of strips * number of indices in strip */ + indices = malloc(sizeof(indices[0]) * (nr_verts_in_row - 1) * + (nr_indices_in_strip)); + + for (strip = 0; strip < nr_verts_in_row - 1; strip += 2) { + for (i = 0; i < nr_indices_in_strip; i+=2) { + unsigned idx = i + strip * nr_indices_in_strip; + unsigned idx2 = (nr_indices_in_strip - i - 2) + (strip + + 1) * (nr_indices_in_strip); + indices[idx + 1] = i/2 + strip*nr_verts_in_row; + indices[idx] = i/2 + (strip + 1)*nr_verts_in_row; + if (strip + 1 < nr_verts_in_row - 1) { + indices[idx2] = i/2 + (strip + 1)*nr_verts_in_row; + indices[idx2 + 1] = i/2 + (strip + 2)*nr_verts_in_row; + } + } + } +} + +static void init( void ) +{ + + + generate_verts(); + generate_colors(); + generate_indices(); + + glClearColor( 0.0, 0.0, 0.0, 0.0 ); + glShadeModel( GL_SMOOTH ); + + glEnableClientState( GL_VERTEX_ARRAY ); + glEnableClientState( GL_COLOR_ARRAY ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -100.0, 100.0, -100.0, 100.0, 1.0, 100.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + +#ifdef GL_EXT_compiled_vertex_array + if ( compiled ) { + glLockArraysEXT( 0, rows * rows ); + } +#endif +} + +static void display( void ) +{ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glDrawElements( GL_TRIANGLE_STRIP, nr_indices_in_strip * (nr_verts_in_row - 1) , GL_UNSIGNED_INT, indices ); + + if ( double_buffer ) + glutSwapBuffers(); + else + glFlush(); +} + +static void keyboard( unsigned char key, int x, int y ) +{ + switch ( key ) { + case 27: + exit( 0 ); + break; + } + + glutPostRedisplay(); +} + +static GLboolean args( int argc, char **argv ) +{ + GLint i; + + double_buffer = GL_TRUE; + + for ( i = 1 ; i < argc ; i++ ) { + if ( strcmp( argv[i], "-sb" ) == 0 ) { + double_buffer = GL_FALSE; + } else if ( strcmp( argv[i], "-db" ) == 0 ) { + double_buffer = GL_TRUE; + } else { + fprintf( stderr, "%s (Bad option).\n", argv[i] ); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main( int argc, char **argv ) +{ + GLenum type; + char *string; + double version; + + glutInit( &argc, argv ); + + if ( args( argc, argv ) == GL_FALSE ) { + exit( 1 ); + } + + type = GLUT_RGB | GLUT_DEPTH; + type |= ( double_buffer ) ? GLUT_DOUBLE : GLUT_SINGLE; + + glutInitDisplayMode( type ); + glutInitWindowSize( 250, 250 ); + glutInitWindowPosition( 100, 100 ); + glutCreateWindow( "CVA Test" ); + + /* Make sure the server supports GL 1.2 vertex arrays. + */ + string = (char *) glGetString( GL_VERSION ); + + version = atof(string); + if ( version < 1.2 ) { + fprintf( stderr, "This program requires OpenGL 1.2 vertex arrays.\n" ); + exit( -1 ); + } + + /* See if the server supports compiled vertex arrays. + */ + string = (char *) glGetString( GL_EXTENSIONS ); + + if ( !strstr( string, "GL_EXT_compiled_vertex_array" ) ) { + fprintf( stderr, "Compiled vertex arrays not supported by this renderer.\n" ); + compiled = GL_FALSE; + } + + init(); + + glutDisplayFunc( display ); + glutKeyboardFunc( keyboard ); + glutMainLoop(); + + return 0; +} diff --git a/progs/tests/stencil_twoside.c b/progs/tests/stencil_twoside.c index 7d871e5877..1010139a20 100644 --- a/progs/tests/stencil_twoside.c +++ b/progs/tests/stencil_twoside.c @@ -26,7 +26,7 @@ * \file stencil_twoside.c * * Simple test of GL_ATI_separate_stencil (or the OGL 2.0 equivalent) functionality. - * Four squares are drawn + * Five squares (or six if stencil wrap is available) are drawn * with different stencil modes, but all should be rendered with the same * final color. */ @@ -37,7 +37,7 @@ #include <GL/glut.h> static int use20syntax = 1; -static int Width = 550; +static int Width = 650; static int Height = 200; static const GLfloat Near = 5.0, Far = 25.0; @@ -70,7 +70,7 @@ static void Display( void ) */ glDisable(GL_STENCIL_TEST); - glTranslatef(-6.0, 0, 0); + glTranslatef(-7.0, 0, 0); glBegin(GL_QUADS); glColor3f( 0.5, 0.5, 0.5 ); glVertex2f(-1, -1); @@ -85,6 +85,9 @@ static void Display( void ) /* Draw the first two squares using incr for the affected face */ + /************************************************************************* + * 2nd square + */ if (use20syntax) { stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); @@ -98,8 +101,8 @@ static void Display( void ) glTranslatef(3.0, 0, 0); glBegin(GL_QUADS); glColor3f( 0.9, 0.9, 0.9 ); - /* this should be front facing */ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + /* this should be front facing */ glVertex2f(-1, -1); glVertex2f( 1, -1); glVertex2f( 1, 1); @@ -107,6 +110,7 @@ static void Display( void ) } glEnd(); + /* stencil vals should be equal to max_stencil */ glStencilFunc(GL_EQUAL, max_stencil, ~0); glBegin(GL_QUADS); glColor3f( 0.5, 0.5, 0.5 ); @@ -116,6 +120,9 @@ static void Display( void ) glVertex2f(-1, 1); glEnd(); + /************************************************************************* + * 3rd square + */ if (use20syntax) { stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); @@ -129,9 +136,8 @@ static void Display( void ) glTranslatef(3.0, 0, 0); glBegin(GL_QUADS); glColor3f( 0.9, 0.9, 0.9 ); - - /* this should be back facing */ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + /* this should be back facing */ glVertex2f(-1, -1); glVertex2f(-1, 1); glVertex2f( 1, 1); @@ -139,6 +145,7 @@ static void Display( void ) } glEnd(); + /* stencil vals should be equal to max_stencil */ glStencilFunc(GL_EQUAL, max_stencil, ~0); glBegin(GL_QUADS); glColor3f( 0.5, 0.5, 0.5 ); @@ -148,6 +155,9 @@ static void Display( void ) glVertex2f(-1, 1); glEnd(); + /************************************************************************* + * 4th square + */ if (use20syntax) { stencil_func_separate(GL_FRONT, GL_NEVER, 0, ~0); stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); @@ -161,15 +171,13 @@ static void Display( void ) glTranslatef(3.0, 0, 0); glBegin(GL_QUADS); glColor3f( 0.9, 0.9, 0.9 ); - - /* this should be back facing */ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { - /* this should be back facing */ + /* this should be back facing */ glVertex2f(-1, -1); glVertex2f(-1, 1); glVertex2f( 1, 1); glVertex2f( 1, -1); - /* this should be front facing */ + /* this should be front facing */ glVertex2f(-1, -1); glVertex2f( 1, -1); glVertex2f( 1, 1); @@ -177,6 +185,7 @@ static void Display( void ) } glEnd(); + /* stencil vals should be equal to max_stencil */ glStencilFunc(GL_EQUAL, max_stencil, ~0); glBegin(GL_QUADS); glColor3f( 0.5, 0.5, 0.5 ); @@ -186,6 +195,9 @@ static void Display( void ) glVertex2f(-1, 1); glEnd(); + /************************************************************************* + * 5th square + */ if (use20syntax) { stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); @@ -193,21 +205,19 @@ static void Display( void ) else { stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0); } - stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); - stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); + stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); + stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); glTranslatef(3.0, 0, 0); glBegin(GL_QUADS); glColor3f( 0.9, 0.9, 0.9 ); - - /* this should be back facing */ for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { - /* this should be back facing */ + /* this should be back facing */ glVertex2f(-1, -1); glVertex2f(-1, 1); glVertex2f( 1, 1); glVertex2f( 1, -1); - /* this should be front facing */ + /* this should be front facing */ glVertex2f(-1, -1); glVertex2f( 1, -1); glVertex2f( 1, 1); @@ -224,6 +234,47 @@ static void Display( void ) glVertex2f(-1, 1); glEnd(); + /************************************************************************* + * 6th square + */ + if (glutExtensionSupported("GL_EXT_stencil_wrap")) { + if (use20syntax) { + stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0); + stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0); + } + else { + stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0); + } + stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP); + stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); + + glTranslatef(3.0, 0, 0); + glBegin(GL_QUADS); + glColor3f( 0.9, 0.9, 0.9 ); + for ( i = 0 ; i < (max_stencil + 5) ; i++ ) { + /* this should be back facing */ + glVertex2f(-1, -1); + glVertex2f(-1, 1); + glVertex2f( 1, 1); + glVertex2f( 1, -1); + /* this should be front facing */ + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + } + glEnd(); + + glStencilFunc(GL_EQUAL, 260 - 255, ~0); + glBegin(GL_QUADS); + glColor3f( 0.5, 0.5, 0.5 ); + glVertex2f(-1, -1); + glVertex2f( 1, -1); + glVertex2f( 1, 1); + glVertex2f(-1, 1); + glEnd(); + } + glPopMatrix(); glutSwapBuffers(); @@ -278,7 +329,7 @@ static void Init( void ) stencil_func_separate_ati = (PFNGLSTENCILFUNCSEPARATEATIPROC) glutGetProcAddress( "glStencilFuncSeparateATI" ); stencil_op_separate = (PFNGLSTENCILOPSEPARATEPROC) glutGetProcAddress( "glStencilOpSeparate" ); - printf("\nAll 5 squares should be the same color.\n"); + printf("\nAll 5 (or 6) squares should be the same color.\n"); } diff --git a/progs/trivial/tri-stencil.c b/progs/trivial/tri-stencil.c index 9f68bca914..d66b68c415 100644 --- a/progs/trivial/tri-stencil.c +++ b/progs/trivial/tri-stencil.c @@ -77,6 +77,7 @@ static void Draw(void) glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + /* red triangle (setting stencil to 1) */ glColor3ub(200, 0, 0); glBegin(GL_POLYGON); glVertex3i(-4, -4, 0); @@ -88,6 +89,7 @@ static void Draw(void) glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_INCR, GL_KEEP, GL_DECR); + /* green quad (if over red, decr stencil to 0, else incr to 1) */ glColor3ub(0, 200, 0); glBegin(GL_POLYGON); glVertex3i(3, 3, 0); @@ -101,6 +103,7 @@ static void Draw(void) glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + /* blue quad (where stencil == 1) */ glColor3ub(0, 0, 200); glBegin(GL_POLYGON); glVertex3f(2.5, 2.5, 0); diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile index f81aafe00f..660c540657 100644 --- a/progs/xdemos/Makefile +++ b/progs/xdemos/Makefile @@ -9,7 +9,7 @@ INCDIR = $(TOP)/include LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) # Add X11 and pthread libs to satisfy GNU gold. -APP_LIB_DEPS += $(X_LIBS) -lpthread +APP_LIB_DEPS += $(X11_LIBS) -lpthread LIBS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) $(APP_LIB_DEPS) |