•  

    年度情绪:杯具

    年度难忘:结婚

    年度酝酿:新房装修

    年度进步:除了年龄,还有别的吗?

    年度遗憾:十年A股重新轮回




    年度饮癖:绿茶

    年度餐馆:软件园食堂

    年度交通:地铁

    年度电影:《再见我们的幼儿园》

    年度书籍:《藏地密码》

    年度报纸:时代报

    年度电视剧:

    年度电视节目:非诚勿扰



    年度网站:Google Reader、豆瓣、开心网、新浪微博、来看PSP中文网、Geek3D

    年度博客:小众软件、麦田音乐网

    年度软件:Firefox、SMPlayer、家财通、iTunes

    年度手机软件:QReader

    年度欣慰:继续坚持长期投资理念

    年度伤感:中国A股“万水千山总是情 少跌一点行不行”

  • 由于原来的链接( http://www.nathanm.com/photoshop-blending-math/)好像无法访问,所以备份在这里,以便参考。

    Been working on programmatically blending bitmaps. Below are the macros that I’ve come up, borrowing the some of the formulas from other websites (see sources at the bottom of this post).

    Channel blending

    ?
    #define ChannelBlend_Normal(B,L)     ((uint8)(B))
    #define ChannelBlend_Lighten(B,L)    ((uint8)((L > B) ? L:B))
    #define ChannelBlend_Darken(B,L)     ((uint8)((L > B) ? B:L))
    #define ChannelBlend_Multiply(B,L)   ((uint8)((B * L) / 255))
    #define ChannelBlend_Average(B,L)    ((uint8)((B + L) / 2))
    #define ChannelBlend_Add(B,L)        ((uint8)(min(255, (B + L))))
    #define ChannelBlend_Subtract(B,L)   ((uint8)((B + L < 255) ? 0:(B + L - 255)))
    #define ChannelBlend_Difference(B,L) ((uint8)(abs(B - L)))
    #define ChannelBlend_Negation(B,L)   ((uint8)(255 - abs(255 - B - L)))
    #define ChannelBlend_Screen(B,L)     ((uint8)(255 - (((255 - B) * (255 - L)) >> 8)))
    #define ChannelBlend_Exclusion(B,L)  ((uint8)(B + L - 2 * B * L / 255))
    #define ChannelBlend_Overlay(B,L)    ((uint8)((L < 128) ? (2 * B * L / 255):(255 - 2 * (255 - B) * (255 - L) / 255)))
    #define ChannelBlend_SoftLight(B,L)  ((uint8)((L < 128)?(2*((B>>1)+64))*((float)L/255):(255-(2*(255-((B>>1)+64))*(float)(255-L)/255))))
    #define ChannelBlend_HardLight(B,L)  (ChannelBlend_Overlay(L,B))
    #define ChannelBlend_ColorDodge(B,L) ((uint8)((L == 255) ? L:min(255, ((B << 8 ) / (255 - L)))))
    #define ChannelBlend_ColorBurn(B,L)  ((uint8)((L == 0) ? L:max(0, (255 - ((255 - B) << 8 ) / L))))
    #define ChannelBlend_LinearDodge(B,L)(ChannelBlend_Add(B,L))
    #define ChannelBlend_LinearBurn(B,L) (ChannelBlend_Subtract(B,L))
    #define ChannelBlend_LinearLight(B,L)((uint8)(L < 128)?ChannelBlend_LinearBurn(B,(2 * L)):ChannelBlend_LinearDodge(B,(2 * (L - 128))))
    #define ChannelBlend_VividLight(B,L) ((uint8)(L < 128)?ChannelBlend_ColorBurn(B,(2 * L)):ChannelBlend_ColorDodge(B,(2 * (L - 128))))
    #define ChannelBlend_PinLight(B,L)   ((uint8)(L < 128)?ChannelBlend_Darken(B,(2 * L)):ChannelBlend_Lighten(B,(2 * (L - 128))))
    #define ChannelBlend_HardMix(B,L)    ((uint8)((ChannelBlend_VividLight(B,L) < 128) ? 0:255))
    #define ChannelBlend_Reflect(B,L)    ((uint8)((L == 255) ? L:min(255, (B * B / (255 - L)))))
    #define ChannelBlend_Glow(B,L)       (ChannelBlend_Reflect(L,B))
    #define ChannelBlend_Phoenix(B,L)    ((uint8)(min(B,L) - max(B,L) + 255))
    #define ChannelBlend_Alpha(B,L,O)    ((uint8)(O * B + (1 - O) * L))
    #define ChannelBlend_AlphaF(B,L,F,O) (ChannelBlend_Alpha(F(B,L),B,O))

    B is the base channel and L is the blend channel. For example you to blend using Glow you simply call:

    ?
    Target[i] = ChannelBlend_Glow(Base[i], Blend[i]);

    The great thing about these macros is that you can apply the blending effect simply by passing in the channel value, without regard to which channel is red, green, or blue.

    To use the blending along with opacity you can use the following.

    ?
    Target[i] = ChannelBlend_AlphaF(Base[i], Blend[i], Blend_Subtract, 0.5F)

    Color blending

    To add certain blend modes that utilize hue, luminosity, and saturation we have to construct a per-color interface instead of per-channel interface. For these macros we assume that A and B are buffer pointers and they point to bytes with channels red, green, and blue in that order.

    #define ColorBlend_Buffer(T,B,L,M)      (T)[0] = ChannelBlend_##M((B)[0], (L)[0]), \
                                             (T)[1] = ChannelBlend_##M((B)[1], (L)[1]), \
                                             (T)[2] = ChannelBlend_##M((B)[2], (L)[2])
    #define ColorBlend_Normal(T,B,L)        (ColorBlend_Buffer(T,B,L,Normal))
    #define ColorBlend_Lighten(T,B,L)       (ColorBlend_Buffer(T,B,L,Lighten))
    #define ColorBlend_Darken(T,B,L)        (ColorBlend_Buffer(T,B,L,Darken))
    #define ColorBlend_Multiply(T,B,L)      (ColorBlend_Buffer(T,B,L,Multiply))
    #define ColorBlend_Average(T,B,L)       (ColorBlend_Buffer(T,B,L,Average))
    #define ColorBlend_Add(T,B,L)           (ColorBlend_Buffer(T,B,L,Add))
    #define ColorBlend_Subtract(T,B,L)      (ColorBlend_Buffer(T,B,L,Subtract))
    #define ColorBlend_Difference(T,B,L)    (ColorBlend_Buffer(T,B,L,Difference))
    #define ColorBlend_Negation(T,B,L)      (ColorBlend_Buffer(T,B,L,Negation))
    #define ColorBlend_Screen(T,B,L)        (ColorBlend_Buffer(T,B,L,Screen))
    #define ColorBlend_Exclusion(T,B,L)     (ColorBlend_Buffer(T,B,L,Exclusion))
    #define ColorBlend_Overlay(T,B,L)       (ColorBlend_Buffer(T,B,L,Overlay))
    #define ColorBlend_SoftLight(T,B,L)     (ColorBlend_Buffer(T,B,L,SoftLight))
    #define ColorBlend_HardLight(T,B,L)     (ColorBlend_Buffer(T,B,L,HardLight))
    #define ColorBlend_ColorDodge(T,B,L)    (ColorBlend_Buffer(T,B,L,ColorDodge))
    #define ColorBlend_ColorBurn(T,B,L)     (ColorBlend_Buffer(T,B,L,ColorBurn))
    #define ColorBlend_LinearDodge(T,B,L)   (ColorBlend_Buffer(T,B,L,LinearDodge))
    #define ColorBlend_LinearBurn(T,B,L)    (ColorBlend_Buffer(T,B,L,LinearBurn))
    #define ColorBlend_LinearLight(T,B,L)   (ColorBlend_Buffer(T,B,L,LinearLight))
    #define ColorBlend_VividLight(T,B,L)    (ColorBlend_Buffer(T,B,L,VividLight))
    #define ColorBlend_PinLight(T,B,L)      (ColorBlend_Buffer(T,B,L,PinLight))
    #define ColorBlend_HardMix(T,B,L)       (ColorBlend_Buffer(T,B,L,HardMix))
    #define ColorBlend_Reflect(T,B,L)       (ColorBlend_Buffer(T,B,L,Reflect))
    #define ColorBlend_Glow(T,B,L)          (ColorBlend_Buffer(T,B,L,Glow))
    #define ColorBlend_Phoenix(T,B,L)       (ColorBlend_Buffer(T,B,L,Phoenix))
    #define ColorBlend_Hue(T,B,L)            ColorBlend_Hls(T,B,L,HueL,LuminationB,SaturationB)
    #define ColorBlend_Saturation(T,B,L)     ColorBlend_Hls(T,B,L,HueB,LuminationB,SaturationL)
    #define ColorBlend_Color(T,B,L)          ColorBlend_Hls(T,B,L,HueL,LuminationB,SaturationL)
    #define ColorBlend_Luminosity(T,B,L)     ColorBlend_Hls(T,B,L,HueB,LuminationL,SaturationB)
     
    #define ColorBlend_Hls(T,B,L,O1,O2,O3) {                                        \
         float64 HueB, LuminationB, SaturationB;                                     \
         float64 HueL, LuminationL, SaturationL;                                     \
         Color_RgbToHls((B)[2],(B)[1],(B)[0], &HueB, &LuminationB, &SaturationB);    \
         Color_RgbToHls((L)[2],(L)[1],(L)[0], &HueL, &LuminationL, &SaturationL);    \
         Color_HlsToRgb(O1,O2,O3,&(T)[2],&(T)[1],&(T)[0]);                           \
         }
     
    int32 Color_HueToRgb(float64 M1, float64 M2, float64 Hue, float64 *Channel)
    {
         if (Hue < 0.0)
             Hue += 1.0;
         else if (Hue > 1.0)
             Hue -= 1.0;
     
         if ((6.0 * Hue) < 1.0)
             *Channel = (M1 + (M2 - M1) * Hue * 6.0);
         else if ((2.0 * Hue) < 1.0)
             *Channel = (M2);
         else if ((3.0 * Hue) < 2.0)
             *Channel = (M1 + (M2 - M1) * ((2.0F / 3.0F) - Hue) * 6.0);
         else
             *Channel = (M1);
     
         return TRUE;
    }
     
    int32 Color_RgbToHls(uint8 Red, uint8 Green, uint8 Blue, float64 *Hue, float64 *Lumination, float64 *Saturation)
    {
         float64 Delta;
         float64 Max, Min;
         float64 Redf, Greenf, Bluef;
     
         Redf    = ((float64)Red   / 255.0F);
         Greenf  = ((float64)Green / 255.0F);
         Bluef   = ((float64)Blue  / 255.0F);
     
         Max     = max(max(Redf, Greenf), Bluef);
         Min     = min(min(Redf, Greenf), Bluef);
     
         *Hue        = 0;
         *Lumination = (Max + Min) / 2.0F;
         *Saturation = 0;
     
         if (Max == Min)
             return TRUE;
     
         Delta = (Max - Min);
     
         if (*Lumination < 0.5)
             *Saturation = Delta / (Max + Min);
         else
             *Saturation = Delta / (2.0 - Max - Min);
     
         if (Redf == Max)
             *Hue = (Greenf - Bluef) / Delta;
         else if (Greenf == Max)
             *Hue = 2.0 + (Bluef - Redf) / Delta;
         else
             *Hue = 4.0 + (Redf - Greenf) / Delta;
     
         *Hue /= 6.0;
     
         if (*Hue < 0.0)
             *Hue += 1.0;      
     
         return TRUE;
    }
     
    int32 Color_HlsToRgb(float64 Hue, float64 Lumination, float64 Saturation, uint8 *Red, uint8 *Green, uint8 *Blue)
    {
         float64 M1, M2;
         float64 Redf, Greenf, Bluef;
     
         if (Saturation == 0)
             {
             Redf    = Lumination;
             Greenf  = Lumination;
             Bluef   = Lumination;
             }
         else
             {
             if (Lumination <= 0.5)
                 M2 = Lumination * (1.0 + Saturation);
             else
                 M2 = Lumination + Saturation - Lumination * Saturation;
     
             M1 = (2.0 * Lumination - M2);
     
             Color_HueToRgb(M1, M2, Hue + (1.0F / 3.0F), &Redf);
             Color_HueToRgb(M1, M2, Hue, &Greenf);
             Color_HueToRgb(M1, M2, Hue - (1.0F / 3.0F), &Bluef);
             }
     
         *Red    = (uint8)(Redf * 255);
         *Blue   = (uint8)(Bluef * 255);
         *Green  = (uint8)(Greenf * 255);
     
         return TRUE;
    }

    So now we can use the hue, saturation, color, and luminosity blend modes along with the rest of the blend modes. To use the ColorBlend macros we just position our bitmap’s pointers to the next RGB iteration and call,

    ColorBlend_Glow(Target + iTarget, Base + iBase, Blend + iBlend);

    Color macros

    Here are some color macros for combining and extracting channels colors out of an integer. One macro that I find a lot of use for is HexToRgb. With it I can copy and paste a hex color value out of the Photoshop color dialog and use the macro to do all the conversion for me to an rgb value.

     

    #define COLOR_OPAQUE                (0)
    #define COLOR_TRANSPARENT           (127)
     
    #define RGB_SIZE                    (3)
    #define RGB_BPP                     (24)
    #define RGB_MAXRED                  (255)
    #define RGB_MAXGREEN                (255)
    #define RGB_MAXBLUE                 (255)
     
    #define ARGB_SIZE                   (4)
    #define ARGB_BPP                    (32)
    #define ARGB_MAXALPHA               (127)
    #define ARGB_MAXRED                 (RGB_MAXRED)
    #define ARGB_MAXGREEN               (RGB_MAXGREEN)
    #define ARGB_MAXBLUE                (RGB_MAXBLUE)
     
    /*********************************************************************/
     
    #define Color_GetChannel(c,shift)   ((uint8)((c) >> (shift)))
    #define Color_Reverse(c,bpp)        ((((uint8)(c) << 24) | ((uint8)((c) >> 8 ) << 16) | ((uint8)((c) >> 16) << 8 ) | \
                                         ((uint8)((c) >> 24))) >> (32 - (bpp)))
     
    #define Rgb_ByteWidth(width)        ((width) * RGB_SIZE)
    #define Rgb_PixelWidth(width)       ((width) / RGB_SIZE)
     
    #define Rgb_GetRed(rgb)             (Color_GetChannel(rgb, 0))
    #define Rgb_GetGreen(rgb)           (Color_GetChannel(rgb, 8))
    #define Rgb_GetBlue(rgb)            (Color_GetChannel(rgb, 16))
     
    #define Rgba_GetRed(rgba)           (Color_GetChannel(rgba, 24))
    #define Rgba_GetGreen(rgba)         (Color_GetChannel(rgba, 16))
    #define Rgba_GetBlue(rgba)          (Color_GetChannel(rgba, 8))
    #define Rgba_GetAlpha(rgba)         (Color_GetChannel(rgba, 0))
     
    #define Argb_GetAlpha(argb)         (Color_GetChannel(argb, 24))
    #define Argb_GetRed(argb)           (Color_GetChannel(argb, 16))
    #define Argb_GetGreen(argb)         (Color_GetChannel(argb, 8))
    #define Argb_GetBlue(argb)          (Color_GetChannel(argb, 0))
     
    #define MakeRgb(r,g,b)              (((uint32)(uint8)(b) << 16) | ((uint16)(uint8)(g) << 8 ) | (uint8)(r))
    #define MakeRgba(r,g,b,a)           (((uint32)(uint8)(r) << 24) | ((uint16)(uint8)(g) << 16) | ((uint16)(uint8)(b) << 8 ) | (uint8)(a))
    #define MakeArgb(a,r,g,b)           (((uint32)(uint8)(a) << 24) | ((uint32)(uint8)(r) << 16) | ((uint16)(uint8)(g) << 8 ) | (uint8)(b))
     
    #define HexToRgb(hex)               (MakeRgb(((hex & 0xFF0000) >> 16), ((hex & 0x00FF00) >> 8 ), (hex & 0xFF)))


  •  

          一般的TC程序在XP下是无法输入中文的,同样也没法显示正确。不过WIN-TC程序却可以,其提供了一种DOS中文运行环境的运行模式,不过运行起来还是挺麻烦的,其实只要在main()函数最前面加上system( "graftabl 936 "); 这句话就可以直接运行了。

  •  

    Shadowing Information from NVIDIA

    Shadowing is a key component for convincing, solid-looking rendering. Whether hard or soft, physically correct or perceptually satisfying, NVIDIA has been at the forefront of real-time shadowing technology. This page collects some of the shadow-related presentations and white papers created in recent years by NVIDIA developers.

    Hard Shadows | Soft Shadows | Ambient Occlusion | Raytracing


    Hard Shadows

    Fast, Practical, and Robust Shadow Volumes
    White Paper and Sample Demo, 2004
    Combining efforts from Brown University and NVIDIA Corporation, this paper presents a set of algorithms for rendering shadows using the stencil buffer and the shadow volume technique. Using a series of techniques for culling, clipping, and simplifying shadow volume geometry, it is possible to achieve greater performance than previous methods. The algorithm builds on previously published algorithms by Crow, Everitt and Kilgard, and Lengyel.
    Samples from NVIDIA Graphics SDK 10.5:
    Cascaded Shadow Maps (Whitepaper )
    This sample illustrates cascaded shadow mapping with the use of texture arrays in OpenGL with GLSL.
    Volume Light (Whitepaper )
    Volume Light technique can be considered a simple approximation of real world light scattering effect.
    Samples from NVIDIA Graphics SDK 9.52:
    HLSL Hardware Shadow Map
    This effect shows generating texture coordinates for shadow mapping, along with using the shadow map in the lighting equation per pixel.
    Stencil Shadow Volume Extrusion
    In this sample, vertex shaders are used to extrude polygon objects into stencil shadow volumes. This avoids the CPU cost of computing shadow volumes and updating the shadow volume vertex buffers. It requires more memory to store additional face vertices and zero-area triangles for the automatic shadow volume extrusion.
    Perspective Shadow Maps (User Guide )
    This sample demonstrates hardware-accelerated large-scale perspective shadow maps, using Simon Kozlov's improvements in GPU Gems.
    Infinite Shadow Volumes
    This sample implements the techniques described in the Practical and Robust Shadow Volumes paper.
    Hardware Shadow Mapping
    White Paper , 2005
    Covers the details behind basic hardware shadow mapping with implementation details in OpenGL and Direct3D.
    Shadow Considerations
    White Paper, 2004
    Strategic considerations when using shadows to achieve optimal performance and image quality.
    GPU Gems 2 online:
    Part II, Shading, Lighting and Shadows
    Chapter 9. Deferred Shading in S.T.A.L.K.E.R.
    Chapter 13. Implementing the mental images Phenomena Renderer on the GPU
    GPU Gems online:
    Part II, Lighting and Shadows
    Chapter 9. Efficient Shadow Volume Rendering
    Chapter 10. Cinematic Lighting
    Chapter 11. Shadow Map Antialiasing
    Chapter 12. Omnidirectional Shadow Mapping
    Chapter 14. Perspective Shadow Maps: Care and Feeding
    also available in PDF
    Chapter 15. Managing Visibility for Per-Pixel Lighting
    OpenGL Render to Depth Texture - 2004 Demo w/Source
    This demo shows how to render to depth textures for shadow mapping in OpenGL through the WGL_ARB_render_texture and WGL_NV_render_depth_texture extensions.
    CEDEC 2001: Shadow Mapping with Today's OpenGL Hardware
    Presentation given by Mark Kilgard at CEDEC 2001 in Japan covers the use of shadow maps in OpenGL. Available as PDF in both English and Japanese.
    How-To: CgFX/COLLADA Shared-Surface Shadowing
    Description and Python tools for COLLADA Shared Surfaces, which can be used to develop scene-global shadows, reflections, and refractions in FX Composer 2.
    GDC 2003: From Gaffer To Game Engine - Cinematic Effects
    This presentation covers a wide range of creative shadow and lighting methods and uses, gleaned from the motion picture industry, television, and even Italian renaissance painting, with concrete real-time examples -- even GPU-driven interactive raytracing!


    Soft Shadows

    Samples from NVIDIA Graphics SDK 10.5:
    Percentage Closer Soft Shadows (Whitepaper )
    Percentage Closer Soft Shadows (PCSS) is a shadow mapping technique that renders realistic soft shadows with varying penumbra that harden on contact.
    Variance Shadow Mapping (Whitepaper )
    Variance Shadow Mapping was introduced in 2006 as a way to produce high quality soft shadows using arbitrary filter kernels. This allows for a sizable performance benefit over PCF as the shadow map can be pre-filtered with a separable blur.
    Soft Shadows (Whitepaper )
    This demo presents two algorithms for soft shadow rendering. The common advantage of the presented algorithms is that, in contrast with standard PCF (Percentage Closer Filtering) algorithms, they do not use pseudo-random samples to sample the shadow map. Hence, partially shadowed areas lack noise typically introduced by PCF algorithms.
    Samples from NVIDIA Graphics SDK 9.52:
    HLSL Soft Shadows (Whitepaper )
    This sample shows how to use conditional branching to compute filtered soft shadows efficiently. This technique could also be applied to accelerate other filtering algorithms to increase performance significantly on GPUs that support Shader Model 3.0.
    Simple Soft Shadows (Whitepaper )
    This sample demonstrates how branching in fragment programs can be used to optimize soft shadow rendering in OpenGL. This technique could also be applied to accelerate other filtering algorithms to increase performance significantly on GPUs that support Shader Model 3.0.
    GDC 2008: Soft Shadow Mapping
    Part of a day-long collaboration of hardware and software vendors, this presentation covers a range of available soft shadowing techniques and explores details of their varying implementations and advantages.
    Variance Shadow Maps
    ( PDF ), 2006
    Shadow maps are a widely used shadowing technique in real time graphics. One major drawback of their use is that they cannot be filtered in the same way as color textures, typically leading to severe aliasing. Variance Shadow Maps is an algorithm that approximates the occlusion, and solves the problem of shadow map aliasing with minimal additional storage and computation.
    NVISION08: Beautiful Women of the Future
    The last portion of this character-animation talk covers shadowing on characters and includes images from a survey on effective hair rendering techniques.
    SIGGRAPH 2005: Exposing the SDK
    Contains shadowing algorithms including a soft, "anime shadow" technique borrowed from Studio Ghibli.
    Whitepaper: Integrating Realistic Soft Shadows into Your Game Engine
    How to easily integrate an efficient method for creating realistic soft shadows on DirectX 10 and high-end DirectX 9 GPUs. Samples show our technique implemented in the recently (2008) released game Hellgate: London, developed by Flagship Studios
    GPU Gems 2 online:
    Chapter 17. Efficient Soft-Edged Shadows Using Pixel Shader Branching
    GPU Gems online:
    Chapter 13. Generating Soft Shadows Using Occlusion Interval Maps


    Ambient Occlusion

    To Trace or Not to Trace:
    Image-Space Horizon-Based Ambient Occlusion

    Louis Bavoil, Miguel Sainz, and Rouslan Dimitrov, NVIDIA Corporation
    (Related Japanese Presentation)
    Ambient occlusion is a lighting model that approximates the amount of light reaching a point on a diffuse surface based on its directly visible occluders. It provides a soft shadow appearance which enhances depth perception and spatial relationship between objects. In this talk, we present a new algorithm for rendering ambient occlusion as a post-processing pass by sampling a depth buffer and its associated normal buffer. We discuss how to integrate this approach in real-time engines as well as provide performance analysis.
    Sample from NVIDIA Graphics SDK 10.5: Screen Space Ambient Occlusion (Whitepaper )
    Ambient occlusion is a lighting model that approximates the amount of light reaching a point on a diffuse surface based on its directly visible occluders. We present a novel screen space ambient occlusion algorithm that gives perceptual clues of curvature and spatial proximity and thus is commonly used to add a global illumination look to rendered images. Our approach operates on the depth buffer of the scene being rendered and the associated per-pixel normal buffer.
    Samples from NVIDIA Graphics SDK 9.52:
    Dynamic Ambient Occlusion (Whitepaper )
    This sample demonstrates a new technique for computing diffuse light transfer and shows how it can be used to compute global illumination for animated scenes. The technique efficiently calculates ambient occlusion and indirect lighting data on the fly for each rendered frame. It does not have the limitations of precomputed radiance transfer (PRT) or precomputed ambient occlusion techniques, which are limited to rigid objects that do not move relative to one another. It works by treating polygon meshes as a set of surface elements that can emit, transmit, or reflect light and that can shadow each other. This method is efficient because it works without calculating the visibility of one element to another. Instead, it uses a much simpler and faster technique that uses shadowing to account for occluding (blocking) geometry.
    Ambient Occlusion using Hardware Shadow Maps
    This example demonstrates hardware-accelerated "ambient occlusion" using a hemisphere of shadow-mapped lights. Each light is rendered in a separate pass, and the results are summed together using a floating point accumulation buffer. The projection matrix is randomly jittered to provide anti-aliasing.
    GDC 2008: Real-Time Ambient Occlusion
    This lecture does a review of multiple depth-buffer-based ambient occlusion techniques. Three of the described algorithms are ray-marching in the depth buffer, an algorithm based on accumulating solid angles, and a new hybrid method called "tangent tracing."
    GPU Gems 2 online:
    Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting
    GPU Gems online:
    Chapter 17. Ambient Occlusion


    Ray Tracing

    Interactive Ray Tracing with CUDA
    David Luebke and Steven Parker, NVIDIA Corporation
    Ray tracing has long been associated with high-quality graphics, but it has not been suitable for interactive use. With CUDA and an NVIDIA GPU, it is now possible to ray trace reflections from curved surfaces, refractions, and accurate shadows. By combining these effects with rasterization to efficiently compute viewing ray intersections, accurate inter-reflections and other effects can be achieved at high resolutions and frame rates.

    Want to Learn More? NVIDIA Documentation Home Page

  • 记住啦,明天会更好!

  • 保存至剪贴板:
            //定义字符型变量用来保存用户输入的数据
           
    CString str;
            HGLOBAL hClip;
            //定义一个HGLOBAL句柄变量用来指向分配的内存块
            if (OpenClipboard())
            {
                EmptyClipboard();                            //将剪贴板内容清空
                hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);
                //在堆上分配可移动的内存块,程序返回一个内存句柄
                char * buff;                                 //定义指向字符型的指针变量
                buff=(char*)GlobalLock(hClip);
                //对分配的内存块进行加锁,将内存块句柄转化成一个指针,并将相应的引用计数器加1
                strcpy(buff,str);
                //将用户输入的数据复制到指针变量中,实际上就是复制到分配的内存块中
                GlobalUnlock(hClip);
                //数据写入完毕,进行解锁操作,并将引用计数器数字减1
                SetClipboardData(CF_TEXT,hClip);
                //将存放有数据的内存块放入剪贴板的资源管理中
                CloseClipboard();
                //关闭剪贴板,释放剪贴板资源的占用权
                MessageBox("已将数据存入剪贴板");
            }

    从剪贴板中取出文本:

           CString str;
            //字符型变量保存由剪贴板复制下来的数据
            HANDLE hClip;
            //定义HANDLE句柄型变量用来指向GetClipboardData函数返回的句柄
            if (OpenClipboard())
            {
                hClip=GetClipboardData(CF_TEXT);
                //从剪贴板中取出一个内存的句柄
                char* buff;
                //定义字符型指针变量用来保存内存块中的数据
                buff=(char*)GlobalLock(hClip);
                //对内存块进行加锁,将内存句柄值转化为一个指针,并将内存块的引用计数器加一,内存中的数据也返回到指针型变量中
                str=buff;
                //将数据保存到字符型变量中
                GlobalUnlock(hClip);
                //将内存块的引用计数器减一
                CloseClipboard();
                //关闭剪贴板,释放剪贴板资源的占用权
               
            }

  •  

          又陷入了Unicode的泥潭,工作中遇到一个模块需要从wchar_t* 转到 char*,而且后续的工作都是基于Char*进行的。网上找了下资料,代码如下:

    还有个搞人的东西是VS2005下的ifstream及ofstream函数,打开带有中文路径的文件会失败。

    解决方案非常HACK,例如

        非简体中文操作系统如下解决:

        std::locale prev_loc = std::locale::global( std::locale("chs") ); // 没有这一句的话,文件打开失败
        std::ifstream file( "d:\\测试\\test.txt" );
        std::locale::global( prev_loc ); // 没有这一句的话,文件中的中文无法输出,且wcout输出中文也失败

        简体中文操作系统下,

        std::locale::global( std::locale("") ); // 没有这一句的话,文件打开失败
        std::ifstream file( "d:\\测试\\test.txt" );

    --------------------------------------------------------------------------------------------------

    #include <stdio.h>
     #include <windows.h>
     #include <locale.h>
     #define BUFF_SIZE 1024
     
     wchar_t * ANSIToUnicode( const char* str )
     {
          int textlen ;
          wchar_t * result;
          textlen = MultiByteToWideChar( CP_ACP, 0, str,-1, NULL,0 );
          result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));
          memset(result,0,(textlen+1)*sizeof(wchar_t));
          MultiByteToWideChar(CP_ACP, 0,str,-1,(LPWSTR)result,textlen );
          return result;
     }
     
     char * UnicodeToANSI( const wchar_t* str )
     {
          char* result;
          int textlen;
          textlen = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
          result =(char *)malloc((textlen+1)*sizeof(char));
          memset( result, 0, sizeof(char) * ( textlen + 1 ) );
          WideCharToMultiByte( CP_ACP, 0, str, -1, result, textlen, NULL, NULL );
          return result;
     }
     
     wchar_t * UTF8ToUnicode( const char* str )
     {
          int textlen ;
          wchar_t * result;
          textlen = MultiByteToWideChar( CP_UTF8, 0, str,-1, NULL,0 );
          result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));
          memset(result,0,(textlen+1)*sizeof(wchar_t));
          MultiByteToWideChar(CP_UTF8, 0,str,-1,(LPWSTR)result,textlen );
          return result;
     }
     
     char * UnicodeToUTF8( const wchar_t* str )
     {
          char* result;
          int textlen;
          textlen = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
          result =(char *)malloc((textlen+1)*sizeof(char));
          memset(result, 0, sizeof(char) * ( textlen + 1 ) );
          WideCharToMultiByte( CP_UTF8, 0, str, -1, result, textlen, NULL, NULL );
          return result;
     }
     /*宽字符转换为多字符Unicode - ANSI*/
     char* w2m(const wchar_t* wcs)
     {
           int len;
           char* buf;
           len =wcstombs(NULL,wcs,0);
           if (len == 0)
               return NULL;
           buf = (char *)malloc(sizeof(char)*(len+1));
           memset(buf, 0, sizeof(char) *(len+1));
           len =wcstombs(buf,wcs,len+1);
           return buf;
     }
     /*多字符转换为宽字符ANSI - Unicode*/
     wchar_t* m2w(const char* mbs)
     {
           int len;
           wchar_t* buf;
           len =mbstowcs(NULL,mbs,0);
           if (len == 0)
               return NULL;
           buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
           memset(buf, 0, sizeof(wchar_t) *(len+1));
           len =mbstowcs(buf,mbs,len+1);
           return buf;
     }
     
     char* ANSIToUTF8(const char* str)
     {
          return UnicodeToUTF8(ANSIToUnicode(str));
     }
     
     char* UTF8ToANSI(const char* str)
     {
          return UnicodeToANSI(UTF8ToUnicode(str));
     }

  • 新建文本文档,将下面代码复制其中,保存为DEL.bat。

    DEL /F /A /Q \\?\%1

    RD /S /Q \\?\%1



    将不能删除的文件和文件夹拖入此DEL.bat文件就可以删除了!

  •       今天从云风的网站上看到的信息,原文在这里,一个比较轻量级的C++库,支持

    • Apple's g++ on OS X. Works on both Intel and PPC Macs
    • MinGW g++ compiler on Win32
    • Microsoft Visual C++ 2005 on Win32
  • Android SDK Emulator 是谷歌手机应用开发包中的一个模拟器组件,它可以在Windows、Mac或Linux电脑上运行,这个模拟器是用来让开发者开发软件时进行测试的。我们可以利用这个免费的模拟器在我们的电脑上好好体验一下Android了。

    全文见http://www.iplaysoft.com/android-emulator.html

    PS:啥时候会有iPhone或iPad模拟器啊?

  • 周云蓬《买房子&卖房子》

    歌词:
    买房子
    买了一套房子,花了三十多万,买房子的钱,全靠银行贷款
    从今天以后,不能随便请客吃饭了,不能多喝酒,不能去旅游
    从今天以后,我要拼命地还钱,我要努力地还钱,我要还清贷款
    不管风雨雷电,我要去上班,不管天塌地陷,我要去上班
    不管洪水滔天,我要去上班,不管海枯石烂,我还是要上班
    我努力地还,我拼命地还,我要一直还钱,我要还清这贷款
    我努力地还,我拼命地还,我要一直还钱,我要还清这贷款
    直到有一天,所有的钱都还完了,头发也就白了,嘴里没有牙了

    卖房子
    卖了一套房子,赚了一百多万 卖房子的钱,八辈子我都花不完
    从今天以后,吃肉要吃天鹅肉 喝酒要喝XO,喝粥要喝黄金粥
    从今天以后,我要努力的花钱喽 我要拼命地花喽,我要雇一个人来花钱
    不管春夏秋冬,我爱你哟房地产 不管海枯石烂,还是爱你房地产
    不管天塌地陷,我爱你哟房地产 不管洪水滔天,还是爱你房地产
    我要努力地花钱,我要拼命地花钱 我要一直地花钱喽,我要雇一个人来花钱
    我要拼命地花钱喽,我要努力地花钱 我要拼命地花钱喽,我要努力地花钱
    直到有一天,一平米房子涨到了一百万 你们都住在树枝上 只有我在树下面
    直到有一天,一平米房子涨到了一千万 你们都住在大海里 只有我在陆地上
    直到有一天,一平米房子涨到了一万万 你们都住在太空里 只有我在地球上
    你们都住在太空里 只有我在地球上 所有地球都是我地,我是地球的主人
    然后我就幸灾乐祸的唱起了这首歌.

  •  



    大家都知道,3D空间的鼠标拾取操作其中重要的一步是屏幕空间坐标到世界空间坐标的变换,在perspective变换时, Trace Vector的计算方法如下:


     

    D3DXMATRIXA16 matProj;
    lpd3d_device->GetTransform( D3DTS_PROJECTION, &matProj );
    ...
  • 内容来自http://www.geeks3d.com/20100628/3d-programming-ready-to-use-64-sample-poisson-disc/

     

    The Poisson disc is a popular sampling pattern used in 3D programming. The samples are distribued randomly on an unit disc (Poisson distribution). The Poisson disc is used, for example, in some soft shadows algorithms to blur shadow edges in the pixel shader.

    Here is a 64-sample Poisson disc you can directly use in your GLSL code (or in HLSL: just replace vec2 by float2):

    vec2 poissonDisk[64];
    poissonDisk[0] = vec2(-0.613392, 0.617481);
    poissonDisk[1] = vec2(0.170019, -0.040254);
    poissonDisk[2] = vec2(-0.299417, 0.791925);
    poissonDisk[3] = vec2(0.645680, 0.493210);
    poissonDisk[4] = vec2(-0.651784, 0.717887);
    poissonDisk[5] = vec2(0.421003, 0.027070);
    poissonDisk[6] = vec2(-0.817194, -0.271096);
    poissonDisk[7] = vec2(-0.705374, -0.668203);
    poissonDisk[8] = vec2(0.977050, -0.108615);
    poissonDisk[9] = vec2(0.063326, 0.142369);
    poissonDisk[10] = vec2(0.203528, 0.214331);
    poissonDisk[11] = vec2(-0.667531, 0.326090);
    poissonDisk[12] = vec2(-0.098422, -0.295755);
    poissonDisk[13] = vec2(-0.885922, 0.215369);
    poissonDisk[14] = vec2(0.566637, 0.605213);
    poissonDisk[15] = vec2(0.039766, -0.396100);
    poissonDisk[16] = vec2(0.751946, 0.453352);
    poissonDisk[17] = vec2(0.078707, -0.715323);
    poissonDisk[18] = vec2(-0.075838, -0.529344);
    poissonDisk[19] = vec2(0.724479, -0.580798);
    poissonDisk[20] = vec2(0.222999, -0.215125);
    poissonDisk[21] = vec2(-0.467574, -0.405438);
    poissonDisk[22] = vec2(-0.248268, -0.814753);
    poissonDisk[23] = vec2(0.354411, -0.887570);
    poissonDisk[24] = vec2(0.175817, 0.382366);
    poissonDisk[25] = vec2(0.487472, -0.063082);
    poissonDisk[26] = vec2(-0.084078, 0.898312);
    poissonDisk[27] = vec2(0.488876, -0.783441);
    poissonDisk[28] = vec2(0.470016, 0.217933);
    poissonDisk[29] = vec2(-0.696890, -0.549791);
    poissonDisk[30] = vec2(-0.149693, 0.605762);
    poissonDisk[31] = vec2(0.034211, 0.979980);
    poissonDisk[32] = vec2(0.503098, -0.308878);
    poissonDisk[33] = vec2(-0.016205, -0.872921);
    poissonDisk[34] = vec2(0.385784, -0.393902);
    poissonDisk[35] = vec2(-0.146886, -0.859249);
    poissonDisk[36] = vec2(0.643361, 0.164098);
    poissonDisk[37] = vec2(0.634388, -0.049471);
    poissonDisk[38] = vec2(-0.688894, 0.007843);
    poissonDisk[39] = vec2(0.464034, -0.188818);
    poissonDisk[40] = vec2(-0.440840, 0.137486);
    poissonDisk[41] = vec2(0.364483, 0.511704);
    poissonDisk[42] = vec2(0.034028, 0.325968);
    poissonDisk[43] = vec2(0.099094, -0.308023);
    poissonDisk[44] = vec2(0.693960, -0.366253);
    poissonDisk[45] = vec2(0.678884, -0.204688);
    poissonDisk[46] = vec2(0.001801, 0.780328);
    poissonDisk[47] = vec2(0.145177, -0.898984);
    poissonDisk[48] = vec2(0.062655, -0.611866);
    poissonDisk[49] = vec2(0.315226, -0.604297);
    poissonDisk[50] = vec2(-0.780145, 0.486251);
    poissonDisk[51] = vec2(-0.371868, 0.882138);
    poissonDisk[52] = vec2(0.200476, 0.494430);
    poissonDisk[53] = vec2(-0.494552, -0.711051);
    poissonDisk[54] = vec2(0.612476, 0.705252);
    poissonDisk[55] = vec2(-0.578845, -0.768792);
    poissonDisk[56] = vec2(-0.772454, -0.090976);
    poissonDisk[57] = vec2(0.504440, 0.372295);
    poissonDisk[58] = vec2(0.155736, 0.065157);
    poissonDisk[59] = vec2(0.391522, 0.849605);
    poissonDisk[60] = vec2(-0.620106, -0.328104);
    poissonDisk[61] = vec2(0.789239, -0.419965);
    poissonDisk[62] = vec2(-0.545396, 0.538133);
    poissonDisk[63] = vec2(-0.178564, -0.596057);
  •       界面库Prof-UIS又来了,翻翻本Blog的历史,界面库Prof-UIS使用心得(1)竟然是2005年8月的旧作。近日兴趣使然,又开始研究起界面库,这次给大家带来迟到的第二篇介绍,Prof-UIS的版本已然从2.40升到了2.89,笔者使用的VS 版本却只是从2003升级到了2005,真的是逝者如斯夫啊~~

          满怀期望地打开vs2005,启动编译,发生崩溃,试了无数次问题依然存在。解决办法如下:打开Prof-UIS\Include\Resources\resource.rc ,将文件中除简体中文( Chinese (P.R.C.) resources)和英文(English (U.S.) resources)其余统统删除。(个人测试保留繁体中文仍然可以通过编译)

          真不知道Prof-UIS为啥有这么大一个BUG,难道VS2005真的要被淘汰了?

  • 今天在Geeks3D看到了一个1k的D3D9 DEMO 3D Mandelbrot fractal,甚感神奇,作者同时列举了一些构造非常非常小的代码的技巧,看看还是有点启发的(当然带来的弊端就是可读性与维护性下降):

    • All variables should be just one letter
    • Make everything lowercase. The shader in this demo contains not a single uppercase letter.
    • All variables should be declared in one place
    • Variables should be reused whenever possible in order to minimize the amount of variables which need to be declared (this shader uses 1 float2, 3 float4s and 10 floats)
    • Since repetitive strings can be compressed better and some letter are more frequent than others, “1000″ may compress better than “999″, or “z*z*z*z” may be
      better than “pow(z,4)”
    • Use all features of c++ whenever possible, such as “o=d=1″, “while(z<400&&i++<11)" or "x=o-=log(b*b+u*u)*.15"
    • DirectX has a few additional features which can be useful. “if(h<1)v=v.gbra" reorders the indices of v while being very compact.
    • Truncate floats as much as possible, always ommit the leading zero and remove all unnecessary spaces and brackets.
    • Macros are usually not worth it.
    • At least on my machine the program would occasionally refuse to start at random. Adding “1*” or “0+” to some line might help.
    • Some variables may require an initilization, but the exact value might be not so important. In that case, just initialize them in combination with some other variable (“o=b=a.y;”) or reuse them when you know what the last value will look like approximately.