Language HLSL (High Level Shading Language)
(Pixelshader for direct3d 9 ps_3_0)
Date: | 03/27/10 |
Author: | Floste |
URL: | n/a |
Comments: | 0 |
Info: | http://msdn.microsoft.com/en-us/library/bb509561%28VS.85%29.aspx |
Score: | (3.00 in 7 votes) |
//////////////////////////////////////////////////////////////////////////////////// //This is a HLSL-shader, wich outputs the "99 bottles of beer"-song. The generation of the songtext is done within the pixelshader. //It needs an ansi sprite-Font assigned to FontTexture to work, because ther is no builtin support for text rendering. //Because the Songtext is a bit too long to fit into one screen, //this shader automatically scrolls down looping the songtext if you assign the current time in seconds to "time" and render frequently. //NVIDIA Fx Composer, wich i used for creating this, automatically does this. //////////////////////////////////////////////////////////////////////////////////// //Autor: Floste //Date: 27.3.2010 //////////////////////////////////////////////////////////////////////////////////// struct VS_OUT { float4 Pos:POSITION; float4 Tex:TEXCOORD0; }; //sprite font: ansi chars in a 16x16 matrix i use: http://www.imagebanana.com/view/fr5xg1w/SpriteFont.png Texture2D FontTexture; //time in seconds float time:animationtime; sampler FontSampler= sampler_state { Filter = MIN_MAG_MIP_LINEAR; AddressU = Clamp; AddressV = Clamp; Texture=<FontTexture>; }; const float numLines=40; const float numCols=100; VS_OUT BeerVertexShader(float2 Tex:TEXCOORD0) { VS_OUT result; result.Pos=float4(Tex.x*2-1,Tex.y*2-1,0,1); result.Tex=float4(Tex,Tex); result.Tex.y-=(time/10.0); return result; } //strings represented by arrays of ansi chars: //" bottles of beer on the wall, ": #define num_p1 30 const float p1[num_p1]={(32.0),(98.0),(111.0),(116.0),(116.0),(108.0),(101.0),(115.0),(32.0),(111.0),(102.0),(32.0),(98.0),(101.0),(101.0),(114.0),(32.0),(111.0),(110.0),(32.0),(116.0),(104.0),(101.0),(32.0),(119.0),(97.0),(108.0),(108.0),(44.0),(32.0)}; //" bottles of beer.": #define num_p2 17 const float p2[num_p2]={(32.0),(98.0),(111.0),(116.0),(116.0),(108.0),(101.0),(115.0),(32.0),(111.0),(102.0),(32.0),(98.0),(101.0),(101.0),(114.0),(46.0)}; //"Take one down and pass it around, ": #define num_p3 34 const float p3[num_p3]={(84.0),(97.0),(107.0),(101.0),(32.0),(111.0),(110.0),(101.0),(32.0),(100.0),(111.0),(119.0),(110.0),(32.0),(97.0),(110.0),(100.0),(32.0),(112.0),(97.0),(115.0),(115.0),(32.0),(105.0),(116.0),(32.0),(97.0),(114.0),(111.0),(117.0),(110.0),(100.0),(44.0),(32.0)}; //" bottles of beer on the wall.": #define num_p4 29 const float p4[num_p4]={(32.0),(98.0),(111.0),(116.0),(116.0),(108.0),(101.0),(115.0),(32.0),(111.0),(102.0),(32.0),(98.0),(101.0),(101.0),(114.0),(32.0),(111.0),(110.0),(32.0),(116.0),(104.0),(101.0),(32.0),(119.0),(97.0),(108.0),(108.0),(46.0)}; #define num_p5 66 const float p5[num_p5]={(71.0),(111.0),(32.0),(116.0),(111.0),(32.0),(116.0),(104.0),(101.0),(32.0),(115.0),(116.0),(111.0),(114.0),(101.0),(32.0),(97.0),(110.0),(100.0),(32.0),(98.0),(117.0),(121.0),(32.0),(115.0),(111.0),(109.0),(101.0),(32.0),(109.0),(111.0),(114.0),(101.0),(44.0),(32.0),(57.0),(57.0),(32.0),(98.0),(111.0),(116.0),(116.0),(108.0),(101.0),(115.0),(32.0),(111.0),(102.0),(32.0),(98.0),(101.0),(101.0),(114.0),(32.0),(111.0),(110.0),(32.0),(116.0),(104.0),(101.0),(32.0),(119.0),(97.0),(108.0),(108.0),(46.0)}; //"no more": #define num_noMore 7 const float noMore[num_noMore]={(78.0),(111.0),(32.0),(109.0),(111.0),(114.0),(101.0)}; float digit1(float num) { return trunc(num/10)+48; } float digit2(float num) { return (num%10)+48; } //gets the char at the specified location float GetCharAt(float x,float y) { y=round(y%300);//repeat every 300 lines int number=round(99-trunc((y+2)/3.0));//the number of bottles in the current line. float paragraphLine=round(y%3);//every paragraph has 3 lines. y%3 returns 0,1,2,0,1,2,1,... int i=round(x); //the following part emulates concatinating strings without using any dynamic or writeable buffers. //test wether i is within the current part and if not subtract the length of the current part and do the same with the next part. if(number<0)//the last line and the space after { if(paragraphLine==1&&number==-1&&i<num_p5) { return p5[i]; } return 32; } if(paragraphLine==0)//the first line in a paragraph { if(number>0) { if(number>9)//avoid a leading zero { if(i<1) return digit1(number); i-=1; } if(i<1) return digit2(number); i-=1; } else { if(i<num_noMore) return noMore[i]; i-=num_noMore; } if(number!=1)//decide wether to write bottle or bottles { if(i<num_p1) return p1[i]; i-=num_p1; } else { if(i<num_p1-1) {//leave out the 's' at index 7 if(i<7)return p1[i]; else return p1[i+1]; } i-=num_p1-1; } if(number>0) { if(number>9) { if(i<1) return digit1(number); i-=1; } if(i<1) return digit2(number); i-=1; } else { if(i<num_noMore) return noMore[i]; i-=num_noMore; } if(number!=1) { if(i<num_p2) return p2[i]; i-=num_p2; } else { if(i<num_p2-1) { if(i<7)return p2[i]; else return p2[i+1]; } i-=num_p2-1; } return 32; } if(paragraphLine==1)//the second line in a paragraph { if(i<num_p3) return p3[i]; i-=num_p3; if(number>0) { if(number>9) { if(i<1) return digit1(number); i-=1; } if(i<1) return digit2(number); i-=1; } else { if(i<num_noMore) return noMore[i]; i-=num_noMore; } if(number!=1) { if(i<num_p4) return p4[i]; i-=num_p4; } else { if(i<num_p4-1) { if(i<7)return p4[i]; else return p4[i+1]; } i-=num_p4-1; } return 32; } return 32;//the third line of a paragraph consists of spaces. } float4 BeerPixelShader(float4 Tex:TEXCOORD0):COLOR { //subLine is the y-coord within the line from 0 to 1 and iLine is the line number float subLine=(1-Tex.y)*numLines; float iLine=trunc(subLine); subLine-=iLine; float subChar=Tex.x*numCols; float iChar=trunc(subChar); subChar-=iChar; int charType=GetCharAt(iChar,iLine); if(charType==32)return float4(Tex.x,Tex.x,Tex.w,1); float4 color=tex2D(FontSampler,float2((subChar*0.6+0.2+charType%16)/16,(subLine+trunc(charType/16))/16)); color=color*color.a+float4(Tex.x,Tex.x,Tex.w,1)*(1-color.a); color.a=1; return color; } technique bottles { pass Pass0 { VertexShader = compile vs_3_0 BeerVertexShader(); PixelShader = compile ps_3_0 BeerPixelShader(); } }
Download Source | Write Comment
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments