Split, Reorganise, + Stefan's benchmark/demo code.

master
ijm 2011-03-23 04:29:07 -07:00
parent e02650cd13
commit b32fd115e5
18 changed files with 9921 additions and 0 deletions

172
benchmark/LICENSE-ashima Executable file
View File

@ -0,0 +1,172 @@
Artistic License 2.0
Copyright (c) 2000-2006, The Perl Foundation.
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Preamble
This license establishes the terms under which a given free software
Package may be copied, modified, distributed, and/or redistributed. The
intent is that the Copyright Holder maintains some artistic control over
the development of that Package while still keeping the Package
available as open source and free software.
You are always permitted to make arrangements wholly outside of this
license directly with the Copyright Holder of a given Package. If the
terms of this license do not permit the full use that you propose to
make of the Package, you should contact the Copyright Holder and seek a
different licensing arrangement.
Definitions
"Copyright Holder" means the individual(s) or organization(s) named in
the copyright notice for the entire Package.
"Contributor" means any party that has contributed code or other
material to the Package, in accordance with the Copyright Holder's
procedures.
"You" and "your" means any person who would like to copy, distribute, or
modify the Package.
"Package" means the collection of files distributed by the Copyright
Holder, and derivatives of that collection and/or of those files. A
given Package may consist of either the Standard Version, or a Modified
Version.
"Distribute" means providing a copy of the Package or making it
accessible to anyone else, or in the case of a company or organization,
to others outside of your company or organization.
"Distributor Fee" means any fee that you charge for Distributing this
Package or providing support for this Package to another party. It does
not mean licensing fees.
"Standard Version" refers to the Package if it has not been modified, or
has been modified only in ways explicitly requested by the Copyright
Holder.
"Modified Version" means the Package, if it has been changed, and such
changes were not explicitly requested by the Copyright Holder.
"Original License" means this Artistic License as Distributed with the
Standard Version of the Package, in its current version or as it may be
modified by The Perl Foundation in the future.
"Source" form means the source code, documentation source, and
configuration files for the Package.
"Compiled" form means the compiled bytecode, object code, binary, or any
other form resulting from mechanical transformation or translation of
the Source form.
Permission for Use and Modification Without Distribution
(1) You are permitted to use the Standard Version and create and use
Modified Versions for any purpose without restriction, provided that you
do not Distribute the Modified Version.
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the
Standard Version of this Package in any medium without restriction,
either gratis or for a Distributor Fee, provided that you duplicate all
of the original copyright notices and associated disclaimers. At your
discretion, such verbatim copies may or may not include a Compiled form
of the Package.
(3) You may apply any bug fixes, portability changes, and other
modifications made available from the Copyright Holder. The resulting
Package will still be considered the Standard Version, and as such will
be subject to the Original License.
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis or
for a Distributor Fee, and with or without a Compiled form of the
Modified Version) provided that you clearly document how it differs from
the Standard Version, including, but not limited to, documenting any
non-standard features, executables, or modules, and provided that you do
at least ONE of the following:
(a) make the Modified Version available to the Copyright Holder of the
Standard Version, under the Original License, so that the Copyright
Holder may include your modifications in the Standard Version.
(b) ensure that installation of your Modified Version does not prevent
the user installing or running the Standard Version. In addition, the
Modified Version must bear a name that is different from the name of the
Standard Version.
(c) allow anyone who receives a copy of the Modified Version to make the
Source form of the Modified Version available to others under
(i) the Original License or
(ii) a license that permits the licensee to freely copy, modify and
redistribute the Modified Version using the same licensing terms that
apply to the copy that the licensee received, and requires that the
Source form of the Modified Version, and of any works derived from it,
be made freely available in that license fees are prohibited but
Distributor Fees are allowed.
Distribution of Compiled Forms of the Standard Version or Modified
Versions without the Source
(5) You may Distribute Compiled forms of the Standard Version without
the Source, provided that you include complete instructions on how to
get the Source of the Standard Version. Such instructions must be valid
at the time of your distribution. If these instructions, at any time
while you are carrying out such distribution, become invalid, you must
provide new instructions on demand or cease further distribution. If you
provide valid instructions or cease distribution within thirty days
after you become aware that the instructions are invalid, then you do
not forfeit any of your rights under this license.
(6) You may Distribute a Modified Version in Compiled form without the
Source, provided that you comply with Section 4 with respect to the
Source of the Modified Version.
Aggregating or Linking the Package
(7) You may aggregate the Package (either the Standard Version or
Modified Version) with other packages and Distribute the resulting
aggregation provided that you do not charge a licensing fee for the
Package. Distributor Fees are permitted, and licensing fees for other
components in the aggregation are permitted. The terms of this license
apply to the use and Distribution of the Standard or Modified Versions
as included in the aggregation.
(8) You are permitted to link Modified and Standard Versions with other
works, to embed the Package in a larger work of your own, or to build
stand-alone binary or bytecode versions of applications that include the
Package, and Distribute the result without restriction, provided the
result does not expose a direct interface to the Package.
Items That are Not Considered Part of a Modified Version
(9) Works (including, but not limited to, modules and scripts) that
merely extend or make use of the Package, do not, by themselves, cause
the Package to be a Modified Version. In addition, such works are not
considered parts of the Package itself, and are not subject to the terms
of this license.
General Provisions
(10) Any use, modification, and distribution of the Standard or Modified
Versions is governed by this Artistic License. By using, modifying or
distributing the Package, you accept this license. Do not use, modify,
or distribute the Package, if you do not accept this license.
(11) If your Modified Version has been derived from a Modified Version
made by someone other than you, you are nevertheless required to ensure
that your Modified Version complies with the requirements of this
license.
(12) This license does not grant you the right to use any trademark,
service mark, tradename, or logo of the Copyright Holder.
(13) This license includes the non-exclusive, worldwide, free-of-charge
patent license to make, have made, use, offer to sell, sell, import and
otherwise transfer the Package with respect to any patent claims
licensable by the Copyright Holder that are necessarily infringed by the
Package. If you institute patent litigation (including a cross-claim or
counterclaim) against any party alleging that the Package constitutes
direct or contributory patent infringement, then this Artistic License
to you shall terminate on the date that such litigation is filed.
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT
HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT
PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER
OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

