shiro #1907(2007/08/06 04:34 GMT) [ Scheme ] Rating0/0=0.00
無駄に遠回りしてみました。 異なったピクセル数の集計をグラフィクスハードウェアにやらせています。 8bit/colorプレーンでオーバフローが起きないように、1024x768ぶんの ビットマップを3分割し、R、G、Bコンポーネントがそれぞれ1または0の 512x512のテクスチャにして、それを256分割して32x32の正方形に加算で 貼込んで、CPU側に読み戻して集計してます。 残念ながら速度はそう速くなく、Pen4 2.0GHz/GeForce 6800/Linux で比較部分が 2.1秒程度。 細かく計測するとglBitmapでの転送がほとんどの時間(1.8秒以上)を占めています。 512x512 一枚の転送に6msくらいかかってるので何か間違えているの だろうかとも思ったんですが、転送サイズを変えてみると綺麗にサイズに 比例してるし、glDrawPixelsなどはそんなに遅くないので、glBitmapで 巨大なイメージを送る方が悪いってことかなあ。(ドライバはNVIDIAのものです)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
(use gl) (use gl.glut) (use gauche.uvector) (use gauche.sequence) (use gauche.time) (use srfi-42) (define *varray* (let1 v (make-f32vector (* 5 4 256)) (do-ec (: x 16) (: y 16) (let ((ind (* (+ (* x 16) y) 5 4)) (x0 (/. x 16)) (x1 (/. (+ x 1) 16)) (y0 (/. y 16)) (y1 (/. (+ y 1) 16))) ;; (s, t, x, y, z) * 4 (set! (subseq v ind (+ ind 20)) `(,x0 ,y0 0 0 0 ,x0 ,y1 0 32 0 ,x1 ,y1 32 32 0 ,x1 ,y0 32 0 0)))) v)) (define *v1* (make-u8vector (* 32 32 3) 1)) (define *texname* 0) (define (count-pixels bitmap) (define (draw-source cnt color) (gl-color color) (gl-raster-pos 0 0) (gl-bitmap 512 512 0 0 0 0 (uvector-alias <u8vector> bitmap (* cnt (* (/ 1024 8) 256)) (* (+ cnt 1) (* (/ 1024 8) 256))))) (define (make-texture) (gl-clear GL_COLOR_BUFFER_BIT) (draw-source 0 '#u8(1 0 0)) (draw-source 1 '#u8(0 1 0)) (draw-source 2 '#u8(0 0 1)) (gl-copy-tex-image-2d GL_TEXTURE_2D 0 GL_RGB 0 0 512 512 0)) (define (accumulate) (gl-clear GL_COLOR_BUFFER_BIT) (gl-color 0 0 0) (gl-enable GL_TEXTURE_2D) (gl-draw-arrays GL_QUADS 0 (* 4 256)) (gl-disable GL_TEXTURE_2D)) (define (count) (let1 v (gl-read-pixels 0 0 32 32 GL_RGB GL_UNSIGNED_BYTE) (u8vector-dot *v1* v))) (make-texture) (accumulate) (until (gl-get-error) (pa$ = GL_NO_ERROR) => err (print "glError: "(glu-error-string err))) (count)) (define (find-closest-pic vec pics) (values-ref (fold2 (lambda (pic i minscore) (let1 score (count-pixels (u8vector-xor vec pic)) (if (< score (cdr minscore)) (values (+ i 1) (cons i score)) (values (+ i 1) minscore)))) 0 '(0 . #i1/0) pics) 1)) (define (doit) (print (time (find-closest-pic (car *vecs*) (cdr *vecs*)))) (exit 0)) (define (main args) (glut-init args) (glut-init-display-mode (logior GLUT_SINGLE GLUT_RGB)) (glut-init-window-size 512 512) (glut-create-window (car args)) (gl-pixel-store GL_UNPACK_ALIGNMENT 1) (gl-clear-color 0 0 0 0) (gl-viewport 0 0 512 512) (gl-matrix-mode GL_PROJECTION) (glu-ortho-2d 0 512 0 512) (gl-matrix-mode GL_MODELVIEW) (gl-load-identity) (gl-enable GL_BLEND) (gl-blend-func GL_ONE GL_ONE) (gl-shade-model GL_FLAT) (set! *texname* (ref (gl-gen-textures 1) 0)) (gl-bind-texture GL_TEXTURE_2D *texname*) (gl-tex-parameter GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST) (gl-tex-parameter GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST) (gl-tex-env GL_TEXTURE_ENV GL_TEXTURE_ENV_MODE GL_ADD) (gl-interleaved-arrays GL_T2F_V3F *varray*) (glut-display-func doit) (glut-main-loop) 0) ;;; ;;; test data generation ;;; (use srfi-27) (define (generate-random-pics n) (list-ec (: k n) (let1 v (make-u8vector (/ (* 1024 768) 8)) (do-ec (: i (/ (* 1024 768) 8)) (u8vector-set! v i (random-integer (expt 2 8)))) v))) (define *vecs* (generate-random-pics 100))
Rating0/0=0.00-0+
[ reply ]
shiro
#1907()
[
Scheme
]
Rating0/0=0.00
Rating0/0=0.00-0+
[ reply ]