Migrate aether post from 01451504315
This commit is contained in:
parent
f7e33d421f
commit
f67cd018ac
1 changed files with 198 additions and 0 deletions
198
_posts/2015-12-30-Coolest-C-Preprocessor-Trick-of-the-Year.html
Normal file
198
_posts/2015-12-30-Coolest-C-Preprocessor-Trick-of-the-Year.html
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: 'Coolest C Preprocessor Trick of the Year'
|
||||||
|
redirect_from:
|
||||||
|
- /01451504315
|
||||||
|
---
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Coolest C Preprocessor Trick of the Year</title>
|
||||||
|
<link rel="stylesheet" href="https://media.unpythonic.net/css/bootstrap.min.css">
|
||||||
|
<style>
|
||||||
|
|
||||||
|
|
||||||
|
#mask {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0.7;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading {
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
width: 58px;
|
||||||
|
height: 60px;
|
||||||
|
background-color: black;
|
||||||
|
background-image: url('https://media.unpythonic.net/img/loading.gif');
|
||||||
|
opacity: 0.9;
|
||||||
|
z-index: 20;
|
||||||
|
display: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bigimg {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#maskouter {
|
||||||
|
height: 100%;
|
||||||
|
display: table;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#maskinner {
|
||||||
|
vertical-align: middle;
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgleft, #imgright {
|
||||||
|
cursor: pointer;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: black;
|
||||||
|
z-index: 22;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgleft {
|
||||||
|
left: 0;
|
||||||
|
background-image: url('https://media.unpythonic.net/img/prevbtn.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgleft.disabled, #imgright.disabled { display: none; }
|
||||||
|
|
||||||
|
#imgright {
|
||||||
|
right: 0;
|
||||||
|
background-image: url('https://media.unpythonic.net/img/nextbtn.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgdesc {
|
||||||
|
position: fixed;
|
||||||
|
left: 64px;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #333;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
padding-left: 2em;
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgdesc .filename {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgdesc .description {
|
||||||
|
color: #fff;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mask { z-index: 10990; }
|
||||||
|
#loading { z-index: 10991; }
|
||||||
|
#bigimg { z-index: 10992; }
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript" src="https://media.unpythonic.net/js/jquery-1.6.4.min.js"></script>
|
||||||
|
<script type="text/javascript" src="https://media.unpythonic.net/js/bootstrap-dropdown.js"></script>
|
||||||
|
<script type="text/javascript" src="https://media.unpythonic.net/js/jquery.mousewheel.js"></script>
|
||||||
|
<script type="text/javascript" src="https://media.unpythonic.net/js/jquery.ba-hashchange.min.js"></script>
|
||||||
|
<script type="text/javascript" src="https://media.unpythonic.net/js/jquery.mobile.custom.min.js"></script>
|
||||||
|
<script type="text/javascript" src="https://media.unpythonic.net/js/gallery.js"></script>
|
||||||
|
<style><!--
|
||||||
|
div.floatimageleft, div.floatimageright {
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 2px;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
div.floatimageleft { clear: left; float: left; }
|
||||||
|
div.floatimageright { clear: right; float: right; }
|
||||||
|
div.floatimageleft img, div.floatimageright img { border: 0px; }
|
||||||
|
|
||||||
|
div.floatimageleft img.zoom, div.floatimageright img.zoom {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
--></style>
|
||||||
|
<style><!--
|
||||||
|
div.albumouter {
|
||||||
|
margin-right: 1ex;
|
||||||
|
margin-top: 1ex;
|
||||||
|
vertical-align: baseline;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album { display: block; clear: both; }
|
||||||
|
|
||||||
|
.album a:link, .album a:hover, .album a:visited
|
||||||
|
{ text-decoration: none; }
|
||||||
|
.album a:hover { color: red; }
|
||||||
|
|
||||||
|
.albumimage {
|
||||||
|
display: block;
|
||||||
|
padding-left: 2px; padding-right: 2px;
|
||||||
|
padding-top: 3px; padding-bottom: 3px;
|
||||||
|
background: #ececec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.albumimage img.zoom {
|
||||||
|
margin-left: 0px; margin-right: 0px;
|
||||||
|
padding-top: 4px; padding-right: 4px; }
|
||||||
|
.albumimage img { border: 0px;
|
||||||
|
display: block; margin-left: auto; margin-right:auto
|
||||||
|
}
|
||||||
|
--></style>
|
||||||
|
|
||||||
|
<!-- no summary found -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Probably everyone knew about this but me, but here goes anyway. (hat tip:
|
||||||
|
<a href="https://github.com/google/angle/blob/master/util/shader_utils.h#L19">Google's ANGLE library</a>)
|
||||||
|
|
||||||
|
<p>By suitably defining SHADER_SOURCE, you can write your shader program as
|
||||||
|
though it was just inline source in your larger C(++) program:
|
||||||
|
<pre>
|
||||||
|
const char * fs = SHADER_SOURCE
|
||||||
|
(
|
||||||
|
precision mediump float;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>The definition of SHADER_SOURCE is simple:
|
||||||
|
<pre>
|
||||||
|
#define SHADER_SOURCE(...) # __VA_ARGS__
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>This works as long as your shader is a valid sequence of preprocessor
|
||||||
|
tokens. If you need to also use shader language directives like
|
||||||
|
<tt>#version</tt>, you will need to write them as strings. But due to
|
||||||
|
the way string catenation works, you can do
|
||||||
|
|
||||||
|
<p><pre>
|
||||||
|
const char * fs =
|
||||||
|
"#version 100\n"
|
||||||
|
SHADER_SOURCE(...);
|
||||||
|
</pre>
|
||||||
|
and keep most of the inline shader source outside of strings.
|
||||||
|
<br><br><font size=-2>Entry first conceived on 30 December 2015, 19:38 UTC, last modified on 29 February 2016, 22:04 UTC</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in a new issue