14
benchmark/Linux/Makefile Executable file
View File

@ -0,0 +1,14 @@
SHADERS=GLSL-ashimanoise.vert GLSL-ashimanoise2D.frag \
GLSL-ashimanoise3D.frag GLSL-ashimanoise4D.frag
COMDIR=../common
VPATH=$(COMDIR)
all: noisebench links_done
noisebench: noisebench.c
gcc -I. -I/usr/X11/include $^ -lglfw -o $@
links_done: $(SHADERS)
ln -s $? . ; touch links_done

24
benchmark/MacOSX/Makefile Normal file
View File

@ -0,0 +1,24 @@
SHADERS=GLSL-ashimanoise.vert GLSL-ashimanoise2D.frag \
GLSL-ashimanoise3D.frag GLSL-ashimanoise4D.frag
COMDIR=../common
VPATH=$(COMDIR)
OBJS=noisebench.o
CFLAGS=-I. -I/usr/X11/include
LDFLAGS=-framework Cocoa -framework OpenGL -lglfw
all: noisebench.app links_done
links_done: $(SHADERS)
ln -s $? . ; touch links_done
noisebench.app: noisebench
./bundle.sh $@ $^ ; chmod a-x $^
noisebench: $(OBJS)
clean:
rm -r noisebench.app; rm noisebench links_done $(OBJS) $(SHADERS)

56
benchmark/MacOSX/bundle.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/sh
# Creates application bundles for use on Mac OS X.
if [ -z "$1" ]; then
echo "usage: `basename $0` BUNDLE-NAME exec-name"
exit 1
fi
bundle_name="$1"
exec_file="$2"
if [ ! -f $exec_file ]; then
echo "Can't find $exec_file"
exit 1
fi
if [ ! -d "${bundle_name}/Contents/MacOS" ]; then
mkdir -p "${bundle_name}/Contents/MacOS"
fi
cp $exec_file "${bundle_name}/Contents/MacOS/"
touch "${bundle_name}"
if [ ! -d "${bundle_name}/Contents/Resources" ]; then
mkdir -p "${bundle_name}/Contents/Resources"
fi
if [ ! -f "${bundle_name}/Contents/PkgInfo" ]; then
echo -n "APPL????" > "${bundle_name}/Contents/PkgInfo"
fi
if [ ! -f "${bundle_name}/Contents/Info.plist" ]; then
cat > "${bundle_name}/Contents/Info.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${bundle_name}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.1</string>
</dict>
</plist>
EOF
fi

14
benchmark/README-ashima Executable file
View File

@ -0,0 +1,14 @@
This work follows Stefan Gustavson's paper "Simplex noise demystified"
http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
without using uniform arrays or texture engines.
A single vec4 uniform 'pParam' is used to set the length and a and
c constants respectively of the permutation polynomial to use. The
last element of the vec4 is the number of gradients to select from
on the vertices. An example vec4 is ( 19*19, 2*19, 1, 7 )
Refer to http://en.wikipedia.org/wiki/Permutation_polynomial for
more information on permutation polynomials.

30
benchmark/Win32/Makefile.win Executable file
View File

@ -0,0 +1,30 @@
# Project: GLSL-ashimanoise
# Makefile created by Dev-C++ 4.9.9.2
CPP = g++.exe -D__DEBUG__
CC = gcc.exe -D__DEBUG__
WINDRES = windres.exe
RES =
OBJ = noisebench.o $(RES)
LINKOBJ = noisebench.o $(RES)
LIBS = -L"C:/Dev-Cpp/lib" -mwindows -lglfw -lopengl32 -lglu32 -mconsole -g3
INCS = -I"C:/Dev-Cpp/include"
CXXINCS = -I"C:/Dev-Cpp/include"
BIN =noisebench.exe
CXXFLAGS = $(CXXINCS) -g3
CFLAGS = $(INCS) -Wall -O3 -ffast-math -I"C:\Dev-Cpp\include" -g3
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before noisebench.exe all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o "noisebench.exe" $(LIBS)
GLSLashimanoise.o: GLSLashimanoise.c
$(CC) -c noisebench.c -o noisebench.o $(CFLAGS)

