<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff Foreground: #000 PrimaryPale: #8cf PrimaryLight: #18f PrimaryMid: #04b PrimaryDark: #014 SecondaryPale: #ffc SecondaryLight: #fe8 SecondaryMid: #db4 SecondaryDark: #841 TertiaryPale: #eee TertiaryLight: #ccc TertiaryMid: #999 TertiaryDark: #666 Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}
h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
.tabSelected{color:[[ColorPalette::PrimaryDark]];
background:[[ColorPalette::TertiaryPale]];
border-left:1px solid [[ColorPalette::TertiaryLight]];
border-top:1px solid [[ColorPalette::TertiaryLight]];
border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}
#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}
#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
.tiddler .defaultCommand {font-weight:bold;}
.shadow .title {color:[[ColorPalette::TertiaryDark]];}
.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}
.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}
.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}
.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}
.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}
.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
.imageLink, #displayArea .imageLink {background:transparent;}
.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}
body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}
hr {height:1px;}
a {text-decoration:none;}
dt {font-weight:bold;}
ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}
.txtOptionInput {width:11em;}
#contentWrapper .chkOptionInput {border:0;}
.externalLink {text-decoration:underline;}
.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}
.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}
/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
#mainMenu .tiddlyLinkExisting,
#mainMenu .tiddlyLinkNonExisting,
#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}
.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}
#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}
.wizard {padding:0.1em 1em 0em 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}
#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline;}
.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}
.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}
.tabset {padding:1em 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}
#contentWrapper {display:block;}
#splashScreen {display:none;}
#displayArea {margin:1em 17em 0em 14em;}
.toolbar {text-align:right; font-size:.9em;}
.tiddler {padding:1em 1em 0em 1em;}
.missing .viewer,.missing .title {font-style:italic;}
.title {font-size:1.6em; font-weight:bold;}
.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}
.tiddler .button {padding:0.2em 0.4em;}
.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}
.footer {font-size:.9em;}
.footer li {display:inline;}
.annotation {padding:0.5em; margin:0.5em;}
* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}
.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}
.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}
.sparkline {line-height:1em;}
.sparktick {outline:0;}
.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}
* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
#displayArea {margin: 1em 1em 0em 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers: * SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar) * MainMenu: The menu (usually on the left) * DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened You'll also need to enter your username for signing your edits: <<option txtUserName>>
These InterfaceOptions for customising TiddlyWiki are saved in your browser Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs) <<option txtUserName>> <<option chkSaveBackups>> SaveBackups <<option chkAutoSave>> AutoSave <<option chkRegExpSearch>> RegExpSearch <<option chkCaseSensitiveSearch>> CaseSensitiveSearch <<option chkAnimate>> EnableAnimations ---- Also see AdvancedOptions
<<importTiddlers>>
For those of you having problems with the course, you are welcome to contact me to make an appointment and we can try to work through things together. Questions not requiring an appointment are better sent to the Moodle forum where everyone can benefit from the discussion rather than as direct emails. Never fear, Moodle will alert me by email of any question that you post over there. The Moodle pages for the site are [[here|http://moodle.ucl.ac.uk/course/view.php?id=752]], the ELECTRAN coursework system [[here|http://www.cs.ucl.ac.uk/staff/electran/1001/index.html]], and the syllabus [[here|http://www.cs.ucl.ac.uk/teaching/syllabus/ug/1001.htm]].
! SPIM
If you are working on a lab Linux machine, you can run spim from the following locations:
{{{
/cs/shareopt/UCLCScourseware/bin.linux/spim
/cs/shareopt/UCLCScourseware/bin.linux/xspim
}}}
The manual is here: {{{/cs/shareopt/UCLCScourseware/man/spim.man}}}.
! Going further
If you happen to be enjoying your MIPS programming, my top tip is to get hold of some real development tools rather than using SPIM. Codesourcery are looking after the current official GNU toolchain for MIPS which you can find [[here|http://www.codesourcery.com/sgpp/lite/mips]]. With this you can prototype and debug your algorithms in C/C++ before translating them to assembly. You can then do things like validate the output of the assembly against that of the C/C++ version, and compare the compiler generated code to your own manual efforts. There is a simulator included. You probably want an [[ELF version|http://www.codesourcery.com/sgpp/lite/mips/portal/release1034]] rather than a Linux one if you are not running on real hardware. They also produce the [[ARM GNU toolchain|http://www.codesourcery.com/sgpp/lite/arm]], which you might want to look at if you are interested in [[getting to grips with the leading 32bit embedded architecture|http://infocenter.arm.com/help/index.jsp]] (which thanks to the iPhone, Android, Nintendo DS & GBA, 90% of mobile phones, etc., you are more likely to have a real device that you can program for).
<html> <object width="100%" height="720"> <param name="movie" value="http://www.youtubejavascript:;.com/v/75MSiLNQVWU&hl=en_GB&fs=1&hd=1"></param> <param name="allowFullScreen" value="true"></param> <param name="allowscriptaccess" value="always"></param> <embed src="http://www.youtube.com/v/75MSiLNQVWU&hl=en_GB&fs=1&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="1100"></embed></object></html>
I graduated with a ~BSc in Computer Science from UCL in 2007. After that I worked on embedded graphics in the Media Processing Division of ARM Ltd. for one year. I've since returned to UCL and am now an RA in the lab of Jan Kautz. A full CV is available [[here|http://www.cs.ucl.ac.uk/staff/andrew.cox/Andrew_Cox_cv.pdf]].
/***
|Name|DcTableOfContentsPlugin|
|Author|[[Doug Compton|http://www.zagware.com/tw/plugins.html#DcTableOfContentsPlugin]]|
|Contributors|[[Lewcid|http://lewcid.org]], [[FND|http://devpad.tiddlyspot.com]], [[ELS|http://www.tiddlytools.com]]|
|Source|[[FND's DevPad|http://devpad.tiddlyspot.com#DcTableOfContentsPlugin]]|
|Version|0.4.1|
|~CoreVersion|2.2|
<<showtoc>>
!Description
This macro will insert a table of contents reflecting the headings that are used in a tiddler and will be automatically updated when you make changes. Each item in the table of contents can be clicked on to jump to that heading. It can be used either inside of select tiddlers or inside a system wide template.
A parameter can be used to show the table of contents of a seperate tiddler, <<showtoc tiddlerTitle>>
It will also place a link beside each header which will jump the screen to the top of the current tiddler. This will only be displayed if the current tiddler is using the <<showtoc>> macro.
The appearance of the table of contents and the link to jump to the top can be modified using CSS. An example of this is given below.
!Usage
!!Only in select tiddlers
The table of contents above is an example of how to use this macro in a tiddler. Just insert <<showtoc>> in a tiddler on a line by itself.
It can also display the table of contents of another tiddler by using the macro with a parameter, <<showtoc tiddlerTitle>>
!!On every tiddler
It can also be used in a template to have it show on every tiddler. An example ViewTemplate is shown below.
//{{{
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'>Created <span macro='view created date DD-MM-YY'></span>, updated <span macro='view modified date DD-MM-YY'></span></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class="toc" macro='showtoc'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
//}}}
!Examples
If you had a tiddler with the following headings:
{{{
!Heading1a
!!Heading2a
!!Heading2b
!!!Heading3
!Heading1b
}}}
this table of contents would be automatically generated:
* Heading1a
** Heading2a
** Heading2b
*** Heading3
* Heading1b
!Changing how it looks
To modifiy the appearance, you can use CSS similiar to the below.
//{{{
.dcTOC ul {
color: red;
list-style-type: lower-roman;
}
.dcTOC a {
color: green;
border: none;
}
.dcTOC a:hover {
background: white;
border: solid 1px;
}
.dcTOCTop {
font-size: 2em;
color: green;
}
//}}}
!Revision History
!!v0.1.0 (2006-04-07)
* initial release
!!v0.2.0 (2006-04-10)
* added the [top] link on headings to jump to the top of the current tiddler
* appearance can now be customized using CSS
* all event handlers now return false
!!v0.3.0 (2006-04-12)
* added the ability to show the table of contents of a seperate tiddler
* fixed an error when a heading had a ~WikiLink in it
!!v0.3.5 (2007-10-16)
* updated formatter object for compatibility with TiddlyWiki v2.2 (by Lewcid)
!!v0.4.0 (2007-11-14)
* added toggle button for collapsing/expanding table of contents element
* refactored documentation
!To Do
* code sanitizing/rewrite
* documentation refactoring
* use shadow tiddler for styles
!Code
***/
//{{{
version.extensions.DcTableOfContentsPlugin= {
major: 0, minor: 4, revision: 0,
type: "macro",
source: "http://devpad.tiddlyspot.com#DcTableOfContentsPlugin"
};
// Replace heading formatter with our own
for (var n=0; n<config.formatters.length; n++) {
var format = config.formatters[n];
if (format.name == 'heading') {
format.handler = function(w) {
// following two lines is the default handler
var e = createTiddlyElement(w.output, "h" + w.matchLength);
w.subWikifyTerm(e, this.termRegExp); //updated for TW 2.2+
// Only show [top] if current tiddler is using showtoc
if (w.tiddler && w.tiddler.isTOCInTiddler == 1) {
// Create a container for the default CSS values
var c = createTiddlyElement(e, "div");
c.setAttribute("style", "font-size: 0.5em; color: blue;");
// Create the link to jump to the top
createTiddlyButton(c, " [top]", "Go to top of tiddler", window.scrollToTop, "dcTOCTop", null, null);
}
}
break;
}
}
config.macros.showtoc = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var text = "";
var title = "";
var myTiddler = null;
// Did they pass in a tiddler?
if (params.length) {
title = params[0];
myTiddler = store.getTiddler(title);
} else {
myTiddler = tiddler;
}
if (myTiddler == null) {
wikify("ERROR: Could not find " + title, place);
return;
}
var lines = myTiddler .text.split("\n");
myTiddler.isTOCInTiddler = 1;
// Create a parent container so the TOC can be customized using CSS
var r = createTiddlyElement(place, "div", null, "dcTOC");
// create toggle button
createTiddlyButton(r, "toggle", "show/collapse table of contents",
function() { config.macros.showtoc.toggleElement(this.nextSibling); },
"toggleButton")
// Create a container so the TOC can be customized using CSS
var c = createTiddlyElement(r, "div");
if (lines != null) {
for (var x=0; x<lines.length; x++) {
var line = lines[x];
if (line.substr(0,1) == "!") {
// Find first non ! char
for (var i=0; i<line.length; i++) {
if (line.substr(i, 1) != "!") {
break;
}
}
var desc = line.substring(i);
// Remove WikiLinks
desc = desc.replace(/\[\[/g, "");
desc = desc.replace(/\]\]/g, "");
text += line.substr(0, i).replace(/[!]/g, '*');
text += '<html><a href="javascript:;" onClick="window.scrollToHeading(\'' + title + '\', \'' + desc+ '\', event)">' + desc+ '</a></html>\n';
}
}
}
wikify(text, c);
}
}
config.macros.showtoc.toggleElement = function(e) {
if(e) {
if(e.style.display != "none") {
e.style.display = "none";
} else {
e.style.display = "";
}
}
};
window.scrollToTop = function(evt) {
if (! evt)
var evt = window.event;
var target = resolveTarget(evt);
var tiddler = story.findContainingTiddler(target);
if (! tiddler)
return false;
window.scrollTo(0, ensureVisible(tiddler));
return false;
};
window.scrollToHeading = function(title, anchorName, evt) {
var tiddler = null;
if (! evt)
var evt = window.event;
if (title) {
story.displayTiddler(store.getTiddler(title), title, null, false);
tiddler = document.getElementById(story.idPrefix + title);
} else {
var target = resolveTarget(evt);
tiddler = story.findContainingTiddler(target);
}
if (tiddler == null)
return false;
var children1 = tiddler.getElementsByTagName("h1");
var children2 = tiddler.getElementsByTagName("h2");
var children3 = tiddler.getElementsByTagName("h3");
var children4 = tiddler.getElementsByTagName("h4");
var children5 = tiddler.getElementsByTagName("h5");
var children = new Array();
children = children.concat(children1, children2, children3, children4, children5);
for (var i = 0; i < children.length; i++) {
for (var j = 0; j < children[i].length; j++) {
var heading = children[i][j].innerHTML;
// Remove all HTML tags
while (heading.indexOf("<") >= 0) {
heading = heading.substring(0, heading.indexOf("<")) + heading.substring(heading.indexOf(">") + 1);
}
// Cut off the code added in showtoc for TOP
heading = heading.substr(0, heading.length-6);
if (heading == anchorName) {
var y = findPosY(children[i][j]);
window.scrollTo(0,y);
return false;
}
}
}
return false
};
//}}}
[[Welcome]] [[CV]]
!Visual Studio 2008 Profile Guided Optimization Summary
{{{
Microsoft (R) Profile Guided Optimization Manager 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
PGD File: build\win-i386-vc9.0\bin\gfxmeter\gfxmeter.pgd 11/04/2009 14:58:27
Module Count: 1 Function Count: 5019 Arc Count: 20714 Value Count: 541
Static instructions: 174225 Basic blocks: 29515 Average BB size: 5.9
Dynamic instructions: 3135849250
entry static dynamic % run
Function Name count instr instr total total
G3D::GFont::computePackedArray 123659 248 471581542 15.0 15.0
G3D::Array<G3D::Vector3,10,32>::resize
335823 100 227532529 7.3 22.3
G3D::MD2Model::getGeometry 152754 573 192862856 6.2 28.4
G3D::RenderDevice::RenderState::TextureUnit::TextureUnit
5353696 26 139196096 4.4 32.9
G3D::Array<G3D::Vector2,10,32>::operator[]
36274499 3 108823497 3.5 36.4
G3D::RenderDevice::forceSetTextureMatrix
523732 87 104251772 3.3 39.7
G3D::Array<G3D::Vector2,10,32>::resize
123667 100 95942598 3.1 42.7
G3D::Matrix3::operator* 334606 38 87666772 2.8 45.5
G3D::RenderDevice::setState 334607 292 70307823 2.2 47.8
G3D::GFont::draw2D 123659 274 65997574 2.1 49.9
G3D::Matrix4::operator== 174578 40 46699146 1.5 51.4
G3D::RenderDevice::RenderState::RenderState
334606 139 46510234 1.5 52.9
G3D::Array<G3D::Vector3,10,32>::~Array<G3D::Vector3,10,32>
58606 23 39780454 1.3 54.1
G3D::MeshAlg::computeAdjacency 3 487 39512667 1.3 55.4
G3D::RenderDevice::setTexCoord 1440294 29 37447644 1.2 56.6
G3D::CoordinateFrame::pointToWorldSpace
363279 98 35601342 1.1 57.7
G3D::VertexRange::init 458262 143 35286174 1.1 58.8
G3D::computeStats 12 253 27930563 0.9 59.7
G3D::Matrix3::operator== 170941 24 27350560 0.9 60.6
G3D::ReferenceCountedPointer<G3D::VertexBuffer>::zeroPointer
4888195 18 26885160 0.9 61.5
G3D::RenderDevice::setTexture 545562 98 25801381 0.8 62.3
`vector copy constructor iterator'
334606 11 23087814 0.7 63.0
G3D::ReferenceCountedPointer<G3D::VertexBuffer>::setPointer
2596852 9 22913388 0.7 63.7
G3D::_getGLMatrix 443726 50 22186300 0.7 64.5
G3D::MD2Model::load 2 794 19533858 0.6 65.1
G3D::RenderDevice::setLight 327362 142 18695808 0.6 65.7
G3D::VertexRange::uploadToCard 458262 82 18330480 0.6 66.3
G3D::RenderDevice::setVARAreaFromVAR
458262 90 18024972 0.6 66.8
G3D::Array<int,10,32>::operator[]
5884538 3 17653614 0.6 67.4
G3D::Rect2D::corner 1287534 47 16737942 0.5 67.9
G3D::MD2Model::sendGeometry 152754 178 16344683 0.5 68.4
G3D::Array<G3D::RenderDevice::RenderState,10,32>::resize
334609 115 16061257 0.5 69.0
G3D::Draw::rect2D 32734 62 15810522 0.5 69.5
G3D::BinaryInput::prepareToRead
1047808 25 15717120 0.5 70.0
G3D::MeshAlg::computeNormals 1 144 14688393 0.5 70.4
}}}
! Accompanying Log
{{{
Application Log
Start: Wed Nov 04 14:37:48 2009
Setting video mode
wglSwapIntervalEXT(0);
Enabling separate specular lighting.
Setting initial rendering state.
Done setting initial state.
numTextureCoords = 8
numTextures = 32
numTextureUnits = 4
glGet(GL_MAX_TEXTURE_UNITS_ARB) = 4
glGet(GL_MAX_TEXTURE_IMAGE_UNITS_ARB) = 32
Operating System: Windows 6.0 build 6000 Platform 2
Processor Architecture: 4 x 32-bit Intel processor
GL Vendor: NVIDIA Corporation
GL Renderer: Quadro FX 5800/PCI/SSE2
GL Version: 3.2.0
Driver version: 8.16.11.9100
GL extensions: "GL_ARB_color_buffer_float GL_ARB_compatibility GL_ARB_copy_buffer GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_draw_buffers GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_fragment_coord_conventions GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging GL_ARB_map_buffer_range GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_provoking_vertex GL_ARB_seamless_cube_map GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_shadow GL_ARB_sync GL_ARB_texture_border_clamp GL_ARB_texture_buffer_object GL_ARB_texture_compression GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_float GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample GL_ARB_texture_non_power_of_two GL_ARB_texture_rectangle GL_ARB_texture_rg GL_ARB_transpose_matrix GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra GL_ARB_vertex_array_object GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float GL_ATI_texture_mirror_once GL_S3_s3tc GL_EXT_texture_env_add GL_EXT_abgr GL_EXT_bgra GL_EXT_bindable_uniform GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_compiled_vertex_array GL_EXT_Cg_shader GL_EXT_depth_bounds_test GL_EXT_direct_state_access GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXTX_framebuffer_mixed_formats GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_packed_pixels GL_EXT_pixel_buffer_object GL_EXT_point_parameters GL_EXT_provoking_vertex GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_shader_objects GL_EXT_separate_specular_color GL_EXT_shadow_funcs GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_array GL_EXT_texture_buffer_object GL_EXT_texture_compression_latc GL_EXT_texture_compression_rgtc GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map GL_EXT_texture_edge_clamp GL_EXT_texture_env_combine GL_EXT_texture_env_dot3 GL_EXT_texture_filter_anisotropic GL_EXT_texture_integer GL_EXT_texture_lod GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_object GL_EXT_texture_shared_exponent GL_EXT_texture_sRGB GL_EXT_texture_swizzle GL_EXT_timer_query GL_EXT_vertex_array GL_EXT_vertex_array_bgra GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat GL_KTX_buffer_region GL_NV_blend_square GL_NV_conditional_render GL_NV_copy_depth_to_color GL_NV_copy_image GL_NV_depth_buffer_float GL_NV_depth_clamp GL_NV_explicit_multisample GL_NV_fence GL_NV_float_buffer GL_NV_fog_distance GL_NV_fragment_program GL_NV_fragment_program_option GL_NV_fragment_program2 GL_NV_framebuffer_multisample_coverage GL_NV_geometry_shader4 GL_NV_gpu_program4 GL_NV_half_float GL_NV_light_max_exponent GL_NV_multisample_coverage GL_NV_multisample_filter_hint GL_NV_occlusion_query GL_NV_packed_depth_stencil GL_NV_parameter_buffer_object GL_NV_parameter_buffer_object2 GL_NV_pixel_data_range GL_NV_point_sprite GL_NV_primitive_restart GL_NV_register_combiners GL_NV_register_combiners2 GL_NV_shader_buffer_load GL_NV_texgen_reflection GL_NV_texture_barrier GL_NV_texture_compression_vtc GL_NV_texture_env_combine4 GL_NV_texture_expand_normal GL_NV_texture_rectangle GL_NV_texture_shader GL_NV_texture_shader2 GL_NV_texture_shader3 GL_NV_transform_feedback GL_NV_transform_feedback2 GL_NV_vertex_array_range GL_NV_vertex_array_range2 GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program GL_NV_vertex_program1_1 GL_NV_vertex_program2 GL_NV_vertex_program2_option GL_NV_vertex_program3 GL_NV_video_capture GL_NVX_conditional_render GL_SGIS_generate_mipmap GL_SGIS_texture_lod GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum GL_WIN_swap_hint WGL_EXT_swap_control "
Supported Formats:
Format Texture RenderBuffer
L8 Yes Yes
L16 Yes Yes
L16F Yes Yes
L32F Yes Yes
A8 Yes Yes
A16 Yes Yes
A16F Yes Yes
A32F Yes Yes
LA4 Yes Yes
LA8 Yes Yes
LA16 Yes Yes
LA16F Yes Yes
LA32F Yes Yes
RGB5 Yes Yes
RGB5A1 Yes Yes
RGB8 Yes Yes
RGB10 Yes Yes
RGB10A2 Yes Yes
RGB16 Yes Yes
RGB16F Yes Yes
RGB32F Yes Yes
RGBA8 Yes Yes
RGBA16 Yes Yes
RGB16F Yes Yes
RGBA32F Yes Yes
RGBA32UI Yes Yes
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
RGB_DXT1 Yes No
YUV420_PLANAR No No
YUV422 No No
YUV444 No No
RGB_DXT1 Yes No
RGBA_DXT1 Yes No
RGBA_DXT3 Yes No
RGBA_DXT5 Yes No
DEPTH16 Yes Yes
DEPTH24 Yes Yes
DEPTH32 Yes Yes
DEPTH32F Yes Yes
STENCIL1 No Yes
STENCIL4 No Yes
STENCIL8 No Yes
STENCIL16 No Yes
DEPTH24_STENCIL8 No Yes
Capability Minimum Desired Received Ok?
-------------------------------------------------
* RENDER DEVICE
Depth 16 bits 24 bits 24 bits ok
Stencil 8 bits 8 bits 8 bits ok
Alpha 0 bits ok
Red 8 bits ok
Green 8 bits ok
Blue 8 bits ok
FSAA 0 0 ok
Width 960 pixels ok
Height 600 pixels ok
Mode Windowed ok
Done initializing RenderDevice.
Network StartupStarting WinSock networking.
Network:
Status: WinSock 2.0
Loaded winsock specification version 1568901 (2 is the highest available)
514 sockets available
Largest UDP datagram packet size is 0 bytes
System {
App {
Name =
"k:\\documents\\dev\\g3d\\g3d\\build\\win-i386-vc9.0\\bin\\gfxmeter\\gfxmeter.exe"
cwd =
"k:\\documents\\dev\\g3d\\g3d\\build\\win-i386-vc9.0\\bin\\gfxmeter"
}
OS {
Name = "Windows 6.0 build 6000 Platform 2 "
}
CPU {
Vendor = "GenuineIntel"
Architecture = "4 x 32-bit Intel processor"
hasCPUID = Yes
hasMMX = Yes
hasSSE = Yes
hasSSE2 = Yes
hasSSE3 = Yes
has3DNow = No
hasRDTSC = Yes
numCores = 4
}
G3D {
Link version = 80002
Compile version = "G3D 8.00 beta 2"
}
GPU {
Chipset = "Quadro FX 5800/PCI/SSE2"
Vendor = "NVIDIA Corporation"
Driver = "8.16.11.9100"
OpenGL version = "3.2.0"
Textures = 32
Texture coordinates = 8
Texture units = 4
GL_MAX_TEXTURE_SIZE = 8192
GL_MAX_COLOR_ATTACHMENTS_EXT = 8
}
Window {
API = "Win32"
Version = "1.1"
In focus = Yes
Centered = Yes
Framed = Yes
Visible = Yes
Resizable = No
Full screen = No
Top = 286
Left = 317
Width = 960
Height = 600
Refresh rate = 85
Alpha bits = 0
Red bits = 8
Green bits = 8
Blue bits = 8
Depth bits = 24
Stencil bits = 8
Asynchronous = Yes
Stereo = No
FSAA samples = 0
}
Network {
{
...
}
}
}
WARNING: Could not find 'console-small.fnt' so '../../../../data-files/font/console-small.fnt' was substituted.
PERF WARNING: Using Film class for tonemapping from GApp
Shaders:
Combiners: NV rc2, NV ts3
Assembly: ARB fp1, ARB vp1, NV fp40, NV vp3
GLSL: 1.00
Detailed Performance Tests
* Vertex Rate
345960 tris, 2 lights, 1 texture, and 4 attributes
Low Coherence [ High Coherence ]
Method FPS [ FPS |Mverts/sec]
------------------------------------------------+---------
glBegin/glEndFPS: 19.7 [ 18.8 | 19.6 ]
glDrawElements: 276.3 [ 99.4 | 103.1 ]
+ VBO 87.4 [ 267.6 | 277.7 ]
+ uint16 index 83.9 [ 254.0 | 263.6 ]
+ gl interleaved 218.3 [ 550.6 | 571.5 ]
+ manual interleaved 220.6 [ 551.3 | 572.2 ]
without shading 330.2 [ 848.7 | 880.8 ]
glDrawArrays Peak: [ 507.2 | 526.4 ]
Bugs:
_____________________________________________________
### Files Used ###
gears.jpg
../../../../data-files/font/console-small.fnt
bunny.ifs
intel.jpg
pknight.md2
tiny.jpg
ogro.pcx
g3d.ico
./carbon.fnt
ogro.md2
pknight.pcx
./arial.fnt
nvidia.jpg
Network CleanupNetwork cleaned up.Shutting down RenderDevice.
Restoring gamma.
Freeing all VertexRange memory
Deleting window.
}}}
{{{
Microsoft (R) Profile Guided Optimization Manager 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
PGD File: build\win-i386-vc9.0\bin\viewer\viewer.pgd 11/04/2009 15:12:41
Module Count: 1 Function Count: 5889 Arc Count: 23275 Value Count: 567
Static instructions: 206304 Basic blocks: 33893 Average BB size: 6.1
Dynamic instructions: 19895643272
entry static dynamic % run
Function Name count instr instr total total
G3D::AABox::culledBy 10971553 151 4418988200 22.2 22.2
G3D::_BSPMAP::Map::getVisibleFaces
9184 157 2364256350 11.9 34.1
G3D::Plane::halfSpaceContainsFinite
95221339 26 2307412029 11.6 45.7
G3D::_BSPMAP::Mesh::render 20454417 47 961357599 4.8 50.5
G3D::_BSPMAP::Map::renderFaces 18368 148 767559422 3.9 54.4
G3D::_BSPMAP::Mesh::updateSortKey
21387234 31 663004254 3.3 57.7
G3D::_BSPMAP::Map::isClusterVisible
38122784 21 661553172 3.3 61.0
G3D::GFont::computePackedArray 210838 248 545834180 2.7 63.8
G3D::Array<G3D::_BSPMAP::FaceSet *,10,32>::append
22241288 40 400343202 2.0 65.8
G3D::Vector4::operator* 985559 36 346916768 1.7 67.5
G3D::_BSPMAP::BitSet::isOn 38340462 9 345064158 1.7 69.3
G3D::computeStats 124 245 312732836 1.6 70.8
G3D::Array<G3D::Plane,10,32>::operator[]
95221339 3 285664017 1.4 72.3
G3D::Array<G3D::_BSPMAP::Vertex,10,32>::operator[]
82989098 3 248967294 1.3 73.5
G3D::Spline<G3D::UprightFrame>::evaluate
985559 210 203025158 1.0 74.6
G3D::Array<G3D::_BSPMAP::BSPLeaf,10,32>::operator[]
38165176 5 190825880 1.0 75.5
G3D::_BSPMAP::BitSet::set 22241392 8 177931136 0.9 76.4
G3D::Array<int,10,32>::operator[]
58843141 3 176529423 0.9 77.3
G3D::Color3::max 6731416 23 154822568 0.8 78.1
G3D::Color3::min 6731416 23 154822568 0.8 78.8
G3D::Matrix3::operator* 523071 38 137044602 0.7 79.5
G3D::Spline<G3D::UprightFrame>::getControl
3942236 287 135280300 0.7 80.2
G3D::Array<G3D::Vector2,10,32>::operator[]
42116714 3 126350142 0.6 80.9
G3D::Rect2D::corner 9189688 47 119465944 0.6 81.5
G3D::ReferenceCountedPointer<G3D::Texture>::isNull
29220997 6 116918833 0.6 82.0
G3D::Color3::Color3 6731416 16 107702656 0.5 82.6
G3D::Array<G3D::ReferenceCountedPointer<G3D::Texture>,10,32>::operator[]
35067041 3 105201123 0.5 83.1
G3D::UprightFrame::unwrapYaw 985559 70 96728395 0.5 83.6
G3D::Array<G3D::_BSPMAP::FaceSet *,10,32>::resize
18380 94 89720265 0.5 84.0
}}}
[[By completing this survey, you will be entered into a prize draw to win a luxury skiing holiday for two in the French Alps, worth £2,000. You will also provide valuable feedback to help other people choose their graduate jobs|http://www.2iresearch.com/gradjobs/referral.php?id=45]].
We'll be meeting on Fridays for two hours between 16:00 and 18:00 in MPEB 1.21. Our main emphasis in those sessions will be to get you through the [[exercises and coursework|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/index.html]] but it is also a chance for you to ask about other aspects of the course. We welcome your questions and if you want to write an email ahead of time to be sure that we've thought through our answers, that is fine too. Min Kim has some good notes on the course from a previous year [[here|http://web4.cs.ucl.ac.uk/staff/M.Kim/teaching/gmv.html]]. Please note that the course has changed since these notes were written and also note that any questions should be directed to myself and Insu, and not to Min. I am accumulating a fair bit of information relevant to the course. [[Click to open all GV10 posts|http://www.cs.ucl.ac.uk/staff/Andrew.Cox/#%5B%5BGraphics GV10%5D%5D %5B%5BGraphics GV10 coursework%5D%5D %5B%5BGraphics GV10 Coursework 1 - ray tracer in Java%5D%5D %5B%5BGraphics GV10 coursework - Annoying need to click window before hitting ESC to exit%5D%5D %5B%5BGraphics GV10 Coursework 1 - Self-intersection%5D%5D %5B%5BGraphics GV10 Labs%5D%5D %5B%5BGraphics GV10 OpenGL%5D%5D %5B%5BGraphics GV10 Modern OpenGL%5D%5D %5B%5BGraphics GV10 Links%5D%5D %5B%5BGraphics GV10 Tutorial 3%5D%5D %5B%5BGraphics GV10 Tutorial 4%5D%5D]].
Generating shadows involves tracing rays between lights and surfaces. Similarly, reflection rays also originate on surfaces. In these cases we have to make sure that the object at the ray origin isn't counted as being intersected by it. Ignoring this issue leads to black speckles (object shadows itself) and bright ones (reflection bounced from surface that was just exited). A few approaches to avoiding this problem are possible, including the following: * Screen that one object out of the list of objects to intersect. ** (-) harder to do in a real system with many object types and some form of hierarchy in the scene. * Require intersections to be beyond some minimum t value.
The description of the coursework can be found [[here|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab4/coursework1.html]]. The example solution to Lab 2 and suggested code framework for starting the coursework that is given on that page will not build on a case-sensitive system such as Linux, so I've placed a version of it with corrected file names [[here|teaching/09/gv10/cw1.starting_code.correct_caps.zip]].
!!!! Colour to use for reflections
{{{Material.Specular}}} can be used as the reflective colour to modulate intensities returned from reflected rays.
!!! Tutorial 2 The description of this lab is [[here|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab2/lab2.html]]. There are many possible local lighting models, but go with the one described in the [[course|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Slides/local_illumination.pdf]] and on [[Min's page|http://web4.cs.ucl.ac.uk/staff/M.Kim/teaching/gmv.html]] (see equation below reproduced from Min's FAQ). [img[http://web4.cs.ucl.ac.uk/staff/M.Kim/teaching/gmv/eq_local_illuminantion.png]] The code provided is very simple to build and run on a machine with a Java development environment setup. In the following two subsections you can find instructions for building via the command line and via Netbeans on the machines in room 1.21. !!!! Building on the Command Line * Check where your java JDK is installed. I found one here on a lab machine: C:\Program Files\Java\jdk1.6.0_02\ * Add your Java JDK tools to your path. For my lab machine, the command was as follows, but adjust according to the path you found in the last step: set PATH=%PATH%;C:\Program Files\Java\jdk1.6.0_02\bin\ * Tell Java to look for classes to load in the current directory: set CLASSPATH=%CLASSPATH%;. * Unzip the code from here: http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab2/lab2.zip * Place the lab2 folder somewhere sensible in your documents. * cd into "...\lab2\Question". * Compile the java code: javac *.java * Run the app that you just built: java ~SimpleRay simplescene.dat !!!! Building in Netbeans * Start Netbeans from the start menu. * Create new project. ** In the wizard that appears, make the project "General" and "Java Application". ** Hit Next. ** Give the project a sensible name and location in your documents. ** Deselect "Create Main Class" ** Hit next/finish. * Unzip the code from [[here|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab2/lab2.zip]] * Place the unzipped java code from "...\lab2\Question" in the src folder that ~NetBeans has created inside the project folder. * Switch back to Netbeans and the java code should have appeared in the project window under "Source Packages" and in the Files tab. * Right click the project in the Projects tab and select "Build Project". It should build with one deprecation warning. * Place the file "simplescene.dat" from "lab2/Question" in the project folder (the folder one level up from the netbeans "src" folder). * Right click the project in the Projects tab and select "properties". ** Select the "Run" category and enter the string "simplescene.dat" in the "Arguments" text field. ** Click OK. * Right click the project again and select "Run Project". The program should run and show the rendered scene. !!! Tutorial 3 [[Graphics GV10 Tutorial 3]] !!! Tutorial 4 [[Graphics GV10 Tutorial 4]]
!!Links * [[G3D|http://g3d-cpp.sourceforge.net/]] Is a realtime graphics toolkit, operating at a lower level than most engines such as Ogre or scene graphs such as OSG or the other OSG. It offers seemless access to the underlying ~OpenGL implementation (see [[this example|http://g3d-cpp.cvs.sourceforge.net/viewvc/g3d-cpp/G3D/demos/rawOpenGL/main.cpp?view=markup]] using ~G3D much as you might employ GLUT).
If you are interested in going beyond the traditional fixed-function ~OpenGL taught in this course and getting to grips with shaders and other more recent features, a good place to start is by learning ~OpenGL ES 2.x. The slimming-down of the original specification to create a profile for new platforms that are free of legacy issues such as mobile phones and consoles like the Playstation 3 produced a library that resembles very much the "pure" future incarnation of ~OpenGL that had been envisioned by 3D Labs during their time as caretakers of GL after it had left the hands of SGI. There are several GLES implementations that run on ~PCs, such as [[this|http://www.malideveloper.com/tools/software-development/opengl-es-20-emulator.php]] one from [[ARM|http://www.malideveloper.com/index.php]], the embedded graphics market leader, [[this|http://www.imgtec.com/powervr/insider/sdk/KhronosOpenGLES2xSGX.asp]] one from ~PowerVR and [[this|http://developer.amd.com/GPU/OpenGL/Pages/default.aspx]] from ATI/AMD. The specifications are maintained by [[Khronos|http://www.khronos.org/opengles/2_X/]]. Since GLES is ~OpenGL minus the cruft, a good rule of thumb for deciding whether an ~OpenGL feature from the 1.x versions is worth learning is to see whether it exists in the GLES spec and if not, don't bother. Examples of this include Feedback mode, evaluators, and the 1.4 imaging features. You'll also see that there is no Begin/End paradigm in GLES. We pretty much force you to learn that to do the coursework because it is handy for didactic purposes but try not to get too used to it if you can.
During the lab sessions we will be working with ~OpenGL. This API has evolved greatly over the years and the most up-to-date information on it will not necessarily be the most relevant to the subset that we are teaching on this course. A great resource for learning is the [[OpenGL Red Book|http://www.opengl.org/documentation/red_book/]] which is [[available online|http://www.glprogramming.com/red/]] in the most useful edition for our purposes. The specification is often the place to go for the answers to questions (See version 1.1 as [[PDF|GLspec1.1.pdf]] and [[PS|http://www.opengl.org/documentation/specs/version1.1/GLspec1.1.ps]]). [[This diagram|http://www.opengl.org/documentation/specs/version1.1/state.pdf]] may prove helpful in visualising how the parts of the system interact. The main GPU manufacturers have ~SDKs that might be helpful in that they provide a code base that you can adapt if you have chosen a final project that stresses real-time graphics, but their examples will probably be a distraction from the essentials required for this course. You can find them [[here|http://developer.download.nvidia.com/SDK/10/opengl/samples.html]] and [[here|http://developer.amd.com/gpu/radeon/Pages/default.aspx]].
The slides for the recap on ~OpenGL matrices that was presented in the lab are [[here|http://www.cs.ucl.ac.uk/staff/Andrew.Cox/teaching/09/gv10/week56_tut3.ppt]] (ppt) and [[here|http://www.cs.ucl.ac.uk/staff/Andrew.Cox/teaching/09/gv10/Week 5-6 Tutorial 3.pdf]] (pdf).
!drawBox breakdown
Some students without C/C++ experience found lines like {{{glVertex3fv(&v[faces[i][0]][0]);}}} a little dense to follow. I've broken the drawBox function down below so the indirections are hopefully easier to trace through.
<code cpp>
void
submitFaceGeometry(int face)
{
int corner;
for (corner = 0; corner < 4; corner++) {
GLint vertex_index = faces[face][corner];
// Take the address of the x component of the vertex position:
GLfloat* vertex_position = &v[vertex_index][0];
// Pass the address of the the vertex position to GL (the y and z
// components follow the x component in consecutive memory words):
glVertex3fv(vertex_position);
}
}
void
drawBox(void)
{
int face;
for (face = 0; face < 6; face++) {
glBegin(GL_QUADS);
glNormal3fv(&n[face][0]);
submitFaceGeometry(face);
glEnd();
}
}
</code>
The full source for the modified program is [[here|teaching/09/gv10/cube_dbb.c]].
! Corrected cube.c
Some of you had some lighting problems once you started rotating your cubes. It turned out that two of the face normals were pointing in the wrong directions (into the cube instead of out into the world). Here is a corrected version.
<code cpp>
/* Copyright (c) Mark J. Kilgard, 1997. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
/* This program was requested by Patrick Earl; hopefully someone else
will write the equivalent Direct3D immediate mode program. */
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
//GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */
// {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
// {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */
{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
{0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, 0.0, 1.0} };
GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */
{0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
{4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */
void
drawBox(void)
{
int i;
for (i = 0; i < 6; i++) {
glBegin(GL_QUADS);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
}
static float g_rotate_x = 0.0f;
static float g_rotate_y = 0.0f;
void keyboard(unsigned char key, int x, int y)
{
switch(key){
case 'q':
g_rotate_x += 360.0f / 60.0f;
break;
case 'a':
g_rotate_x -= 360.0f / 60.0f;
break;
case 's':
g_rotate_y += 360.0f / 60.0f;
break;
case 'd':
g_rotate_y -= 360.0f / 60.0f;
break;
case 27:
exit(0);
};
glutPostRedisplay();
printf("key == %d, rotate == %f\n", (unsigned)key, g_rotate_x);
}
void
display(void)
{
/*From OpenGL specification 1.3, section 2.13:
The current model-view matrix is applied to the position parameter indicated
with Light for a particular light source when that position is specified.
These transformed values are the values used in the lighting equation.
*/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
// Start with a fresh matrix every frame:
glLoadIdentity();
// Set Light position in viewspace so it is not affected by object
// transformations:
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in positive Y direction */
/* Adjust cube position to be asthetic angle. */
glTranslatef(0.0, 0.0, -1.0);
glRotatef(g_rotate_y, 0.0, 1.0, 0.0);
glRotatef(g_rotate_x, 1.0, 0.0, 0.0);
glRotatef(60, 1.0, 0.0, 0.0);
glRotatef(-20, 0.0, 0.0, 1.0);
// Set Light position in objectspace so it follows the object transformations:
//glLightfv(GL_LIGHT0, GL_POSITION, light_position);
drawBox();
glutSwapBuffers();
}
void
init(void)
{
/* Setup cube vertex data. */
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
/* Enable a single OpenGL light. */
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
/* Use depth buffering for hidden surface elimination. */
glEnable(GL_DEPTH_TEST);
/* Setup the view of the cube. */
glMatrixMode(GL_PROJECTION);
gluPerspective( /* field of view in degree */ 40.0,
/* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 10.0);
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("red 3D lit cube");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
init();
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
</code>
The task described [[here|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/index.html]] is to sweep a 2d line around a circle that is perpendicular to it in order to define a surface in 3d. The point of all this is to get you familiar with a common form of [[boundary representation|http://en.wikipedia.org/wiki/Boundary_representation]].
! Example solution
A solution is available [[here|teaching/09/gv10/tut4_brep.release.zip]]. It divides the problem into the following two parts:
# Generate a boundary representation in [[this|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab5/cw_spec.txt]] format.
# Load and display models in the format linked to above.
It implements each part as a separate program, with only the viewer knowing anything about ~OpenGL.
!! Building the example
Under linux or, presumably, cygwin running on Windows, the bash script {{{build_generator.sh}}} will build the brep generator program. Similarly, {{{build_viewer.sh}}} will build the brep loader and viewer program.
!! Running the example programs
[>img[teaching/09/gv10/simple_12_4.png]]
!!! Generator
This writes its results to standard output so that must be captured to a file. Using bash (linux, cygwin, ...) that is done as follows:
{{{
./gen_rep_d > a_filename.dat
}}}
The generator will by default, produce the simple shape that we talked about in the lab and a rendering of which is illustrated to the right.
!!! Viewer
The viewer reads a text description of a boundary rep object in the [[specified format|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab5/cw_spec.txt]] from standard input and draws it in wireframe using ~OpenGL. It is therefore necessary to feed it a file of interest. This is done in bash as follows:
{{{
cat a_filename.dat | ./brep_view_d
}}}
[>img[teaching/09/gv10/glass_12_2.png]]
It can also show the example files if the viewing parameters are manually tweaked (modify the code) so that the camera takes them in at their various scales. For example, change {{{if(true)}}} to {{{if(false)}}} on line 111 and vice versa on line 115 of {{{brep_view.cpp}}} to be able to view [[glass.dat|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/lab5/data/glass.dat]].
!! Math of generating points on the surface from point in the outline
<html><!-->[>img[teaching/09/gv10/glass_12_1.png]]<--></html>
Several of you were ignoring the definition of the maths for this rotation from the problem statement and going ahead to construct 3x3 rotation matrices and whatnot. Sorry to the one person I saw doing this that I forgot to correct because of another puzzle in your code. Anyway, as you see from the example code below, {{{x' = x * cos(angle);}}}, {{{y' = x * sin(angle);}}}, and {{{z' = z;}}}.
<code c++>
/// Generate one single segment of the object's surface points.
void rotate_insert_outline(
/// Incoming definition of outline as 2d line strip.
const vector<vec2>& outline,
/// Outgoing definition of surface positions.
vector<vec3> & positions,
/// Angle about z-axis at which the points of this segment will be generated.
const double angle,
/// The location in the positions vector at which the first point of this segment should be placed.
const unsigned first_position)
{
const unsigned num_outline_points = outline.size();
for(unsigned ioutline_point = 0; ioutline_point < num_outline_points;
++ioutline_point)
{
vec2 outline_point = outline[ioutline_point];
vec3 point;
point.v_[0] = float(outline_point[0] * cos(angle));
point.v_[1] = float(outline_point[0] * sin(angle));
point.v_[2] = outline_point[1];
positions[first_position + ioutline_point] = point;
}
}
</code>
!! Generating quad corner indexes
The indexes can be generated entirely separately from the geometry (positions), purely by careful counting,
<code c++>
void gen_seg_indices(
const unsigned num_outline_points,
const unsigned point_base1, const unsigned point_base2,
vector<unsigned>& indices, const unsigned index_base)
{
for(unsigned ioutline_point = 0; ioutline_point < num_outline_points - 1u;
++ioutline_point)
{
const unsigned quad_base = index_base + ioutline_point * 4u;·
indices[quad_base + 0] = point_base1 + ioutline_point;
indices[quad_base + 1] = point_base2 + ioutline_point;
indices[quad_base + 2] = point_base2 + ioutline_point + 1;
indices[quad_base + 3] = point_base1 + ioutline_point + 1;
}
}
</code>
!! Top level sweep function
<code c++>
/// Given a list of points, rotate them around the z-axis and tie them together
/// into indexed quads.
/// ! Note that vec2.y is treated as a z coordinate in 3D.
IndexedQuadSet sweep_outline(
const vector<vec2>& outline,
const unsigned num_segments)
{
IndexedQuadSet quadset;
quadset.positions_.resize(num_segments * outline.size());
quadset.indices_.resize((num_segments) * (outline.size()-1u) * 4u);
// Store rotated positions:
for(unsigned segment = 0; segment < num_segments; ++segment)
{
// For each point in the outline, rotate it around the z axis:
double angle = PI2 * segment / num_segments;
const unsigned insertion_point = segment * outline.size();
rotate_insert_outline(outline, quadset.positions_, angle,insertion_point);
}
// Tie positions together with quad indexes:
for(unsigned segment = 0; segment < num_segments; ++segment)
{
const unsigned first_seg = segment;
const unsigned second_seg = (segment + 1) % num_segments;
const unsigned point_base1 = first_seg * outline.size();
const unsigned point_base2 = second_seg * outline.size();
const unsigned index_base = segment * (outline.size() - 1u) * 4u;
gen_seg_indices(outline.size(), point_base1, point_base2,
quadset.indices_, index_base);
}
return quadset;
}
</code>
The lab exercises and coursework descriptions can be found [[here|http://www.cs.ucl.ac.uk/staff/j.kautz/teaching/3080/Exercises/index.html]].
Add the following single line in the context given below to get an ~RSI-friendly ~ESC-to-exit feature.
<code java>
public static void main (String args[]) {
// ...
tmp.addKeyListener(tmp);
tmp.requestFocusInWindow(); // <<<<<<<<<<<<<<<< ADD THIS LINE
</code>
[[Welcome]] [[CV]] !!!Teaching [[Graphics GV10]] [[Architecture 1001]]
~OpenMP has a [[directive|http://msdn.microsoft.com/en-us/library/2etkydkz.aspx]] to support reductions in parallel loops. If each thread that did some of the work has produced it's own idea of the final result, this mechanism takes those partial results, and applies the reduction operation to them to produce the final, final result around the time of the thread join. Without this help from the system, the simple approach to reductions would have shared variables and synchronisation inside the per-thread sub-loops (see [[here|http://www.openmp.org/pipermail/omp/2005/000254.html]]).
Unfortunately, the min and max operations of the FORTRAN version have been left out of C/C++ ~OpenMP. I say unfortunately because finding the min and max of an array of elements is a very useful operation. For example, they are a necessary prerequisite for normalisation of the array elements. Below is my naive attempt at implementing a min reduction in ~OpenMP, using a purely private variable, lock-free inner loop.
First up after some preliminaries, a single-threaded implementation to compare against:
{{{
#include <float.h>
#include <stdio.h>
#ifndef NUMTHREAD
#define NUMTHREAD 2
#endif
float singlethread_min_of_array(const float * const in_img, const unsigned int ilength)
{
unsigned i = 0;
float min, temp;
// initialize
min = FLT_MAX;
for (i = 0; i < ilength; i++){
temp = in_img[i];
if (temp<min) min = temp;
}
return min;
}
}}}
The parallel version which follows is much longer.
{{{
float manual_min_of_array(const float * const in_img, const unsigned int ilength)
{
unsigned i = 0;
float min, private_min, temp;
// initialize
min = FLT_MAX;
private_min = FLT_MAX;
// find out max and min
unsigned isublength = 0;
unsigned spare_elements = ilength % NUMTHREAD;
unsigned assigned_elements = 0;
unsigned first_element = 0;
#pragma omp parallel num_threads(NUMTHREAD) private(i, temp, first_element, isublength, private_min)
{
// Grab some of the input array to work on, protecting thread-shared
// state by synchronisation:
#pragma omg critical
{
first_element = assigned_elements;
isublength = ilength / NUMTHREAD;
if(assigned_elements == 0)
{
assigned_elements += spare_elements;
isublength += spare_elements;
}
assigned_elements += isublength;
}
// Do most work in a thread-private way with no syncronisation:
for (i = 0; i < isublength; i++){
temp = in_img[first_element + i];
if (temp<private_min) private_min = temp;
}
// Update the shared min inside a critical section:
#pragma omg critical
if(private_min < min) { min = private_min; }
}
return min;
}
}}}
Note that the only part doing the work is the following. The rest is setup, work assignment, and fixup. It seems from looking at this that having the support for min and max reductions would be worthwhile.
{{{
// Do most work in a thread-private way with no syncronisation:
for (i = 0; i < isublength; i++){
temp = in_img[first_element + i];
if (temp<private_min) private_min = temp;
}
}}}
A driver function was used to verify (to some small extent) the parallel implementation against the reference one. Yes, this should be expanded for greater confidence.
{{{
int main (int argc, const char*const*const argv)
{
// min is 0.5f:
const float a_test[] = {1.f, 2.f, 4.f, 55.f, 12.f, 0.5f, 57.f };
const unsigned ilen = sizeof(a_test) / sizeof(float);
const float min_ref = singlethread_min_of_array(a_test, ilen);
const float manual_min = manual_min_of_array(a_test, ilen);
if(min_ref != manual_min)
{
fprintf(stderr, "ERROR: Wrong result!\n");
return -1;
}
fprintf(stderr, "SUCCESS: Correct result!\n");
return 0;
}
}}}
If the above fragments are pasted into a file called openmp.cpp, they can be built for gcc 4.3.2 like this:
{{{
g++ -fopenmp -O3 -march=pentium3 -ffast-math openmp.cpp -o openmp_test
}}}
Or, just grab these files: [[openmp.cpp|openmp.cpp]] and [[build_openmp.sh|build_openmp.sh]].
Any feedback on a better way to achieve this would be most welcome. Compiler support for min, max, and user-defined reductions (in the style of lambda functions perhaps) even more so.
Andrew Cox
These videos show slicemap voxelisation that is purely surface-based. There is no filling-in of the interiors of objects. <html><object width="100%" height="720"><param name="movie" value="http://www.youtube.com/v/BzeNA3eyRWI&hl=en&fs=1&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/BzeNA3eyRWI&hl=en&fs=1&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="720"></embed></object></html> <html><object width="100%" height="720"><param name="movie" value="http://www.youtube.com/v/cuBPmMCT9Lk&hl=en&fs=1&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/cuBPmMCT9Lk&hl=en&fs=1&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="720"></embed></object></html>
This video shows that sponza will not work for solid slicemap voxelisation. The hard-edged green areas highlight failures in the process.<html><object width="100%" height="720"><param name="movie" value="http://www.youtube.com/v/nmbhT_L51fs&hl=en&fs=1&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/nmbhT_L51fs&hl=en&fs=1&hd=1 type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="720"></embed></object></html>
[[StyleSheetSyntaxHighlighter]]
/***
StyleSheet for ~SyntaxHighlighter
***/
/*{{{*/
.dp-highlighter
{
font-family: "Consolas", "Courier New", Courier, mono, serif;
font-size: 12px;
background-color: #E7E5DC;
width: 99%;
overflow: auto;
margin: 18px 0 18px 0 !important;
padding-top: 1px; /* adds a little border on top when controls are hidden */
}
/* clear styles */
.dp-highlighter ol,
.dp-highlighter ol li,
.dp-highlighter ol li span
{
margin: 0;
padding: 0;
border: none;
}
.dp-highlighter a,
.dp-highlighter a:hover
{
background: none;
border: none;
padding: 0;
margin: 0;
}
.dp-highlighter .bar
{
padding-left: 45px;
}
.dp-highlighter.collapsed .bar,
.dp-highlighter.nogutter .bar
{
padding-left: 0px;
}
.dp-highlighter ol
{
list-style: decimal; /* for ie */
background-color: #fff;
margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */
padding: 0px;
color: #5C5C5C;
}
.dp-highlighter.nogutter ol,
.dp-highlighter.nogutter ol li
{
list-style: none !important;
margin-left: 0px !important;
}
.dp-highlighter ol li,
.dp-highlighter .columns div
{
list-style: decimal-leading-zero; /* better look for others, override cascade from OL */
list-style-position: outside !important;
border-left: 3px solid #6CE26C;
background-color: #F8F8F8;
color: #5C5C5C;
padding: 0 3px 0 10px !important;
margin: 0 !important;
line-height: 14px;
}
.dp-highlighter.nogutter ol li,
.dp-highlighter.nogutter .columns div
{
border: 0;
}
.dp-highlighter .columns
{
background-color: #F8F8F8;
color: gray;
overflow: hidden;
width: 100%;
}
.dp-highlighter .columns div
{
padding-bottom: 5px;
}
.dp-highlighter ol li.alt
{
background-color: #FFF;
color: inherit;
}
.dp-highlighter ol li span
{
color: black;
background-color: inherit;
}
/* Adjust some properties when collapsed */
.dp-highlighter.collapsed ol
{
margin: 0px;
}
.dp-highlighter.collapsed ol li
{
display: none;
}
/* Additional modifications when in print-view */
.dp-highlighter.printing
{
border: none;
}
.dp-highlighter.printing .tools
{
display: none !important;
}
.dp-highlighter.printing li
{
display: list-item !important;
}
/* Styles for the tools */
.dp-highlighter .tools
{
padding: 3px 8px 3px 10px;
font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif;
color: silver;
background-color: #f8f8f8;
padding-bottom: 10px;
border-left: 3px solid #6CE26C;
}
.dp-highlighter.nogutter .tools
{
border-left: 0;
}
.dp-highlighter.collapsed .tools
{
border-bottom: 0;
}
.dp-highlighter .tools a
{
font-size: 9px;
color: #a0a0a0;
background-color: inherit;
text-decoration: none;
margin-right: 10px;
}
.dp-highlighter .tools a:hover
{
color: red;
background-color: inherit;
text-decoration: underline;
}
/* About dialog styles */
.dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; }
.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; }
.dp-about td { padding: 10px; vertical-align: top; }
.dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; }
.dp-about .title { color: red; background-color: inherit; font-weight: bold; }
.dp-about .para { margin: 0 0 4px 0; }
.dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; }
.dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; }
/* Language specific styles */
.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
.dp-highlighter .string { color: blue; background-color: inherit; }
.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
.dp-highlighter .preprocessor { color: gray; background-color: inherit; }
/*}}}*/
<html><object width="100%" height="720"><param name="movie" value="http://www.youtube.com/v/mF6t8ZwU0cE&hl=en&fs=1&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/mF6t8ZwU0cE&hl=en&fs=1&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="720"></embed></object></html>
/***
!Metadata:
|''Name:''|SyntaxHighlighterPlugin|
|''Description:''|Code Syntax Highlighter Plugin for TiddlyWiki.|
|''Version:''|1.1.3|
|''Date:''|Oct 24, 2008|
|''Source:''|http://www.coolcode.cn/show-310-1.html|
|''Author:''|Ma Bingyao (andot (at) ujn (dot) edu (dot) cn)|
|''License:''|[[GNU Lesser General Public License|http://www.gnu.org/licenses/lgpl.txt]]|
|''~CoreVersion:''|2.4.1|
|''Browser:''|Firefox 1.5+; InternetExplorer 6.0; Safari; Opera; Chrome; etc.|
!Syntax:
{{{
<code options>
codes
</code>
}}}
!Examples:
{{{
<code java>
public class HelloWorld {
public static void main(String args[]) {
System.out.println("HelloWorld!");
}
}
</code>
}}}
!Revision History:
|''Version''|''Date''|''Note''|
|1.1.2|Oct 15, 2008|Optimize Highlight|
|1.0.0|Oct 13, 2008|Initial release|
!Code section:
***/
//{{{
var dp={sh:{Toolbar:{},Utils:{},RegexLib:{},Brushes:{},Strings:{AboutDialog:"<html><head><title>About...</title></head><body class=\"dp-about\"><table cellspacing=\"0\"><tr><td class=\"copy\"><p class=\"title\">dp.SyntaxHighlighter</div><div class=\"para\">Version: {V}</p><p><a href=\"http://www.dreamprojections.com/syntaxhighlighter/?ref=about\" target=\"_blank\">http://www.dreamprojections.com/syntaxhighlighter</a></p>©2004-2007 Alex Gorbatchev.</td></tr><tr><td class=\"footer\"><input type=\"button\" class=\"close\" value=\"OK\" onClick=\"window.close()\"/></td></tr></table></body></html>"},ClipboardSwf:null,Version:"1.5.1"}};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:"+ expand source",check:function($){return $.collapse},func:function($,_){$.parentNode.removeChild($);_.div.className=_.div.className.replace("collapsed","")}},ViewSource:{label:"view plain",func:function($,_){var A=dp.sh.Utils.FixForBlogger(_.originalCode).replace(/</g,"<"),B=window.open("","_blank","width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0");B.document.write("<textarea style=\"width:99%;height:99%\">"+A+"</textarea>");B.document.close()}},CopyToClipboard:{label:"copy to clipboard",check:function(){return window.clipboardData!=null||dp.sh.ClipboardSwf!=null},func:function($,A){var B=dp.sh.Utils.FixForBlogger(A.originalCode).replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");if(window.clipboardData)window.clipboardData.setData("text",B);else if(dp.sh.ClipboardSwf!=null){var _=A.flashCopier;if(_==null){_=document.createElement("div");A.flashCopier=_;A.div.appendChild(_)}_.innerHTML="<embed src=\""+dp.sh.ClipboardSwf+"\" FlashVars=\"clipboard="+encodeURIComponent(B)+"\" width=\"0\" height=\"0\" type=\"application/x-shockwave-flash\"></embed>"}alert("The code is in your clipboard now")}},PrintSource:{label:"print",func:function($,B){var _=document.createElement("IFRAME"),A=null;_.style.cssText="position:absolute;width:0px;height:0px;left:-500px;top:-500px;";document.body.appendChild(_);A=_.contentWindow.document;dp.sh.Utils.CopyStyles(A,window.document);A.write("<div class=\""+B.div.className.replace("collapsed","")+" printing\">"+B.div.innerHTML+"</div>");A.close();_.contentWindow.focus();_.contentWindow.print();alert("Printing...");document.body.removeChild(_)}},About:{label:"?",func:function(_){var A=window.open("","_blank","dialog,width=300,height=150,scrollbars=0"),$=A.document;dp.sh.Utils.CopyStyles($,window.document);$.write(dp.sh.Strings.AboutDialog.replace("{V}",dp.sh.Version));$.close();A.focus()}}};dp.sh.Toolbar.Create=function(B){var A=document.createElement("DIV");A.className="tools";for(var _ in dp.sh.Toolbar.Commands){var $=dp.sh.Toolbar.Commands[_];if($.check!=null&&!$.check(B))continue;A.innerHTML+="<a href=\"#\" onclick=\"dp.sh.Toolbar.Command('"+_+"',this);return false;\">"+$.label+"</a>"}return A};dp.sh.Toolbar.Command=function(_,$){var A=$;while(A!=null&&A.className.indexOf("dp-highlighter")==-1)A=A.parentNode;if(A!=null)dp.sh.Toolbar.Commands[_].func($,A.highlighter)};dp.sh.Utils.CopyStyles=function(A,_){var $=_.getElementsByTagName("link");for(var B=0;B<$.length;B++)if($[B].rel.toLowerCase()=="stylesheet")A.write("<link type=\"text/css\" rel=\"stylesheet\" href=\""+$[B].href+"\"></link>")};dp.sh.Utils.FixForBlogger=function($){return(dp.sh.isBloggerMode==true)?$.replace(/<br\s*\/?>|<br\s*\/?>/gi,"\n"):$};dp.sh.RegexLib={MultiLineCComments:new RegExp("/\\*[\\s\\S]*?\\*/","gm"),SingleLineCComments:new RegExp("//.*$","gm"),SingleLinePerlComments:new RegExp("#.*$","gm"),DoubleQuotedString:new RegExp("\"(?:\\.|(\\\\\\\")|[^\\\"\"\\n])*\"","g"),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'","g")};dp.sh.Match=function(_,$,A){this.value=_;this.index=$;this.length=_.length;this.css=A};dp.sh.Highlighter=function(){this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true};dp.sh.Highlighter.SortCallback=function($,_){if($.index<_.index)return-1;else if($.index>_.index)return 1;else if($.length<_.length)return-1;else if($.length>_.length)return 1;return 0};dp.sh.Highlighter.prototype.CreateElement=function(_){var $=document.createElement(_);$.highlighter=this;return $};dp.sh.Highlighter.prototype.GetMatches=function(_,B){var $=0,A=null;while((A=_.exec(this.code))!=null)this.matches[this.matches.length]=new dp.sh.Match(A[0],A.index,B)};dp.sh.Highlighter.prototype.AddBit=function($,A){if($==null||$.length==0)return;var C=this.CreateElement("SPAN");$=$.replace(/ /g," ");$=$.replace(/</g,"<");$=$.replace(/\n/gm," <br>");if(A!=null){if((/br/gi).test($)){var _=$.split(" <br>");for(var B=0;B<_.length;B++){C=this.CreateElement("SPAN");C.className=A;C.innerHTML=_[B];this.div.appendChild(C);if(B+1<_.length)this.div.appendChild(this.CreateElement("BR"))}}else{C.className=A;C.innerHTML=$;this.div.appendChild(C)}}else{C.innerHTML=$;this.div.appendChild(C)}};dp.sh.Highlighter.prototype.IsInside=function(_){if(_==null||_.length==0)return false;for(var A=0;A<this.matches.length;A++){var $=this.matches[A];if($==null)continue;if((_.index>$.index)&&(_.index<$.index+$.length))return true}return false};dp.sh.Highlighter.prototype.ProcessRegexList=function(){for(var $=0;$<this.regexList.length;$++)this.GetMatches(this.regexList[$].regex,this.regexList[$].css)};dp.sh.Highlighter.prototype.ProcessSmartTabs=function(E){var B=E.split("\n"),$="",D=4,A="\t";function _(A,E,_){var B=A.substr(0,E),C=A.substr(E+1,A.length),$="";for(var D=0;D<_;D++)$+=" ";return B+$+C}function C(B,C){if(B.indexOf(A)==-1)return B;var D=0;while((D=B.indexOf(A))!=-1){var $=C-D%C;B=_(B,D,$)}return B}for(var F=0;F<B.length;F++)$+=C(B[F],D)+"\n";return $};dp.sh.Highlighter.prototype.SwitchToList=function(){var C=this.div.innerHTML.replace(/<(br)\/?>/gi,"\n"),B=C.split("\n");if(this.addControls==true)this.bar.appendChild(dp.sh.Toolbar.Create(this));if(this.showColumns){var A=this.CreateElement("div"),_=this.CreateElement("div"),E=10,G=1;while(G<=150)if(G%E==0){A.innerHTML+=G;G+=(G+"").length}else{A.innerHTML+="·";G++}_.className="columns";_.appendChild(A);this.bar.appendChild(_)}for(var G=0,D=this.firstLine;G<B.length-1;G++,D++){var $=this.CreateElement("LI"),F=this.CreateElement("SPAN");$.className=(G%2==0)?"alt":"";F.innerHTML=B[G]+" ";$.appendChild(F);this.ol.appendChild($)}this.div.innerHTML=""};dp.sh.Highlighter.prototype.Highlight=function(C){function A($){return $.replace(/^\s*(.*?)[\s\n]*$/g,"$1")}function $($){return $.replace(/\n*$/,"").replace(/^\n*/,"")}function _(B){var E=dp.sh.Utils.FixForBlogger(B).split("\n"),C=new Array(),D=new RegExp("^\\s*","g"),$=1000;for(var F=0;F<E.length&&$>0;F++){if(A(E[F]).length==0)continue;var _=D.exec(E[F]);if(_!=null&&_.length>0)$=Math.min(_[0].length,$)}if($>0)for(F=0;F<E.length;F++)E[F]=E[F].substr($);return E.join("\n")}function D(A,$,_){return A.substr($,_-$)}var F=0;if(C==null)C="";this.originalCode=C;this.code=$(_(C));this.div=this.CreateElement("DIV");this.bar=this.CreateElement("DIV");this.ol=this.CreateElement("OL");this.matches=new Array();this.div.className="dp-highlighter";this.div.highlighter=this;this.bar.className="bar";this.ol.start=this.firstLine;if(this.CssClass!=null)this.ol.className=this.CssClass;if(this.collapse)this.div.className+=" collapsed";if(this.noGutter)this.div.className+=" nogutter";if(this.tabsToSpaces==true)this.code=this.ProcessSmartTabs(this.code);this.ProcessRegexList();if(this.matches.length==0){this.AddBit(this.code,null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);return}this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var E=0;E<this.matches.length;E++)if(this.IsInside(this.matches[E]))this.matches[E]=null;for(E=0;E<this.matches.length;E++){var B=this.matches[E];if(B==null||B.length==0)continue;this.AddBit(D(this.code,F,B.index),null);this.AddBit(B.value,B.css);F=B.index+B.length}this.AddBit(this.code.substr(F),null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol)};dp.sh.Highlighter.prototype.GetKeywords=function($){return"\\b"+$.replace(/ /g,"\\b|\\b")+"\\b"};dp.sh.BloggerMode=function(){dp.sh.isBloggerMode=true};dp.sh.HighlightAll=function(N,B,K,I,O,E){function A(){var $=arguments;for(var _=0;_<$.length;_++){if($[_]==null)continue;if(typeof($[_])=="string"&&$[_]!="")return $[_]+"";if(typeof($[_])=="object"&&$[_].value!="")return $[_].value+""}return null}function J($,_){for(var A=0;A<_.length;A++)if(_[A]==$)return true;return false}function L(A,B,C){var _=new RegExp("^"+A+"\\[(\\w+)\\]$","gi"),$=null;for(var D=0;D<B.length;D++)if(($=_.exec(B[D]))!=null)return $[1];return C}function C(B,A,_){var $=document.getElementsByTagName(_);for(var C=0;C<$.length;C++)if($[C].getAttribute("name")==A)B.push($[C])}var T=[],P=null,M={},$="innerHTML";C(T,N,"pre");C(T,N,"textarea");if(T.length==0)return;for(var R in dp.sh.Brushes){var F=dp.sh.Brushes[R].Aliases;if(F==null)continue;for(var G=0;G<F.length;G++)M[F[G]]=R}for(G=0;G<T.length;G++){var _=T[G],U=A(_.attributes["class"],_.className,_.attributes["language"],_.language),Q="";if(U==null)continue;U=U.split(":");Q=U[0].toLowerCase();if(M[Q]==null)continue;P=new dp.sh.Brushes[M[Q]]();_.style.display="none";P.noGutter=(B==null)?J("nogutter",U):!B;P.addControls=(K==null)?!J("nocontrols",U):K;P.collapse=(I==null)?J("collapse",U):I;P.showColumns=(E==null)?J("showcolumns",U):E;var D=document.getElementsByTagName("head")[0];if(P.Style&&D){var S=document.createElement("style");S.setAttribute("type","text/css");if(S.styleSheet)S.styleSheet.cssText=P.Style;else{var H=document.createTextNode(P.Style);S.appendChild(H)}D.appendChild(S)}P.firstLine=(O==null)?parseInt(L("firstline",U,1)):O;P.Highlight(_[$]);P.source=_;_.parentNode.insertBefore(P.div,_)}};version.extensions.SyntaxHighLighterPlugin={major:1,minor:1,revision:3,date:new Date(2008,10,24)};dp.sh.ClipboardSwf="clipboard.swf";dp.sh.Highlight=function(_,Q,B,J,H,M,D){function A(){var $=arguments;for(var _=0;_<$.length;_++){if($[_]==null)continue;if(typeof($[_])=="string"&&$[_]!="")return $[_]+"";if(typeof($[_])=="object"&&$[_].value!="")return $[_].value+""}return null}function I($,_){for(var A=0;A<_.length;A++)if(_[A]==$)return true;return false}function K(A,B,C){var _=new RegExp("^"+A+"\\[(\\w+)\\]$","gi"),$=null;for(var D=0;D<B.length;D++)if(($=_.exec(B[D]))!=null)return $[1];return C}var N=null,$="innerHTML";if(this.registered==undefined){var L={};for(var O in dp.sh.Brushes){var E=dp.sh.Brushes[O].Aliases;if(E==null)continue;for(var F=0;F<E.length;F++)L[E[F]]=O}this.registered=L}Q=Q.split(":");language=Q[0].toLowerCase();if(this.registered[language]==null)return;N=new dp.sh.Brushes[this.registered[language]]();_.style.display="none";N.noGutter=(B==null)?I("nogutter",Q):!B;N.addControls=(J==null)?!I("nocontrols",Q):J;N.collapse=(H==null)?I("collapse",Q):H;N.showColumns=(D==null)?I("showcolumns",Q):D;var C=document.getElementsByTagName("head")[0],P=document.getElementById(N.CssClass);if(N.Style&&C&&!P){P=document.createElement("style");P.setAttribute("id",N.CssClass);P.setAttribute("type","text/css");if(P.styleSheet)P.styleSheet.cssText=N.Style;else{var G=document.createTextNode(N.Style);P.appendChild(G)}C.appendChild(P)}N.firstLine=(M==null)?parseInt(K("firstline",Q,1)):M;N.Highlight(_[$]);N.source=_;_.parentNode.insertBefore(N.div,_)};config.formatters.push({name:"SyntaxHighlighter",match:"^<code[\\s]+[^>]+>\\n",element:"pre",handler:function(_){this.lookaheadRegExp=/<code[\s]+([^>]+)>\n((?:^[^\n]*\n)+?)(^<\/code>$\n?)/mg;this.lookaheadRegExp.lastIndex=_.matchStart;var $=this.lookaheadRegExp.exec(_.source);if($&&$.index==_.matchStart){var C=$[1],B=$[2];if(config.browser.isIE)B=B.replace(/\n/g,"\r");var A=createTiddlyElement(_.output,this.element,null,null,B);dp.sh.Highlight(A,C);_.nextMatch=$.index+$[0].length}}});config.formatterHelpers.enclosedTextHelper=function(_){this.lookaheadRegExp.lastIndex=_.matchStart;var $=this.lookaheadRegExp.exec(_.source);if($&&$.index==_.matchStart){var B=$[1];if(config.browser.isIE)B=B.replace(/\n/g,"\r");var A=createTiddlyElement(_.output,this.element,null,null,B);switch(_.matchText){case"/*{{{*/\n":dp.sh.Highlight(A,"css");break;case"//{{{\n":dp.sh.Highlight(A,"js");break;case"<!--{{{-->\n":dp.sh.Highlight(A,"xml");break}_.nextMatch=$.index+$[0].length}};dp.sh.Brushes.AS3=function(){var _="class interface package",$="Array Boolean Date decodeURI decodeURIComponent encodeURI encodeURIComponent escape "+"int isFinite isNaN isXMLName Number Object parseFloat parseInt "+"String trace uint unescape XML XMLList "+"Infinity -Infinity NaN undefined "+"as delete instanceof is new typeof "+"break case catch continue default do each else finally for if in "+"label return super switch throw try while with "+"dynamic final internal native override private protected public static "+"...rest const extends function get implements namespace set "+"import include use "+"AS3 flash_proxy object_proxy "+"false null this true "+"void Null";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"blockcomment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"definition"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp("var","gm"),css:"variable"}];this.CssClass="dp-as";this.Style=".dp-as .comment { color: #009900; font-style: italic; }"+".dp-as .blockcomment { color: #3f5fbf; }"+".dp-as .string { color: #990000; }"+".dp-as .preprocessor { color: #0033ff; }"+".dp-as .definition { color: #9900cc; font-weight: bold; }"+".dp-as .keyword { color: #0033ff; }"+".dp-as .variable { color: #6699cc; font-weight: bold; }"};dp.sh.Brushes.AS3.prototype=new dp.sh.Highlighter();dp.sh.Brushes.AS3.Aliases=["as","actionscript","ActionScript","as3","AS3"];dp.sh.Brushes.Bash=function(){var _="alias bg bind break builtin cd command compgen complete continue "+"declare dirs disown echo enable eval exec exit export fc fg "+"getopts hash help history jobs kill let local logout popd printf "+"pushd pwd read readonly return set shift shopt source "+"suspend test times trap type typeset ulimit umask unalias unset wait",$="case do done elif else esac fi for function if in select then "+"time until while";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("[()[\\]{}]","g"),css:"delim"},{regex:new RegExp("\\$\\w+","g"),css:"vars"},{regex:new RegExp("\\w+=","g"),css:"vars"},{regex:new RegExp("\\s-\\w+","g"),css:"flag"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-bash";this.Style=".dp-bash .builtin {color: maroon; font-weight: bold;}"+".dp-bash .comment {color: gray;}"+".dp-bash .delim {font-weight: bold;}"+".dp-bash .flag {color: green;}"+".dp-bash .string {color: red;}"+".dp-bash .vars {color: blue;}"};dp.sh.Brushes.Bash.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Bash.Aliases=["bash","sh"];dp.sh.Brushes.Batch=function(){var _="APPEND ATTRIB CD CHDIR CHKDSK CHOICE CLS COPY DEL ERASE DELTREE "+"DIR EXIT FC COMP FDISK FIND FORMAT FSUTIL HELP JOIN "+"LABEL LOADFIX MK MKDIR MEM MEMMAKER MORE MOVE MSD PCPARK "+"PRINT RD RMDIR REN SCANDISK SHARE SORT SUBST SYS "+"TIME DATE TREE TRUENAME TYPE UNDELETE VER XCOPY",$="DO ELSE FOR IN CALL CHOICE GOTO SHIFT PAUSE ERRORLEVEL "+"IF NOT EXIST LFNFOR START SETLOCAL ENDLOCAL ECHO SET";this.regexList=[{regex:new RegExp("REM.*$","gm"),css:"comment"},{regex:new RegExp("::.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("[()[\\]{}]","g"),css:"delim"},{regex:new RegExp("%\\w+%","g"),css:"vars"},{regex:new RegExp("%%\\w+","g"),css:"vars"},{regex:new RegExp("\\w+=","g"),css:"vars"},{regex:new RegExp("@\\w+","g"),css:"keyword"},{regex:new RegExp(":\\w+","g"),css:"keyword"},{regex:new RegExp("\\s/\\w+","g"),css:"flag"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-batch";this.Style=".dp-batch .builtin {color: maroon; font-weight: bold;}"+".dp-batch .comment {color: gray;}"+".dp-batch .delim {font-weight: bold;}"+".dp-batch .flag {color: green;}"+".dp-batch .string {color: red;}"+".dp-batch .vars {color: blue;font-weight: bold;}"};dp.sh.Brushes.Batch.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Batch.Aliases=["batch","dos"];dp.sh.Brushes.ColdFusion=function(){this.CssClass="dp-coldfusion";this.Style=".dp-coldfusion { font: 13px \"Courier New\", Courier, monospace; }"+".dp-coldfusion .tag, .dp-coldfusion .tag-name { color: #990033; }"+".dp-coldfusion .attribute { color: #990033; }"+".dp-coldfusion .attribute-value { color: #0000FF; }"+".dp-coldfusion .cfcomments { background-color: #FFFF99; color: #000000; }"+".dp-coldfusion .cfscriptcomments { color: #999999; }"+".dp-coldfusion .keywords { color: #0000FF; }"+".dp-coldfusion .mgkeywords { color: #CC9900; }"+".dp-coldfusion .numbers { color: #ff0000; }"+".dp-coldfusion .strings { color: green; }";this.mgKeywords="setvalue getvalue addresult viewcollection viewstate";this.keywords="var eq neq gt gte lt lte not and or true false "+"abs acos addsoaprequestheader addsoapresponseheader "+"arrayappend arrayavg arrayclear arraydeleteat arrayinsertat "+"arrayisempty arraylen arraymax arraymin arraynew "+"arrayprepend arrayresize arrayset arraysort arraysum "+"arrayswap arraytolist asc asin atn binarydecode binaryencode "+"bitand bitmaskclear bitmaskread bitmaskset bitnot bitor bitshln "+"bitshrn bitxor ceiling charsetdecode charsetencode chr cjustify "+"compare comparenocase cos createdate createdatetime createobject "+"createobject createobject createobject createobject createodbcdate "+"createodbcdatetime createodbctime createtime createtimespan "+"createuuid dateadd datecompare dateconvert datediff dateformat "+"datepart day dayofweek dayofweekasstring dayofyear daysinmonth "+"daysinyear de decimalformat decrementvalue decrypt decryptbinary "+"deleteclientvariable directoryexists dollarformat duplicate encrypt "+"encryptbinary evaluate exp expandpath fileexists find findnocase "+"findoneof firstdayofmonth fix formatbasen generatesecretkey "+"getauthuser getbasetagdata getbasetaglist getbasetemplatepath "+"getclientvariableslist getcontextroot getcurrenttemplatepath "+"getdirectoryfrompath getencoding getexception getfilefrompath "+"getfunctionlist getgatewayhelper gethttprequestdata gethttptimestring "+"getk2serverdoccount getk2serverdoccountlimit getlocale "+"getlocaledisplayname getlocalhostip getmetadata getmetricdata "+"getpagecontext getprofilesections getprofilestring getsoaprequest "+"getsoaprequestheader getsoapresponse getsoapresponseheader "+"gettempdirectory gettempfile gettemplatepath gettickcount "+"gettimezoneinfo gettoken hash hour htmlcodeformat htmleditformat "+"iif incrementvalue inputbasen insert int isarray isbinary isboolean "+"iscustomfunction isdate isdebugmode isdefined isk2serverabroker "+"isk2serverdoccountexceeded isk2serveronline isleapyear islocalhost "+"isnumeric isnumericdate isobject isquery issimplevalue issoaprequest "+"isstruct isuserinrole isvalid isvalid isvalid iswddx isxml "+"isxmlattribute isxmldoc isxmlelem isxmlnode isxmlroot javacast "+"jsstringformat lcase left len listappend listchangedelims listcontains "+"listcontainsnocase listdeleteat listfind listfindnocase listfirst "+"listgetat listinsertat listlast listlen listprepend listqualify "+"listrest listsetat listsort listtoarray listvaluecount "+"listvaluecountnocase ljustify log log10 lscurrencyformat lsdateformat "+"lseurocurrencyformat lsiscurrency lsisdate lsisnumeric lsnumberformat "+"lsparsecurrency lsparsedatetime lsparseeurocurrency lsparsenumber "+"lstimeformat ltrim max mid min minute month monthasstring now "+"numberformat paragraphformat parameterexists parsedatetime pi "+"preservesinglequotes quarter queryaddcolumn queryaddrow querynew "+"querysetcell quotedvaluelist rand randomize randrange refind "+"refindnocase releasecomobject removechars repeatstring replace "+"replacelist replacenocase rereplace rereplacenocase reverse right "+"rjustify round rtrim second sendgatewaymessage setencoding "+"setlocale setprofilestring setvariable sgn sin spanexcluding "+"spanincluding sqr stripcr structappend structclear structcopy "+"structcount structdelete structfind structfindkey structfindvalue "+"structget structinsert structisempty structkeyarray structkeyexists "+"structkeylist structnew structsort structupdate tan timeformat "+"tobase64 tobinary toscript tostring trim ucase urldecode urlencodedformat "+"urlsessionformat val valuelist week wrap writeoutput xmlchildpos "+"xmlelemnew xmlformat xmlgetnodetype xmlnew xmlparse xmlsearch xmltransform "+"xmlvalidate year yesnoformat";this.stringMatches=new Array();this.attributeMatches=new Array()};dp.sh.Brushes.ColdFusion.prototype=new dp.sh.Highlighter();dp.sh.Brushes.ColdFusion.Aliases=["coldfusion","cf"];dp.sh.Brushes.ColdFusion.prototype.ProcessRegexList=function(){function B(_,$){_[_.length]=$}function A(A,$){for(var _=0;_<A.length;_++)if(A[_]==$)return _;return-1}var _=null,$=null;this.GetMatches(new RegExp("\\b(\\d+)","gm"),"numbers");this.GetMatches(new RegExp(this.GetKeywords(this.mgKeywords),"igm"),"mgkeywords");this.GetMatches(dp.sh.RegexLib.SingleLineCComments,"cfscriptcomments");this.GetMatches(dp.sh.RegexLib.MultiLineCComments,"cfscriptcomments");this.GetMatches(new RegExp("(<|<)!---[\\s\\S]*?---(>|>)","gm"),"cfcomments");$=new RegExp("(cfset\\s*)?([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?')*","gm");while((_=$.exec(this.code))!=null){if(_[1]!=undefined&&_[1]!="")continue;if(_[3]!=undefined&&_[3]!=""&&_[3]!="\"\""&&_[3]!="''"){B(this.matches,new dp.sh.Match(_[2],_.index,"attribute"));B(this.matches,new dp.sh.Match(_[3],_.index+_[0].indexOf(_[3]),"attribute-value"));B(this.stringMatches,_[3]);B(this.attributeMatches,_[2])}}this.GetMatches(new RegExp("(<|<)/*\\?*(?!\\!)|/*\\?*(>|>)","gm"),"tag");$=new RegExp("(?:<|<)/*\\?*\\s*([:\\w-.]+)","gm");while((_=$.exec(this.code))!=null)B(this.matches,new dp.sh.Match(_[1],_.index+_[0].indexOf(_[1]),"tag-name"));$=new RegExp(this.GetKeywords(this.keywords),"igm");while((_=$.exec(this.code))!=null)if(A(this.attributeMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"keywords"));$=new RegExp("cfset\\s*.*(\".*?\"|'.*?')","gm");while((_=$.exec(this.code))!=null)if(_[1]!=undefined&&_[1]!=""){B(this.matches,new dp.sh.Match(_[1],_.index+_[0].indexOf(_[1]),"strings"));B(this.stringMatches,_[1])}while((_=dp.sh.RegexLib.DoubleQuotedString.exec(this.code))!=null)if(A(this.stringMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"strings"));while((_=dp.sh.RegexLib.SingleQuotedString.exec(this.code))!=null)if(A(this.stringMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"strings"))};dp.sh.Brushes.Cpp=function(){var _="ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR "+"DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH "+"HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP "+"HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY "+"HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT "+"HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE "+"LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF "+"LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR "+"LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR "+"PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT "+"PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 "+"POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR "+"PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 "+"PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT "+"SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG "+"ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM "+"char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t "+"clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS "+"FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t "+"__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t "+"jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler "+"sig_atomic_t size_t _stat __stat64 _stati64 terminate_function "+"time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf "+"va_list wchar_t wctrans_t wctype_t wint_t signed",$="break case catch class const __finally __exception __try "+"const_cast continue private public protected __declspec "+"default delete deprecated dllexport dllimport do dynamic_cast "+"else enum explicit extern if for friend goto inline "+"mutable naked namespace new noinline noreturn nothrow "+"register reinterpret_cast return selectany "+"sizeof static static_cast struct switch template this "+"thread throw true false try typedef typeid typename union "+"using uuid virtual void volatile whcar_t while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^ *#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"datatypes"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-cpp";this.Style=".dp-cpp .datatypes { color: #2E8B57; font-weight: bold; }"};dp.sh.Brushes.Cpp.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Cpp.Aliases=["cpp","c","c++"];dp.sh.Brushes.CSharp=function(){var $="abstract as base bool break byte case catch char checked class const "+"continue decimal default delegate do double else enum event explicit "+"extern false finally fixed float for foreach get goto if implicit in int "+"interface internal is lock long namespace new null object operator out "+"override params private protected public readonly ref return sbyte sealed set "+"short sizeof stackalloc static string struct switch this throw true try "+"typeof uint ulong unchecked unsafe ushort using virtual void while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c";this.Style=".dp-c .vars { color: #d00; }"};dp.sh.Brushes.CSharp.prototype=new dp.sh.Highlighter();dp.sh.Brushes.CSharp.Aliases=["c#","c-sharp","csharp"];dp.sh.Brushes.CSS=function(){var _="ascent azimuth background-attachment background-color background-image background-position "+"background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top "+"border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color "+"border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width "+"border-bottom-width border-left-width border-width border cap-height caption-side centerline clear clip color "+"content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display "+"elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font "+"height letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top "+"margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans "+"outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page "+"page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position "+"quotes richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress "+"table-layout text-align text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em "+"vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index",$="above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder "+"both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed "+"continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double "+"embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia "+"gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic "+"justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha "+"lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower "+"navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset "+"outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side "+"rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow "+"small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize "+"table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal "+"text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin "+"upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow",A="[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif";this.regexList=[{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\#[a-zA-Z0-9]{3,6}","g"),css:"value"},{regex:new RegExp("(-?\\d+)(.\\d+)?(px|em|pt|:|%|)","g"),css:"value"},{regex:new RegExp("!important","g"),css:"important"},{regex:new RegExp(this.GetKeywordsCSS(_),"gm"),css:"keyword"},{regex:new RegExp(this.GetValuesCSS($),"g"),css:"value"},{regex:new RegExp(this.GetValuesCSS(A),"g"),css:"value"}];this.CssClass="dp-css";this.Style=".dp-css .value { color: black; }"+".dp-css .important { color: red; }"};dp.sh.Highlighter.prototype.GetKeywordsCSS=function($){return"\\b([a-z_]|)"+$.replace(/ /g,"(?=:)\\b|\\b([a-z_\\*]|\\*|)")+"(?=:)\\b"};dp.sh.Highlighter.prototype.GetValuesCSS=function($){return"\\b"+$.replace(/ /g,"(?!-)(?!:)\\b|\\b()")+":\\b"};dp.sh.Brushes.CSS.prototype=new dp.sh.Highlighter();dp.sh.Brushes.CSS.Aliases=["css"];dp.sh.Brushes.Delphi=function(){var $="abs addr and ansichar ansistring array as asm begin boolean byte cardinal "+"case char class comp const constructor currency destructor div do double "+"downto else end except exports extended false file finalization finally "+"for function goto if implementation in inherited int64 initialization "+"integer interface is label library longint longword mod nil not object "+"of on or packed pansichar pansistring pchar pcurrency pdatetime pextended "+"pint64 pointer private procedure program property pshortstring pstring "+"pvariant pwidechar pwidestring protected public published raise real real48 "+"record repeat set shl shortint shortstring shr single smallint string then "+"threadvar to true try type unit until uses val var varirnt while widechar "+"widestring with word write writeln xor";this.regexList=[{regex:new RegExp("\\(\\*[\\s\\S]*?\\*\\)","gm"),css:"comment"},{regex:new RegExp("{(?!\\$)[\\s\\S]*?}","gm"),css:"comment"},{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\{\\$[a-zA-Z]+ .+\\}","g"),css:"directive"},{regex:new RegExp("\\b[\\d\\.]+\\b","g"),css:"number"},{regex:new RegExp("\\$[a-zA-Z0-9]+\\b","g"),css:"number"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-delphi";this.Style=".dp-delphi .number { color: blue; }"+".dp-delphi .directive { color: #008284; }"+".dp-delphi .vars { color: #000; }"};dp.sh.Brushes.Delphi.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Delphi.Aliases=["delphi","pascal"];dp.sh.Brushes.Java=function(){var $="abstract assert boolean break byte case catch char class const "+"continue default do double else enum extends "+"false final finally float for goto if implements import "+"instanceof int interface long native new null "+"package private protected public return "+"short static strictfp super switch synchronized this throw throws true "+"transient try void volatile while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b","gi"),css:"number"},{regex:new RegExp("(?!\\@interface\\b)\\@[\\$\\w]+\\b","g"),css:"annotation"},{regex:new RegExp("\\@interface\\b","g"),css:"keyword"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-j";this.Style=".dp-j .annotation { color: #646464; }"+".dp-j .number { color: #C00000; }"};dp.sh.Brushes.Java.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Java.Aliases=["java"];dp.sh.Brushes.JScript=function(){var $="abstract boolean break byte case catch char class const continue debugger "+"default delete do double else enum export extends false final finally float "+"for function goto if implements import in instanceof int interface long native "+"new null package private protected public return short static super switch "+"synchronized this throw throws transient true try typeof var void volatile while with";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c"};dp.sh.Brushes.JScript.prototype=new dp.sh.Highlighter();dp.sh.Brushes.JScript.Aliases=["js","jscript","javascript"];dp.sh.Brushes.Lua=function(){var $="break do end else elseif function if local nil not or repeat return and then until while this",_="math\\.\\w+ string\\.\\w+ os\\.\\w+ debug\\.\\w+ io\\.\\w+ error fopen dofile coroutine\\.\\w+ arg getmetatable ipairs loadfile loadlib loadstring longjmp print rawget rawset seek setmetatable assert tonumber tostring";this.regexList=[{regex:new RegExp("--\\[\\[[\\s\\S]*\\]\\]--","gm"),css:"comment"},{regex:new RegExp("--[^\\[]{2}.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"func"},];this.CssClass="dp-lua"};dp.sh.Brushes.Lua.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Lua.Aliases=["lua"];dp.sh.Brushes.Mxml=function(){this.CssClass="dp-mxml";this.Style=".dp-mxml .cdata { color: #000000; }"+".dp-mxml .tag { color : #0000ff; }"+".dp-mxml .tag-name { color: #0000ff; }"+".dp-mxml .script { color: green; }"+".dp-mxml .metadata { color: green; }"+".dp-mxml .attribute { color: #000000; }"+".dp-mxml .attribute-value { color: #990000; }"+".dp-mxml .trace { color: #cc6666; }"+".dp-mxml .var { color: #6699cc; }"+".dp-mxml .comment { color: #009900; }"+".dp-mxml .string { color: #990000; }"+".dp-mxml .keyword { color: blue; }"};dp.sh.Brushes.Mxml.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Mxml.Aliases=["mxml"];dp.sh.Brushes.Mxml.prototype.ProcessRegexList=function(){function H(_,$){_[_.length]=$}function B(B,_){var A=0,$=false;for(A=0;A<B.length;A++)if(_.index>B[A].firstIndex&&_.index<B[A].lastIndex)$=true;return $}var $=0,F=null,D=null,A=null,C="",E=new Array(),_="abstract boolean break byte case catch char class const continue debugger "+"default delete do double else enum export extends false final finally float "+"for function goto if implements import in instanceof int interface long native "+"new null package private protected public return short static super switch "+"synchronized this throw throws transient true try typeof var void volatile while with",G=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords("trace"),"gm"),css:"trace"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"keyword"}];A=new RegExp("<\\!\\[CDATA\\[(.|\\s)*?\\]\\]>","gm");while((F=A.exec(this.code))!=null){C=F[0].substr(0,12);H(this.matches,new dp.sh.Match(C,F.index,"cdata"));C=F[0].substr(12,F[0].length-12-6);for(var I=0;I<G.length;I++)while((D=G[I].regex.exec(C))!=null)H(this.matches,new dp.sh.Match(D[0],F.index+12+D.index,G[I].css));C=F[0].substr(F[0].length-6,6);H(this.matches,new dp.sh.Match(C,F.index+F[0].length-6,"cdata"));E.push({firstIndex:F.index,lastIndex:F.index+F[0].length-1})}this.GetMatches(new RegExp("(<|<)!--\\s*.*?\\s*--(>|>)","gm"),"comments");A=new RegExp("([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?'|\\w+)*|(\\w+)","gm");while((F=A.exec(this.code))!=null){if(F[1]==null)continue;if(B(E,F))continue;H(this.matches,new dp.sh.Match(F[1],F.index,"attribute"));if(F[2]!=undefined)H(this.matches,new dp.sh.Match(F[2],F.index+F[0].indexOf(F[2]),"attribute-value"))}A=new RegExp("(?:<|<)/*\\?*\\s*([:\\w-.]+)","gm");while((F=A.exec(this.code))!=null){if(B(E,F))continue;C=F[0].substr(4,F[0].length-4);switch(C){case"mx:Script":case"/mx:Script":H(this.matches,new dp.sh.Match(F[0]+">",F.index,"script"));break;case"mx:Metadata":case"/mx:Metadata":H(this.matches,new dp.sh.Match(F[0]+">",F.index,"metadata"));break;default:H(this.matches,new dp.sh.Match(F[0],F.index,"tag-name"));break}}A=new RegExp("\\?>|>|/>","gm");while((F=A.exec(this.code))!=null){if(B(E,F))continue;H(this.matches,new dp.sh.Match(F[0],F.index,"tag"))}};dp.sh.Brushes.Perl=function(){var _="abs accept alarm atan2 bind binmode bless caller chdir chmod chomp chop chown chr chroot close closedir connect cos crypt dbmclose dbmopen defined delete dump each endgrent endhostent endnetent endprotoent endpwent endservent eof exec exists exp fcntl fileno flock fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getppid getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt glob gmtime grep hex import index int ioctl join keys kill lc lcfirst length link listen localtime lock log lstat m map mkdir msgctl msgget msgrcv msgsnd no oct open opendir ord pack pipe pop pos print printf prototype push q qq quotemeta qw qx rand read readdir readline readlink readpipe recv ref rename reset reverse rewinddir rindex rmdir scalar seek seekdir semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unlink unpack unshift untie utime values vec waitpid wantarray warn write qr",$="s select goto die do package redo require return continue for foreach last next wait while use if else elsif eval exit unless switch case",A="my our local";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("(\\$|@|%)\\w+","g"),css:"vars"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(A),"gm"),css:"declarations"}];this.CssClass="dp-perl"};dp.sh.Brushes.Perl.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Perl.Aliases=["perl"];dp.sh.Brushes.Php=function(){var _="abs acos acosh addcslashes addslashes "+"array_change_key_case array_chunk array_combine array_count_values array_diff "+"array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill "+"array_filter array_flip array_intersect array_intersect_assoc array_intersect_key "+"array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map "+"array_merge array_merge_recursive array_multisort array_pad array_pop array_product "+"array_push array_rand array_reduce array_reverse array_search array_shift "+"array_slice array_splice array_sum array_udiff array_udiff_assoc "+"array_udiff_uassoc array_uintersect array_uintersect_assoc "+"array_uintersect_uassoc array_unique array_unshift array_values array_walk "+"array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert "+"basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress "+"bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir "+"checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists "+"closedir closelog copy cos cosh count count_chars date decbin dechex decoct "+"deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log "+"error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded "+"feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents "+"fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype "+"floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf "+"fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname "+"gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt "+"getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext "+"gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set "+"interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double "+"is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long "+"is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault "+"is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br "+"parse_ini_file parse_str parse_url passthru pathinfo readlink realpath rewind rewinddir rmdir "+"round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split "+"str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes "+"stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk "+"strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime "+"strtoupper strtr strval substr substr_compare",$="and or xor __FILE__ __LINE__ array as break case "+"cfunction class const continue declare default die do else "+"elseif empty enddeclare endfor endforeach endif endswitch endwhile "+"extends for foreach function include include_once global if "+"new old_function return static switch use require require_once "+"var while __FUNCTION__ __CLASS__ "+"__METHOD__ abstract interface public implements extends private protected throw";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\$\\w+","g"),css:"vars"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c"};dp.sh.Brushes.Php.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Php.Aliases=["php"];dp.sh.Brushes.Python=function(){var $="and assert break class continue def del elif else "+"except exec finally for from global if import in is "+"lambda not or pass print raise return try yield while",_="None True False self cls class_";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:new RegExp("^\\s*@\\w+","gm"),css:"decorator"},{regex:new RegExp("(['\"]{3})([^\\1])*?\\1","gm"),css:"comment"},{regex:new RegExp("\"(?!\")(?:\\.|\\\\\\\"|[^\\\"\"\\n\\r])*\"","gm"),css:"string"},{regex:new RegExp("'(?!')*(?:\\.|(\\\\\\')|[^\\''\\n\\r])*'","gm"),css:"string"},{regex:new RegExp("\\b\\d+\\.?\\w*","g"),css:"number"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"special"}];this.CssClass="dp-py";this.Style=".dp-py .builtins { color: #ff1493; }"+".dp-py .magicmethods { color: #808080; }"+".dp-py .exceptions { color: brown; }"+".dp-py .types { color: brown; font-style: italic; }"+".dp-py .commonlibs { color: #8A2BE2; font-style: italic; }"};dp.sh.Brushes.Python.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Python.Aliases=["py","python"];dp.sh.Brushes.Ruby=function(){var $="alias and BEGIN begin break case class def define_method defined do each else elsif "+"END end ensure false for if in module new next nil not or raise redo rescue retry return "+"self super then throw true undef unless until when while yield",_="Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload "+"Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol "+"ThreadGroup Thread Time TrueClass";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(":[a-z][A-Za-z0-9_]*","g"),css:"symbol"},{regex:new RegExp("(\\$|@@|@)\\w+","g"),css:"variable"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"}];this.CssClass="dp-rb";this.Style=".dp-rb .symbol { color: #a70; }"+".dp-rb .variable { color: #a70; font-weight: bold; }"};dp.sh.Brushes.Ruby.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Ruby.Aliases=["ruby","rails","ror"];dp.sh.Brushes.Sql=function(){var _="abs avg case cast coalesce convert count current_timestamp "+"current_user day isnull left lower month nullif replace right "+"session_user space substring sum system_user upper user year",$="absolute action add after alter as asc at authorization begin bigint "+"binary bit by cascade char character check checkpoint close collate "+"column commit committed connect connection constraint contains continue "+"create cube current current_date current_time cursor database date "+"deallocate dec decimal declare default delete desc distinct double drop "+"dynamic else end end-exec escape except exec execute false fetch first "+"float for force foreign forward free from full function global goto grant "+"group grouping having hour ignore index inner insensitive insert instead "+"int integer intersect into is isolation key last level load local max min "+"minute modify move name national nchar next no numeric of off on only "+"open option order out output partial password precision prepare primary "+"prior privileges procedure public read real references relative repeatable "+"restrict return returns revoke rollback rollup rows rule schema scroll "+"second section select sequence serializable set size smallint static "+"statistics table temp temporary then time timestamp to top transaction "+"translation trigger true truncate uncommitted union unique update values "+"varchar varying view when where with work",A="all and any between cross in join like not null or outer some";this.regexList=[{regex:new RegExp("--(.*)$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords(A),"gmi"),css:"op"},{regex:new RegExp(this.GetKeywords($),"gmi"),css:"keyword"}];this.CssClass="dp-sql";this.Style=".dp-sql .func { color: #ff1493; }"+".dp-sql .op { color: #808080; }"};dp.sh.Brushes.Sql.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Sql.Aliases=["sql"];dp.sh.Brushes.Vb=function(){var $="AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto "+"Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate "+"CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType "+"Date Decimal Declare Default Delegate Dim DirectCast Do Double Each "+"Else ElseIf End Enum Erase Error Event Exit False Finally For Friend "+"Function Get GetType GoSub GoTo Handles If Implements Imports In "+"Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module "+"MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing "+"NotInheritable NotOverridable Object On Option Optional Or OrElse "+"Overloads Overridable Overrides ParamArray Preserve Private Property "+"Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume "+"Return Select Set Shadows Shared Short Single Static Step Stop String "+"Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until "+"Variant When While With WithEvents WriteOnly Xor";this.regexList=[{regex:new RegExp("'.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-vb"};dp.sh.Brushes.Vb.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Vb.Aliases=["vb","vb.net"];dp.sh.Brushes.Xml=function(){this.CssClass="dp-xml";this.Style=".dp-xml .cdata { color: #ff1493; }"+".dp-xml .tag, .dp-xml .tag-name { color: #069; font-weight: bold; }"+".dp-xml .attribute { color: red; }"+".dp-xml .attribute-value { color: blue; }"};dp.sh.Brushes.Xml.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Xml.Aliases=["xml","xhtml","xslt","html","xhtml"];dp.sh.Brushes.Xml.prototype.ProcessRegexList=function(){function B(_,$){_[_.length]=$}var $=0,A=null,_=null;this.GetMatches(new RegExp("(<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](>|>)","gm"),"cdata");this.GetMatches(new RegExp("(<|<)!--\\s*.*?\\s*--(>|>)","gm"),"comments");_=new RegExp("([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?'|\\w+)*|(\\w+)","gm");while((A=_.exec(this.code))!=null){if(A[1]==null)continue;B(this.matches,new dp.sh.Match(A[1],A.index,"attribute"));if(A[2]!=undefined)B(this.matches,new dp.sh.Match(A[2],A.index+A[0].indexOf(A[2]),"attribute-value"))}this.GetMatches(new RegExp("(<|<)/*\\?*(?!\\!)|/*\\?*(>|>)","gm"),"tag");_=new RegExp("(?:<|<)/*\\?*\\s*([:\\w-.]+)","gm");while((A=_.exec(this.code))!=null)B(this.matches,new dp.sh.Match(A[1],A.index+A[0].indexOf(A[1]),"tag-name"))}
//}}}
I'm a researcher on the project Lighting for Next Generation Games. My supervisor is [[Jan Kautz|http://www.cs.ucl.ac.uk/staff/J.Kautz/]]. My interests revolve around real time rendering, and the challenges of achieving indirect illumination provide my specific goals. In addition I am fascinated by how ~GPUs work internally and I care about how we go about programming them: about the abstractions that our ~APIs provide to us. I am currently a TA for the courses [[Graphics (GV10/3080)|Graphics GV10]] and [[Computer Architecture (1001)|Architecture 1001]], and previously for Graphics 2011G.
<html><object width="100%" height="720"><param name="movie" value="http://www.youtube.com/v/JKG5Hudc25w&hl=en&fs=1&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/JKG5Hudc25w&hl=en&fs=1&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="720"></embed></object></html>