8643
benchmark/Win32/glext.h Executable file

File diff suppressed because it is too large Load Diff

107
benchmark/Win32/noisebench.dev Executable file
View File

@ -0,0 +1,107 @@
[Project]
FileName=GLSL-ashimanoise.dev
Name=GLSL-ashimanoise
UnitCount=6
Type=0
Ver=1
ObjFiles=
Includes=
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-Wall -O3 -ffast-math -I"C:\Dev-Cpp\include"_@@_
CppCompiler=
Linker=-lglfw -lopengl32 -lglu32 -mconsole_@@_
IsCpp=0
Icon=
ExeOutput=
ObjectOutput=
OverrideOutput=0
OverrideOutputName=GLSL-test.exe
HostApplication=
Folders=
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000001010000
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit1]
FileName=GLSLashimanoise.c
CompileCpp=0
Folder=GLSL-test
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=glext.h
Folder=GLSL-test4
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
CompileCpp=0
[Unit3]
FileName=GLSL-ashimanoise2D.frag
Folder=GLSL-ashimanoise
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
CompileCpp=0
[Unit4]
FileName=GLSL-ashimanoise.vert
CompileCpp=0
Folder=GLSL-ashimanoise
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit5]
FileName=GLSL-ashimanoise3D.frag
Folder=
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=GLSL-ashimanoise4D.frag
Folder=
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@ -0,0 +1,41 @@
[Editor_3]
CursorCol=3
CursorRow=5
TopLine=1
LeftChar=1
Open=1
Top=0
[Editors]
Focused=0
Order=0,3,2,4,5
[Editor_0]
Open=1
Top=1
CursorCol=1
CursorRow=69
TopLine=37
LeftChar=1
[Editor_1]
Open=0
Top=0
[Editor_2]
Open=1
Top=0
CursorCol=1
CursorRow=2
TopLine=1
LeftChar=1
[Editor_4]
Open=1
Top=0
CursorCol=1
CursorRow=5
TopLine=1
LeftChar=1
[Editor_5]
Open=1
Top=0
CursorCol=15
CursorRow=8
TopLine=1
LeftChar=1

View File

@ -0,0 +1,18 @@
#version 120
uniform float time;
/*
* Both 2D and 3D texture coordinates are defined, for testing purposes.
*/
varying vec2 v_texCoord2D;
varying vec3 v_texCoord3D;
varying vec4 v_texCoord4D;
void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
v_texCoord2D = gl_MultiTexCoord0.xy * 16.0 + vec2(0.0, time);
v_texCoord3D = vec3(gl_MultiTexCoord0.xy * 16.0, time);
v_texCoord4D = vec4(gl_MultiTexCoord0.xy * 16.0, time, time);
}

25
benchmark/common/Makefile Normal file
View File

@ -0,0 +1,25 @@
OPTIONS=-DNORMALISE_GRADIENTS
SRCDIR=../../src
COMMON=commonShader.frag $(SRCDIR)/noiseStdLib.glsl
SHADERS=GLSL-ashimanoise2D.frag GLSL-ashimanoise3D.frag \
GLSL-ashimanoise4D.frag
all: $(SHADERS)
clean:
rm $(SHADERS)
GLSL-ashimanoise2D.frag: $(SRCDIR)/noise2D.glsl $(COMMON)
cpp -P -I$(SRCDIR) -DSHADER=\"noise2D.glsl\" \
-DVTYPE=vec2 -DVNAME=v_texCoord2D\
$(OPTIONS) -DVERSION='#version 120' commonShader.frag $@
GLSL-ashimanoise3D.frag: $(SRCDIR)/noise3D.glsl $(COMMON)
cpp -P -I$(SRCDIR) -DSHADER=\"noise3D.glsl\" \
-DVTYPE=vec3 -DVNAME=v_texCoord3D\
$(OPTIONS) -DVERSION='#version 120' commonShader.frag $@
GLSL-ashimanoise4D.frag: $(SRCDIR)/noise4D.glsl $(COMMON)
cpp -P -I$(SRCDIR) -DSHADER=\"noise4D.glsl\" \
-DVTYPE=vec4 -DVNAME=v_texCoord4D\
$(OPTIONS) -DVERSION='#version 120' commonShader.frag $@

View File

@ -0,0 +1,21 @@
VERSION
// uniform vec4 pParam;
// Example constant with a 289-element permutation
const vec4 pParam = vec4( 17.0*17.0, 34.0, 1.0, 7.0);
#include "noiseStdLib.glsl"
#include SHADER
uniform float time; // Used for texture animation
varying VTYPE VNAME ;
//
// main()
//
void main( void )
{
float n = simplexNoise(VNAME);
gl_FragColor = vec4(0.5 + 0.5 * vec3(n, n, n), 1.0);
}

439
benchmark/common/noisebench.c Executable file
View File

@ -0,0 +1,439 @@
/*
* Testbed for GLSL procedural noise functions.
*
* Shaders are loaded from two external files:
* "GLSL-ashimanoise.vert" and "GLSL-ashimanoise.frag".
* The program itself draws a spinning sphere
* with a noise-generated fragment color.
*
* This program uses GLFW for convenience, to handle the OS-specific
* window management stuff. Some Windows-specific stuff for extension
* loading is still here, but that code is short-circuited on other
* platforms - this file compiles unedited on Windows, Linux and MacOS X.
*
* Author: Stefan Gustavson (stegu@itn.liu.se) 2004, 2005, 2010, 2011
*/
// Identify the exact version of noise being benchmarked
#define NOISEVERSION "2011-03-21"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glfw.h>
#ifdef __WIN32__
// The system level include file for GL extensions might not be up to date.
#include "glext.h"
#else
#include <GL/glext.h>
#endif
#ifdef __APPLE__
// MacOS application bundles have the executable inside a directory structure
#define VERTEXSHADERFILE2D "../../../GLSL-ashimanoise.vert"
#define FRAGMENTSHADERFILE2D "../../../GLSL-ashimanoise2D.frag"
#define VERTEXSHADERFILE3D "../../../GLSL-ashimanoise.vert"
#define FRAGMENTSHADERFILE3D "../../../GLSL-ashimanoise3D.frag"
#define VERTEXSHADERFILE4D "../../../GLSL-ashimanoise.vert"
#define FRAGMENTSHADERFILE4D "../../../GLSL-ashimanoise4D.frag"
#define LOGFILENAME "../../../ashimanoise.log"
#else
// Windows, Linux and other Unix systems expose executables as naked files
#define VERTEXSHADERFILE2D "GLSL-ashimanoise.vert"
#define FRAGMENTSHADERFILE2D "GLSL-ashimanoise2D.frag"
#define VERTEXSHADERFILE3D "GLSL-ashimanoise.vert"
#define FRAGMENTSHADERFILE3D "GLSL-ashimanoise3D.frag"
#define VERTEXSHADERFILE4D "GLSL-ashimanoise.vert"
#define FRAGMENTSHADERFILE4D "GLSL-ashimanoise4D.frag"
#define LOGFILENAME "ashimanoise.log"
#endif
#ifdef __WIN32__
/* Global function pointers for everything we need beyond OpenGL 1.1 */
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
PFNGLCREATESHADERPROC glCreateShader = NULL;
PFNGLDELETESHADERPROC glDeleteShader = NULL;
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
PFNGLATTACHSHADERPROC glAttachShader = NULL;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
PFNGLUNIFORM1FVPROC glUniform1fv = NULL;
#endif
/*
* printError() - Signal an error.
* Simple printf() to console for portability.
*/
void printError(const char *errtype, const char *errmsg) {
fprintf(stderr, "%s: %s\n", errtype, errmsg);
}
/*
* Override the Win32 filelength() function with
* a version that takes a Unix-style file handle as
* input instead of a file ID number, and which works
* on platforms other than Windows.
*/
long filelength(FILE *file) {
long numbytes;
long savedpos = ftell(file);
fseek(file, 0, SEEK_END);
numbytes = ftell(file);
fseek(file, savedpos, SEEK_SET);
return numbytes;
}
/*
* loadExtensions() - Load OpenGL extensions for anything above OpenGL
* version 1.1. (This is a requirement only on Windows, so on other
* platforms, this function just checks for the required extensions.)
*/
void loadExtensions() {
//These extension strings indicate that the OpenGL Shading Language
// and GLSL shader objects are supported.
if(!glfwExtensionSupported("GL_ARB_shading_language_100"))
{
printError("GL init error", "GL_ARB_shading_language_100 extension was not found");
return;
}
if(!glfwExtensionSupported("GL_ARB_shader_objects"))
{
printError("GL init error", "GL_ARB_shader_objects extension was not found");
return;
}
else
{
#ifdef __WIN32__
glCreateProgram = (PFNGLCREATEPROGRAMPROC)glfwGetProcAddress("glCreateProgram");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glfwGetProcAddress("glDeleteProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)glfwGetProcAddress("glUseProgram");
glCreateShader = (PFNGLCREATESHADERPROC)glfwGetProcAddress("glCreateShader");
glDeleteShader = (PFNGLDELETESHADERPROC)glfwGetProcAddress("glDeleteShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)glfwGetProcAddress("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)glfwGetProcAddress("glCompileShader");
glGetShaderiv = (PFNGLGETSHADERIVPROC)glfwGetProcAddress("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glfwGetProcAddress("glGetShaderInfoLog");
glAttachShader = (PFNGLATTACHSHADERPROC)glfwGetProcAddress("glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)glfwGetProcAddress("glLinkProgram");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glfwGetProcAddress("glGetProgramiv");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glfwGetProcAddress("glGetProgramInfoLog");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glfwGetProcAddress("glGetUniformLocation");
glUniform1fv = (PFNGLUNIFORM1FVPROC)glfwGetProcAddress("glUniform1fv");
if( !glCreateProgram || !glDeleteProgram || !glUseProgram ||
!glCreateShader || !glDeleteShader || !glShaderSource || !glCompileShader ||
!glGetShaderiv || !glGetShaderInfoLog || !glAttachShader || !glLinkProgram ||
!glGetProgramiv || !glGetProgramInfoLog || !glGetUniformLocation ||
!glUniform1fv )
{
printError("GL init error", "One or more required OpenGL functions were not found");
return;
}
#endif
}
}
/*
* readShaderFile(filename) - read a shader source string from a file
*/
unsigned char* readShaderFile(const char *filename) {
FILE *file = fopen(filename, "r");
if(file == NULL)
{
printError("ERROR", "Cannot open shader file!");
return 0;
}
int bytesinfile = filelength(file);
unsigned char *buffer = (unsigned char*)malloc(bytesinfile+1);
int bytesread = fread( buffer, 1, bytesinfile, file);
buffer[bytesread] = 0; // Terminate the string with 0
fclose(file);
return buffer;
}
/*
* createShaders() - create, load, compile and link the GLSL shader objects.
*/
void createShader(GLuint *programObject, char *vertexshaderfile, char *fragmentshaderfile) {
GLuint vertexShader;
GLuint fragmentShader;
const char *vertexShaderStrings[1];
const char *fragmentShaderStrings[1];
GLint vertexCompiled;
GLint fragmentCompiled;
GLint shadersLinked;
char str[4096]; // For error messages from the GLSL compiler and linker
// Create the vertex shader.
vertexShader = glCreateShader(GL_VERTEX_SHADER);
unsigned char *vertexShaderAssembly = readShaderFile( vertexshaderfile );
vertexShaderStrings[0] = (char*)vertexShaderAssembly;
glShaderSource( vertexShader, 1, vertexShaderStrings, NULL );
glCompileShader( vertexShader);
free((void *)vertexShaderAssembly);
glGetShaderiv( vertexShader, GL_COMPILE_STATUS,
&vertexCompiled );
if(vertexCompiled == GL_FALSE)
{
glGetShaderInfoLog(vertexShader, sizeof(str), NULL, str);
printError("Vertex shader compile error", str);
}
// Create the fragment shader.
fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
unsigned char *fragmentShaderAssembly = readShaderFile( fragmentshaderfile );
fragmentShaderStrings[0] = (char*)fragmentShaderAssembly;
glShaderSource( fragmentShader, 1, fragmentShaderStrings, NULL );
glCompileShader( fragmentShader );
free((void *)fragmentShaderAssembly);
glGetProgramiv( fragmentShader, GL_COMPILE_STATUS,
&fragmentCompiled );
if(fragmentCompiled == GL_FALSE)
{
glGetShaderInfoLog( fragmentShader, sizeof(str), NULL, str );
printError("Fragment shader compile error", str);
}
// Create a program object and attach the two compiled shaders.
*programObject = glCreateProgram();
glAttachShader( *programObject, vertexShader );
glAttachShader( *programObject, fragmentShader );
// Link the program object and print out the info log.
glLinkProgram( *programObject );
glGetProgramiv( *programObject, GL_LINK_STATUS, &shadersLinked );
if( shadersLinked == GL_FALSE )
{
glGetProgramInfoLog( *programObject, sizeof(str), NULL, str );
printError("Program object linking error", str);
}
}
/*
* computeFPS() - Calculate, display and return samples per second.
* Stats are recomputed only once per second.
*/
double computeFPS() {
static double t0 = 0.0;
static int frames = 0;
static double Msamplespersecond = 0.0;
static char titlestring[200];
double t, fps;
int width, height;
// Get current time
t = glfwGetTime(); // Gets number of seconds since glfwInit()
// If one second has passed, or if this is the very first frame
if( (t-t0) > 1.0 || frames == 0 )
{
fps = (double)frames / (t-t0);
glfwGetWindowSize( &width, &height );
// This assumes that multisampling for FSAA is disabled.
Msamplespersecond = 1e-6*fps*width*height;
sprintf(titlestring, "GLSL simplex noise (%.1f M samples/s)", Msamplespersecond);
glfwSetWindowTitle(titlestring);
printf("Speed: %.1f M samples/s\n", Msamplespersecond);
t0 = t;
frames = 0;
}
frames ++;
return Msamplespersecond;
}
/*
* setupCamera() - set up the OpenGL projection and (model)view matrices
*/
void setupCamera() {
int width, height;
// Get window size. It may start out different from the requested
// size, and will change if the user resizes the window.
glfwGetWindowSize( &width, &height );
if(height<=0) height=1; // Safeguard against iconified/closed window
// Set viewport. This is the pixel rectangle we want to draw into.
glViewport( 0, 0, width, height ); // The entire window
// Select and setup the projection matrix.
glMatrixMode(GL_PROJECTION); // "We want to edit the projection matrix"
glLoadIdentity(); // Reset the matrix to identity
// 45 degrees FOV, same aspect ratio as viewport, depth range 1 to 100
glOrtho( -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f );
// Select and setup the modelview matrix.
glMatrixMode( GL_MODELVIEW ); // "We want to edit the modelview matrix"
glLoadIdentity(); // Reset the matrix to identity
}
/*
* initDisplayList(GLuint *listID, GLdouble scale) - create a display list
* to render the demo geometry more efficently than by glVertex() calls.
* (This is currently just as fast as a VBO, and I'm a bit lazy.)
*/
void initDisplayList(GLuint *listID)
{
*listID = glGenLists(1);
glNewList(*listID, GL_COMPILE);
glColor3f(1.0f, 1.0f, 1.0f); // White base color
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glEnd();
glEndList();
}
/*
* renderScene() - draw the scene with the shader active
*/
void renderScene( GLuint listID, GLuint programObject )
{
GLint location_time = -1;
float time = 0.0f;
// Use vertex and fragment shaders.
glUseProgram( programObject );
// Update the uniform time variable.
location_time = glGetUniformLocation( programObject, "time" );
// glUniform1f() is bugged in Linux Nvidia driver 260.19.06,
// so we use glUniform1fv() instead to work around the bug.
if ( location_time != -1 ) {
time = (float)glfwGetTime();
glUniform1fv( location_time, 1, &time );
}
// Render with the shaders active.
glCallList( listID );
// Deactivate the shaders.
glUseProgram(0);
}
/*
* main(argc, argv) - the standard C entry point for the program
*/
int main(int argc, char *argv[]) {
GLuint displayList;
GLuint programObject;
double performance = 0.0;
int ndims = 2; // Currently running version of noise: 2D, 3D or 4D
FILE *logfile;
GLboolean running = GL_TRUE; // Main loop exits when this is set to GL_FALSE
// Initialise GLFW
glfwInit();
// Open the OpenGL window
if( !glfwOpenWindow(1024, 1024, 8,8,8,8, 32,0, GLFW_WINDOW) )
{
glfwTerminate(); // glfwOpenWindow failed, quit the program.
return 1;
}
// Load the extensions for GLSL - note that this has to be done
// *after* the window has been opened, or we won't have a GL context
// to query for those extensions and connect to instances of them.
loadExtensions();
logfile = fopen(LOGFILENAME, "w");
fprintf(logfile, "GL vendor: %s\n", glGetString(GL_VENDOR));
fprintf(logfile, "GL renderer: %s\n", glGetString(GL_RENDERER));
fprintf(logfile, "GL version: %s\n", glGetString(GL_VERSION));
// Create the shader object from two external GLSL source files
createShader(&programObject, VERTEXSHADERFILE2D, FRAGMENTSHADERFILE2D);
fprintf(logfile, "\n2D simplex noise, version %s, ", NOISEVERSION);
// Disable Z buffering for this simple 2D shader benchmark
glDisable(GL_DEPTH_TEST); // Use the Z buffer
glfwSwapInterval(0); // Do not wait for screen refresh between frames
// Compile a display list for the demo geometry, to render it efficiently
initDisplayList(&displayList);
// Main loop
while(running)
{
// Calculate and update the frames per second (FPS) display
performance = computeFPS();
// Do not clear the buffers - this is a raw shader benchmark.
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set up the camera projection.
setupCamera();
// Draw the scene.
renderScene(displayList, programObject);
// Swap buffers, i.e. display the image and prepare for next frame.
glfwSwapBuffers();
// Switch between 2D, 3D and 4D versions of noise
if((glfwGetTime() > 5.0) && (ndims == 2)) {
fprintf(logfile, "%.1f Msamples/s\n", performance);
createShader(&programObject, VERTEXSHADERFILE3D, FRAGMENTSHADERFILE3D);
fprintf(logfile, "3D simplex noise, version %s, ", NOISEVERSION);
ndims = 3;
}
if((glfwGetTime() > 10.0) && (ndims == 3)) {
fprintf(logfile, "%.1f Msamples/s\n", performance);
createShader(&programObject, VERTEXSHADERFILE4D, FRAGMENTSHADERFILE4D);
fprintf(logfile, "4D simplex noise, version %s, ", NOISEVERSION);
ndims = 4;
}
if((glfwGetTime() > 15.0) && (ndims == 4)) {
fprintf(logfile, "%.1f Msamples/s\n", performance);
running = GL_FALSE;
}
// Exit prematurely if the ESC key is pressed or the window is closed.
if(glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) {
running = GL_FALSE;
}
}
// Close the OpenGL window and terminate GLFW.
glfwTerminate();
fclose(logfile);
return 0;
}

76
src/noise2D.glsl Normal file
View File

@ -0,0 +1,76 @@
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110223
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the Artistic License 2.0; See LICENCE file.
//
float simplexNoise(vec2 v)
{
const vec2 C = vec2(0.211324865405187134, // (3.0-sqrt(3.0))/6.;
0.366025403784438597); // 0.5*(sqrt(3.0)-1.);
const vec3 D = vec3( 0., 0.5, 2.0) * 3.14159265358979312;
// First corner
vec2 i = floor(v + dot(v, C.yy) );
vec2 x0 = v - i + dot(i, C.xx);
// Other corners
vec2 i1;
i1.x = float( (x0.x>x0.y) );
i1.y = 1. - i1.x;
// x0 = x0 - 0. + 0. * C.xx ;
// x1 = x0 - i1 + 1. * C.xx ;
// x2 = x0 - 1. + 2. * C.xx ;
vec4 xC = x0.xyxy + vec4( C.xx, -1. + 2.* C.xx);
xC.xy -= i1;
// Permutations
i = mod(i, pParam.x);
vec3 p = permute( permute(
i.y + vec3(0., i1.y, 1. ), pParam.xyz)
+ i.x + vec3(0., i1.x, 1. ), pParam.xyz);
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(xC.xy,xC.xy), dot(xC.zw,xC.zw)), 0.);
m = m*m ;
m = m*m ;
#ifndef USE_CIRCLE
// ( N points uniformly over a line, mapped onto a diamond.)
vec3 x = 2.0 * fract(p / pParam.w) - 1. ;
vec3 h = 0.5 - abs(x) ;
vec3 sx = 2.*floor(x) + 1.;
vec3 sh = floor(h);
vec3 a0 = x + sx*sh;
# ifdef NORMALISE_GRADIENTS
m *= taylorInvSqrt( a0*a0 + h*h );
# endif
//vec2 p0 = vec2(a0.x,h.x);
//vec2 p1 = vec2(a0.y,h.y);
//vec2 p2 = vec2(a0.z,h.z);
//vec3 g = vec3( dot(p0, x0), dot(p1, xC.xy), dot(p2, xC.zw) );
vec3 g;
// a0 *= m;
// h *= m;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * xC.xz + h.yz * xC.yw;
return 1.66666* 70. *2. * dot(m, g);
#else
// N points around a unit circle.
vec3 phi = D.z * mod(p,pParam.w) /pParam.w ;
vec4 a0 = sin(phi.xxyy+D.xyxy);
vec2 a1 = sin(phi.zz +D.xy);
// mix
vec3 g = vec3( dot(a0.xy, x0), dot(a0.zw, xC.xy), dot(a1.xy, xC.zw) );
return 1.66666* 70.*dot(m, g);
#endif
}

108
src/noise3D.glsl Normal file
View File

@ -0,0 +1,108 @@
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110223
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the Artistic License 2.0; See LICENCE file.
//
float simplexNoise(vec3 v)
{
const vec2 C = vec2(1./6. , 1./3. ) ;
const vec4 D = vec4(0., 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
// Other corners
#ifdef COLLAPSE_SORTNET
vec3 g = vec3( greaterThan( x0.xyz, x0.yzx) );
// vec3 l = vec3( lessThanEqual( x0.xyz, x0.yzx) );
vec3 l = 1. - g;
vec3 i1 = g.xyz * l.zxy;
vec3 i2 = max( g.xyz, l.zxy);
#else
// Keeping this clean - let the compiler optimize.
// Force existance of strict total ordering in sort.
vec3 q0 = floor(x0 * 1024.0) + vec3( 0., 1./4., 2./4.);
vec3 q1;
q1.x = max(q0.x, q0.y);
q1.y = min(q0.x, q0.y);
q1.z = q0.z;
vec3 q2;
q2.x = max(q1.x,q1.z);
q2.z = min(q1.x,q1.z);
q2.y = q1.y;
vec3 q3;
q3.y = max(q2.y, q2.z);
q3.z = min(q2.y, q2.z);
q3.x = q2.x;
vec3 i1 = vec3(lessThanEqual(q3.xxx, q0));
vec3 i2 = vec3(lessThanEqual(q3.yyy, q0));
#endif
// x0 = x0 - 0. + 0. * C
vec3 x1 = x0 - i1 + 1. * C.xxx;
vec3 x2 = x0 - i2 + 2. * C.xxx;
vec3 x3 = x0 - 1. + 3. * C.xxx;
// Permutations
i = mod(i, pParam.x );
vec4 p = permute( permute( permute(
i.z + vec4(0., i1.z, i2.z, 1. ), pParam.xyz)
+ i.y + vec4(0., i1.y, i2.y, 1. ), pParam.xyz)
+ i.x + vec4(0., i1.x, i2.x, 1. ), pParam.xyz);
// Gradients
// ( N*N points uniformly over a square, mapped onto a octohedron.)
float n_ = 1.0/pParam.w ;
vec3 ns = n_ * D.wyz - D.xzx ;
vec4 j = p - pParam.w*pParam.w*floor(p * ns.z *ns.z); // mod(p,N*N)
vec4 x_ = floor(j * ns.z) ;
vec4 y_ = floor(j - pParam.w * x_ ) ; // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1. - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,D.xxxx)) *2. -1.;
//vec4 s1 = vec4(lessThan(b1,D.xxxx)) *2. -1.;
vec4 s0 = floor(b0) *2. +1.;
vec4 s1 = floor(b1) *2. +1.;
vec4 sh = -vec4(lessThan(h, D.xxxx));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
#ifdef NORMALISE_GRADIENTS
p0 *= taylorInvSqrt(dot(p0,p0));
p1 *= taylorInvSqrt(dot(p1,p1));
p2 *= taylorInvSqrt(dot(p2,p2));
p3 *= taylorInvSqrt(dot(p3,p3));
#endif
// Mix
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.);
m = m * m;
//used to be 64.
return 48.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}

100
src/noise4D.glsl Normal file
View File

@ -0,0 +1,100 @@
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110223
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the Artistic License 2.0; See LICENCE file.
//
vec4 grad4(float j, vec4 ip)
{
const vec4 ones = vec4(1.0,1.0,1.0,-1.0);
vec4 p,s;
p.xyz = floor( fract (vec3(j) * ip.xyz) *pParam.w) * ip.z -1.0;
p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
s = vec4(lessThan(p, vec4(0.0)));
p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;
return p;
}
float simplexNoise(vec4 v)
{
const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4
0.309016994374947451); // (sqrt(5) - 1)/4 F4
// First corner
vec4 i = floor(v + dot(v, C.yyyy) );
vec4 x0 = v - i + dot(i, C.xxxx);
// Other corners
// Force existance of strict total ordering in sort.
vec4 q0 = floor(x0 * 1024.0) + vec4( 0.0, 1.0/4.0, 2.0/4.0 , 3.0/4.0);
vec4 q1;
q1.xy = max(q0.xy, q0.zw); // x:z y:w
q1.zw = min(q0.xy, q0.zw);
vec4 q2;
q2.xz = max(q1.xz, q1.yw); // x:y z:w
q2.yw = min(q1.xz, q1.yw);
vec4 q3;
q3.y = max(q2.y, q2.z); // y:z
q3.z = min(q2.y, q2.z);
q3.xw = q2.xw;
vec4 i1 = vec4(lessThanEqual(q3.xxxx, q0));
vec4 i2 = vec4(lessThanEqual(q3.yyyy, q0));
vec4 i3 = vec4(lessThanEqual(q3.zzzz, q0));
// x0 = x0 - 0.0 + 0.0 * C
vec4 x1 = x0 - i1 + 1.0 * C.xxxx;
vec4 x2 = x0 - i2 + 2.0 * C.xxxx;
vec4 x3 = x0 - i3 + 3.0 * C.xxxx;
vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx;
// Permutations
i = mod(i, pParam.x);
float j0 = permute( permute( permute( permute (
i.w, pParam.xyz) + i.z, pParam.xyz)
+ i.y, pParam.xyz) + i.x, pParam.xyz);
vec4 j1 = permute( permute( permute( permute (
i.w + vec4(i1.w, i2.w, i3.w, 1.0 ), pParam.xyz)
+ i.z + vec4(i1.z, i2.z, i3.z, 1.0 ), pParam.xyz)
+ i.y + vec4(i1.y, i2.y, i3.y, 1.0 ), pParam.xyz)
+ i.x + vec4(i1.x, i2.x, i3.x, 1.0 ), pParam.xyz);
// Gradients
// ( N*N*N points uniformly over a cube, mapped onto a 4-octohedron.)
vec4 ip = vec4(pParam.w) ;
ip.xy *= pParam.w ;
ip.x *= pParam.w ;
ip = vec4(1.0,1.0,1.0,2.0) / ip ;
vec4 p0 = grad4(j0, ip);
vec4 p1 = grad4(j1.x, ip);
vec4 p2 = grad4(j1.y, ip);
vec4 p3 = grad4(j1.z, ip);
vec4 p4 = grad4(j1.w, ip);
#ifdef NORMALISE_GRADIENTS
p0 *= taylorInvSqrt(dot(p0,p0));
p1 *= taylorInvSqrt(dot(p1,p1));
p2 *= taylorInvSqrt(dot(p2,p2));
p3 *= taylorInvSqrt(dot(p3,p3));
p4 *= taylorInvSqrt(dot(p4,p4));
#endif
// Mix contributions from the five corners
vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);
m0 = m0 * m0;
m1 = m1 * m1;
return 32. * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
+ dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
}

33
src/noiseStdLib.glsl Normal file
View File

@ -0,0 +1,33 @@
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions. Library function.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110223
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the Artistic License 2.0; See LICENCE file.
//
#ifdef FASTMOD
# define PERMMOD(X,Y) (X)
#else
# define PERMMOD(X,Y) mod((X),(Y))
#endif
#define PERMFUN(X) X permute(X x, vec3 p) { \
return floor( mod( (PERMMOD(x * p.y, p.x) + p.z)*x, p.x)); }
PERMFUN(float)
PERMFUN(vec2)
PERMFUN(vec3)
PERMFUN(vec4)
#define TAYLOR_L07(X) X taylorInvSqrt(X r) { \
return ( 0.83666002653408 + 0.7*0.85373472095314 - 0.85373472095314 * r ); }
TAYLOR_L07(float)
TAYLOR_L07(vec2)
TAYLOR_L07(vec3)
TAYLOR_L07(vec4)