├── LICENSE
├── Makefile
├── build
└── vc
│ ├── SDL2GLSL.sln
│ ├── SDL2GLSL.vcxproj
│ └── SDL2GLSL.vcxproj.filters
├── ext
├── bin
│ ├── x64
│ │ └── README.txt
│ └── x86
│ │ └── README.txt
├── include
│ └── SDL2
│ │ └── README.txt
└── lib
│ ├── x64
│ └── README.txt
│ └── x86
│ └── README.txt
├── include
└── main.h
├── res
├── README_ryu.txt
├── crt.fragment
├── crt.uwol.fragment
├── image.png
└── std.vertex
└── src
└── main.cpp
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Augusto Ruiz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | INCDIR=include
2 | SRCDIR=src
3 | OBJDIR=obj
4 | BINDIR=bin
5 | LIBDIR=lib
6 | MKDIR=mkdir
7 |
8 | UNAME_S = $(shell uname -s)
9 |
10 | USE_SDL_FROM_BREW?=false
11 |
12 | CXX=g++
13 | ifeq (${UNAME_S},Darwin)
14 | ifneq (${USE_SDL_FROM_BREW},false)
15 | CXXFLAGS=-std=c++11 -F/Library/Frameworks -O3 -Werror -Wall -fsigned-char `sdl2-config --cflags` -mmacosx-version-min=10.7 -stdlib=libc++ -pedantic-errors
16 | LDFLAGS=-std=c++11 -O3 -Werror -Wall -fsigned-char -mmacosx-version-min=10.7 -stdlib=libc++ -F/Library/Frameworks
17 | LDLIBS=-L/usr/local/lib `sdl2-config --libs` -lSDL2_image -lm -framework OpenGL -framework CoreFoundation
18 | else
19 | CXXFLAGS=-std=c++11 -F/Library/Frameworks -I/Library/Frameworks/SDL2.framework/Headers -I/Library/Frameworks/SDL2_image.framework/Headers -O3 -Werror -Wall -fsigned-char -mmacosx-version-min=10.7 -stdlib=libc++ -pedantic-errors
20 | LDFLAGS=-std=c++11 -O3 -Werror -Wall -fsigned-char -mmacosx-version-min=10.7 -stdlib=libc++ -F/Library/Frameworks
21 | LDLIBS=-L/usr/local/lib -lm -framework OpenGL -framework SDL2 -framework SDL2_image -framework CoreFoundation
22 | endif
23 | else
24 | CXXFLAGS=-std=c++11 -D_GNU_SOURCE=1 -D_THREAD_SAFE -Werror -Wall -fsigned-char `sdl2-config --cflags`
25 | LDLIBS=-L/usr/local/lib `sdl2-config --libs` -lSDL2_image -lGL
26 | LDFLAGS=
27 | endif
28 |
29 | vpath %.h $(INCDIR)
30 | vpath %.cpp $(SRCDIR)
31 | vpath %.cc $(SRCDIR)
32 | vpath %.o $(OBJDIR)
33 |
34 | HEADERS = $(shell find $(INCDIR))
35 | INCLUDES = $(sort $(addprefix -I,$(dir $(HEADERS))))
36 | SRCS = $(shell find $(SRCDIR) -name *.cc) $(shell find $(SRCDIR) -name *.cpp)
37 | OBJS = $(patsubst $(SRCDIR)%,$(OBJDIR)%,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SRCS))))
38 | APPNAME = $(BINDIR)/testSdl2
39 |
40 | all: createFolders $(APPNAME)
41 |
42 | $(APPNAME): $(OBJS) resources
43 | $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) -v
44 |
45 | $(OBJDIR)/%.o: %.cc
46 | $(MKDIR) -p $(dir $@)
47 | $(CXX) $(CXXFLAGS) -o $@ -c $(INCLUDES) $<
48 |
49 | $(OBJDIR)/%.o: %.cpp
50 | $(MKDIR) -p $(dir $@)
51 | $(CXX) $(CXXFLAGS) -o $@ -c $(INCLUDES) $<
52 |
53 | createFolders:
54 | $(MKDIR) -p $(BINDIR)
55 |
56 | resources:
57 | cp res/* bin
58 |
59 | clean:
60 | $(RM) -rf $(OBJDIR)
61 |
62 | cleanall: clean
63 | $(RM) $(APPNAME)
64 |
--------------------------------------------------------------------------------
/build/vc/SDL2GLSL.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26403.7
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2GLSL", "SDL2GLSL.vcxproj", "{67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Debug|x64.ActiveCfg = Debug|x64
17 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Debug|x64.Build.0 = Debug|x64
18 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Debug|x86.ActiveCfg = Debug|Win32
19 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Debug|x86.Build.0 = Debug|Win32
20 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Release|x64.ActiveCfg = Release|x64
21 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Release|x64.Build.0 = Release|x64
22 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Release|x86.ActiveCfg = Release|Win32
23 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/build/vc/SDL2GLSL.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 15.0
23 | {67F2DA5F-F108-4BA7-B2AB-958EBE7B946A}
24 | Win32Proj
25 | 10.0.10586.0
26 |
27 |
28 |
29 | Application
30 | true
31 | v141
32 |
33 |
34 | Application
35 | false
36 | v141
37 |
38 |
39 | Application
40 | true
41 | v141
42 |
43 |
44 | Application
45 | false
46 | v141
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | true
68 |
69 |
70 | true
71 |
72 |
73 |
74 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
75 | $(ProjectDir)..\..\include;$(ProjectDir)..\..\ext\include;$(ProjectDir)..\..\ext\include\SDL2;$(ProjectDir)..\..\ext\include\SDL2_image;%(AdditionalIncludeDirectories)
76 | MultiThreadedDebugDLL
77 | Level3
78 | ProgramDatabase
79 | Disabled
80 |
81 |
82 | MachineX86
83 | true
84 | Windows
85 | $(ProjectDir)..\..\ext\lib\x86
86 | SDL2.lib;SDL2main.lib;SDL2_image.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
87 |
88 |
89 |
90 |
91 |
92 |
93 | copy $(ProjectDir)..\..\ext\bin\$(PlatformShortName)\* $(OutDir)
94 | copy $(ProjectDir)..\..\res\* $(OutDir)
95 |
96 |
97 | Copying external libraries...
98 |
99 |
100 |
101 |
102 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
103 | $(ProjectDir)..\..\include;$(ProjectDir)..\..\ext\include;$(ProjectDir)..\..\ext\include\SDL2;$(ProjectDir)..\..\ext\include\SDL2_image;%(AdditionalIncludeDirectories)
104 | MultiThreadedDLL
105 | Level3
106 | ProgramDatabase
107 |
108 |
109 | MachineX86
110 | true
111 | Windows
112 | true
113 | true
114 | $(ProjectDir)..\..\ext\lib\x86
115 | SDL2.lib;SDL2main.lib;SDL2_image.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
116 |
117 |
118 |
119 |
120 |
121 |
122 | copy $(ProjectDir)..\..\ext\bin\$(PlatformShortName)\* $(OutDir)
123 | copy $(ProjectDir)..\..\res\* $(OutDir)
124 |
125 |
126 | Copying external libraries...
127 |
128 |
129 |
130 |
131 | $(ProjectDir)..\..\include;$(ProjectDir)..\..\ext\include;$(ProjectDir)..\..\ext\include\SDL2;$(ProjectDir)..\..\ext\include\SDL2_image;%(AdditionalIncludeDirectories)
132 |
133 |
134 | $(ProjectDir)..\..\ext\lib\x64
135 | SDL2.lib;SDL2main.lib;SDL2_image.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
136 | Windows
137 |
138 |
139 |
140 |
141 |
142 |
143 | copy $(ProjectDir)..\..\ext\bin\$(PlatformShortName)\* $(OutDir)
144 | copy $(ProjectDir)..\..\res\* $(OutDir)
145 |
146 |
147 | Copying external libraries...
148 |
149 |
150 |
151 |
152 | $(ProjectDir)..\..\include;$(ProjectDir)..\..\ext\include;$(ProjectDir)..\..\ext\include\SDL2;$(ProjectDir)..\..\ext\include\SDL2_image;%(AdditionalIncludeDirectories)
153 |
154 |
155 | $(ProjectDir)..\..\ext\lib\x64
156 | SDL2.lib;SDL2main.lib;SDL2_image.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
157 | Windows
158 |
159 |
160 |
161 |
162 |
163 |
164 | copy $(ProjectDir)..\..\ext\bin\$(PlatformShortName)\* $(OutDir)
165 | copy $(ProjectDir)..\..\res\* $(OutDir)
166 |
167 |
168 | Copying external libraries...
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 | true
180 |
181 |
182 |
183 | true
184 |
185 |
186 |
187 |
188 | true
189 |
190 |
191 |
192 |
193 |
194 |
--------------------------------------------------------------------------------
/build/vc/SDL2GLSL.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
23 |
24 | Header Files
25 |
26 |
27 |
28 |
29 | Resource Files
30 |
31 |
32 | Resource Files
33 |
34 |
35 | Resource Files
36 |
37 |
38 |
39 |
40 | Resource Files
41 |
42 |
43 |
--------------------------------------------------------------------------------
/ext/bin/x64/README.txt:
--------------------------------------------------------------------------------
1 | Place here .dll files for 64-bit...
2 |
--------------------------------------------------------------------------------
/ext/bin/x86/README.txt:
--------------------------------------------------------------------------------
1 | Place here .dll files for 32-bit...
2 |
--------------------------------------------------------------------------------
/ext/include/SDL2/README.txt:
--------------------------------------------------------------------------------
1 | Place here SDL2 include files...
2 |
--------------------------------------------------------------------------------
/ext/lib/x64/README.txt:
--------------------------------------------------------------------------------
1 | Place here .lib files for 64-bit...
2 |
--------------------------------------------------------------------------------
/ext/lib/x86/README.txt:
--------------------------------------------------------------------------------
1 | Place here .lib files for 32-bit...
2 |
--------------------------------------------------------------------------------
/include/main.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #ifdef __APPLE__
9 | #include "CoreFoundation/CoreFoundation.h"
10 | #include
11 |
12 | #if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
13 | #include
14 | #else
15 | #include
16 | #endif //!ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
17 | #else
18 | #include
19 | #include
20 | #endif
21 |
--------------------------------------------------------------------------------
/res/README_ryu.txt:
--------------------------------------------------------------------------------
1 | Ryu image (c) dollarcube@gmail.com.
--------------------------------------------------------------------------------
/res/crt.fragment:
--------------------------------------------------------------------------------
1 | //
2 | // PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER
3 | //
4 | // by Timothy Lottes
5 | //
6 | // This is more along the style of a really good CGA arcade monitor.
7 | // With RGB inputs instead of NTSC.
8 | // The shadow mask example has the mask rotated 90 degrees for less chromatic aberration.
9 | //
10 | // Left it unoptimized to show the theory behind the algorithm.
11 | //
12 | // It is an example what I personally would want as a display option for pixel art games.
13 | // Please take and use, change, or whatever.
14 | //
15 |
16 | varying vec4 v_color;
17 | varying vec2 v_texCoord;
18 |
19 | uniform sampler2D tex0;
20 |
21 | // Hardness of scanline.
22 | // -8.0 = soft
23 | // -16.0 = medium
24 | float hardScan=-8.0;
25 |
26 | // Hardness of pixels in scanline.
27 | // -2.0 = soft
28 | // -4.0 = hard
29 | float hardPix=-2.0;
30 |
31 | // Display warp.
32 | // 0.0 = none
33 | // 1.0/8.0 = extreme
34 | vec2 warp=vec2(1.0/32.0,1.0/24.0);
35 |
36 | // Amount of shadow mask.
37 | float maskDark=1.0;
38 | float maskLight=1.5;
39 |
40 | vec2 res = vec2(640.0,480.0); // /3.0
41 |
42 | //------------------------------------------------------------------------
43 |
44 | // sRGB to Linear.
45 | // Assuing using sRGB typed textures this should not be needed.
46 | float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
47 | vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
48 |
49 | // Linear to sRGB.
50 | // Assuing using sRGB typed textures this should not be needed.
51 | float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
52 | vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
53 |
54 | // Nearest emulated sample given floating point position and texel offset.
55 | // Also zero's off screen.
56 | vec3 Fetch(vec2 pos,vec2 off){
57 | pos=floor(pos*res+off)/res;
58 | if(max(abs(pos.x-0.5),abs(pos.y-0.5))>0.5)return vec3(0.0,0.0,0.0);
59 | return ToLinear(texture2D(tex0,pos.xy,-16.0).rgb);}
60 |
61 | // Distance in emulated pixels to nearest texel.
62 | vec2 Dist(vec2 pos){pos=pos*res;return -((pos-floor(pos))-vec2(0.5));}
63 |
64 | // 1D Gaussian.
65 | float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
66 |
67 | // 3-tap Gaussian filter along horz line.
68 | vec3 Horz3(vec2 pos,float off){
69 | vec3 b=Fetch(pos,vec2(-1.0,off));
70 | vec3 c=Fetch(pos,vec2( 0.0,off));
71 | vec3 d=Fetch(pos,vec2( 1.0,off));
72 | float dst=Dist(pos).x;
73 | // Convert distance to weight.
74 | float scale=hardPix;
75 | float wb=Gaus(dst-1.0,scale);
76 | float wc=Gaus(dst+0.0,scale);
77 | float wd=Gaus(dst+1.0,scale);
78 | // Return filtered sample.
79 | return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
80 |
81 | // 5-tap Gaussian filter along horz line.
82 | vec3 Horz5(vec2 pos,float off){
83 | vec3 a=Fetch(pos,vec2(-2.0,off));
84 | vec3 b=Fetch(pos,vec2(-1.0,off));
85 | vec3 c=Fetch(pos,vec2( 0.0,off));
86 | vec3 d=Fetch(pos,vec2( 1.0,off));
87 | vec3 e=Fetch(pos,vec2( 2.0,off));
88 | float dst=Dist(pos).x;
89 | // Convert distance to weight.
90 | float scale=hardPix;
91 | float wa=Gaus(dst-2.0,scale);
92 | float wb=Gaus(dst-1.0,scale);
93 | float wc=Gaus(dst+0.0,scale);
94 | float wd=Gaus(dst+1.0,scale);
95 | float we=Gaus(dst+2.0,scale);
96 | // Return filtered sample.
97 | return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
98 |
99 | // Return scanline weight.
100 | float Scan(vec2 pos,float off){
101 | float dst=Dist(pos).y;
102 | return Gaus(dst+off,hardScan);}
103 |
104 | // Allow nearest three lines to effect pixel.
105 | vec3 Tri(vec2 pos){
106 | vec3 a=Horz3(pos,-1.0);
107 | vec3 b=Horz5(pos, 0.0);
108 | vec3 c=Horz3(pos, 1.0);
109 | float wa=Scan(pos,-1.0);
110 | float wb=Scan(pos, 0.0);
111 | float wc=Scan(pos, 1.0);
112 | return a*wa+b*wb+c*wc;}
113 |
114 | // Distortion of scanlines, and end of screen alpha.
115 | vec2 Warp(vec2 pos){
116 | pos=pos*2.0-1.0;
117 | pos*=vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
118 | return pos*0.5+0.5;}
119 |
120 | // Shadow mask.
121 | vec3 Mask(vec2 pos){
122 | pos.x+=pos.y*3.0;
123 | vec3 mask=vec3(maskDark,maskDark,maskDark);
124 | pos.x=fract(pos.x/6.0);
125 | if(pos.x<0.333)mask.r=maskLight;
126 | else if(pos.x<0.666)mask.g=maskLight;
127 | else mask.b=maskLight;
128 | return mask;}
129 |
130 | // Draw dividing bars.
131 | float Bar(float pos,float bar){pos-=bar;return pos*pos<4.0?0.0:1.0;}
132 |
133 | // Entry.
134 | void main(){
135 | // Unmodified.
136 | vec2 pos=Warp(v_texCoord);
137 | vec4 fragColor;
138 | fragColor.rgb=Tri(pos)*Mask(gl_FragCoord.xy);
139 | fragColor.rgb=ToSrgb(fragColor.rgb);
140 | gl_FragColor=v_color * vec4(fragColor.rgb, 1.0);
141 | }
142 |
143 |
--------------------------------------------------------------------------------
/res/crt.uwol.fragment:
--------------------------------------------------------------------------------
1 | varying vec4 v_color;
2 | varying vec2 v_texCoord;
3 |
4 | uniform sampler2D tex0;
5 |
6 | // Hardness of scanline.
7 | // -8.0 = soft
8 | // -16.0 = medium
9 | float hardScan=-8.0;
10 |
11 | // Hardness of pixels in scanline.
12 | // -2.0 = soft
13 | // -4.0 = hard
14 | float hardPix=-3.0;
15 |
16 | // Display warp.
17 | // 0.0 = none
18 | // 1.0/8.0 = extreme
19 | vec2 warp = vec2(1.0/32.0, 1.0/24.0);
20 |
21 | // Amount of shadow mask.
22 | float maskDark=0.5;
23 | float maskLight=1.5;
24 |
25 | vec2 iResolution = vec2(640.0,480.0);
26 |
27 | //------------------------------------------------------------------------
28 | // sRGB to Linear.
29 | // Assuing using sRGB typed textures this should not be needed.
30 | float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
31 | vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
32 |
33 | // Linear to sRGB.
34 | // Assuing using sRGB typed textures this should not be needed.
35 | float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
36 | vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
37 |
38 | // Nearest emulated sample given floating point position and texel offset.
39 | // Also zero's off screen.
40 | vec3 Fetch(vec2 pos,vec2 off){
41 | vec3 result;
42 | pos = (floor(pos*iResolution + off) + vec2(0.5,0.5))/iResolution;
43 | result = ToLinear(1.2 * texture2D(tex0 , pos.xy, -16.0).rgb);
44 | return result;
45 | }
46 |
47 | // Distance in emulated pixels to nearest texel.
48 | vec2 Dist(vec2 pos){pos=pos*iResolution;return -((pos-floor(pos))-vec2(0.5));}
49 | // 1D Gaussian.
50 | float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
51 |
52 | // 3-tap Gaussian filter along horz line.
53 | vec3 Horz3(vec2 pos,float off){
54 | vec3 b=Fetch(pos,vec2(-1.0,off));
55 | vec3 c=Fetch(pos,vec2( 0.0,off));
56 | vec3 d=Fetch(pos,vec2( 1.0,off));
57 | float dst=Dist(pos).x;
58 | // Convert distance to weight.
59 | float scale=hardPix;
60 | float wb=Gaus(dst-1.0,scale);
61 | float wc=Gaus(dst+0.0,scale);
62 | float wd=Gaus(dst+1.0,scale);
63 | // Return filtered sample.
64 | return (b*wb+c*wc+d*wd)/(wb+wc+wd);
65 | }
66 |
67 | // 5-tap Gaussian filter along horz line.
68 | vec3 Horz5(vec2 pos,float off){
69 | vec3 a=Fetch(pos,vec2(-2.0,off));
70 | vec3 b=Fetch(pos,vec2(-1.0,off));
71 | vec3 c=Fetch(pos,vec2( 0.0,off));
72 | vec3 d=Fetch(pos,vec2( 1.0,off));
73 | vec3 e=Fetch(pos,vec2( 2.0,off));
74 | float dst=Dist(pos).x;
75 | // Convert distance to weight.
76 | float scale=hardPix;
77 | float wa=Gaus(dst-2.0,scale);
78 | float wb=Gaus(dst-1.0,scale);
79 | float wc=Gaus(dst+0.0,scale);
80 | float wd=Gaus(dst+1.0,scale);
81 | float we=Gaus(dst+2.0,scale);
82 | // Return filtered sample.
83 | return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);
84 | }
85 |
86 | // Return scanline weight.
87 | float Scan(vec2 pos,float off){
88 | float dst=Dist(pos).y;
89 | return Gaus(dst+off,hardScan);
90 | }
91 |
92 | // Allow nearest three lines to effect pixel.
93 | vec3 Tri(vec2 pos){
94 | vec3 a=Horz3(pos,-1.0);
95 | vec3 b=Horz5(pos, 0.0);
96 | vec3 c=Horz3(pos, 1.0);
97 | float wa=Scan(pos,-1.0);
98 | float wb=Scan(pos, 0.0);
99 | float wc=Scan(pos, 1.0);
100 | return a*wa + b*wb + c*wc;
101 | }
102 |
103 | // Distortion of scanlines, and end of screen alpha.
104 | vec2 Warp(vec2 pos){
105 | pos = pos*2.0-1.0;
106 | pos *= vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
107 | return pos*0.5+0.5;
108 | }
109 |
110 | vec3 Mask(vec2 pos) {
111 | pos.x+=pos.y*3.0;
112 | vec3 mask=vec3(maskDark,maskDark,maskDark);
113 | pos.x=fract(pos.x/6.0);
114 | if(pos.x<0.333)mask.r=maskLight;
115 | else if(pos.x<0.666)mask.g=maskLight;
116 | else mask.b=maskLight;
117 | return mask;
118 | }
119 |
120 | void main()
121 | {
122 | vec2 pos = Warp(v_texCoord);
123 | vec4 result;
124 | result.rgb = Tri(pos) * Mask(gl_FragCoord.xy);
125 | gl_FragColor = v_color * vec4(ToSrgb(result.rgb), 1.0);
126 | }
127 |
--------------------------------------------------------------------------------
/res/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustoRuiz/sdl2glsl/94afb548170cd30fe8400b89f7cddb1ab6866040/res/image.png
--------------------------------------------------------------------------------
/res/std.vertex:
--------------------------------------------------------------------------------
1 | varying vec4 v_color;
2 | varying vec2 v_texCoord;
3 |
4 | void main()
5 | {
6 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
7 | v_color = gl_Color;
8 | v_texCoord = vec2(gl_MultiTexCoord0);
9 | }
10 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "main.h"
4 |
5 | const int WIN_WIDTH = 640;
6 | const int WIN_HEIGHT = 480;
7 |
8 | const int WORLD_WIDTH = 320;
9 | const int WORLD_HEIGHT = 240;
10 |
11 | struct sprite {
12 | float x;
13 | float y;
14 | float vx;
15 | float vy;
16 | };
17 |
18 | const int MAX_SPRITES = 20;
19 |
20 | #ifndef __APPLE__
21 |
22 | // I'm avoiding the use of GLEW or some extensions handler, but that
23 | // doesn't mean you should...
24 | PFNGLCREATESHADERPROC glCreateShader;
25 | PFNGLSHADERSOURCEPROC glShaderSource;
26 | PFNGLCOMPILESHADERPROC glCompileShader;
27 | PFNGLGETSHADERIVPROC glGetShaderiv;
28 | PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
29 | PFNGLDELETESHADERPROC glDeleteShader;
30 | PFNGLATTACHSHADERPROC glAttachShader;
31 | PFNGLCREATEPROGRAMPROC glCreateProgram;
32 | PFNGLLINKPROGRAMPROC glLinkProgram;
33 | PFNGLVALIDATEPROGRAMPROC glValidateProgram;
34 | PFNGLGETPROGRAMIVPROC glGetProgramiv;
35 | PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
36 | PFNGLUSEPROGRAMPROC glUseProgram;
37 |
38 | bool initGLExtensions() {
39 | glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader");
40 | glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource");
41 | glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
42 | glGetShaderiv = (PFNGLGETSHADERIVPROC)SDL_GL_GetProcAddress("glGetShaderiv");
43 | glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)SDL_GL_GetProcAddress("glGetShaderInfoLog");
44 | glDeleteShader = (PFNGLDELETESHADERPROC)SDL_GL_GetProcAddress("glDeleteShader");
45 | glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader");
46 | glCreateProgram = (PFNGLCREATEPROGRAMPROC)SDL_GL_GetProcAddress("glCreateProgram");
47 | glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram");
48 | glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)SDL_GL_GetProcAddress("glValidateProgram");
49 | glGetProgramiv = (PFNGLGETPROGRAMIVPROC)SDL_GL_GetProcAddress("glGetProgramiv");
50 | glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog");
51 | glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
52 |
53 | return glCreateShader && glShaderSource && glCompileShader && glGetShaderiv &&
54 | glGetShaderInfoLog && glDeleteShader && glAttachShader && glCreateProgram &&
55 | glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
56 | glUseProgram;
57 | }
58 |
59 | #endif
60 |
61 | GLuint compileShader(const char* source, GLuint shaderType) {
62 | std::cout << "Compilando shader:" << std::endl << source << std::endl;
63 | // Create ID for shader
64 | GLuint result = glCreateShader(shaderType);
65 | // Define shader text
66 | glShaderSource(result, 1, &source, NULL);
67 | // Compile shader
68 | glCompileShader(result);
69 |
70 | //Check vertex shader for errors
71 | GLint shaderCompiled = GL_FALSE;
72 | glGetShaderiv( result, GL_COMPILE_STATUS, &shaderCompiled );
73 | if( shaderCompiled != GL_TRUE ) {
74 | std::cout << "Error en la compilación: " << result << "!" << std::endl;
75 | GLint logLength;
76 | glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength);
77 | if (logLength > 0)
78 | {
79 | GLchar *log = (GLchar*)malloc(logLength);
80 | glGetShaderInfoLog(result, logLength, &logLength, log);
81 | std::cout << "Shader compile log:" << log << std::endl;
82 | free(log);
83 | }
84 | glDeleteShader(result);
85 | result = 0;
86 | } else {
87 | std::cout << "Shader compilado correctamente. Id = " << result << std::endl;
88 | }
89 | return result;
90 | }
91 |
92 | GLuint compileProgram(const char* vtxFile, const char* fragFile) {
93 | GLuint programId = 0;
94 | GLuint vtxShaderId, fragShaderId;
95 |
96 | programId = glCreateProgram();
97 |
98 | std::ifstream f(vtxFile);
99 | std::string source((std::istreambuf_iterator(f)),
100 | std::istreambuf_iterator());
101 | vtxShaderId = compileShader(source.c_str(), GL_VERTEX_SHADER);
102 |
103 | f=std::ifstream(fragFile);
104 | source=std::string((std::istreambuf_iterator(f)),
105 | std::istreambuf_iterator());
106 | fragShaderId = compileShader(source.c_str(), GL_FRAGMENT_SHADER);
107 |
108 | if(vtxShaderId && fragShaderId) {
109 | // Associate shader with program
110 | glAttachShader(programId, vtxShaderId);
111 | glAttachShader(programId, fragShaderId);
112 | glLinkProgram(programId);
113 | glValidateProgram(programId);
114 |
115 | // Check the status of the compile/link
116 | GLint logLen;
117 | glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
118 | if(logLen > 0) {
119 | char* log = (char*) malloc(logLen * sizeof(char));
120 | // Show any errors as appropriate
121 | glGetProgramInfoLog(programId, logLen, &logLen, log);
122 | std::cout << "Prog Info Log: " << std::endl << log << std::endl;
123 | free(log);
124 | }
125 | }
126 | if(vtxShaderId) {
127 | glDeleteShader(vtxShaderId);
128 | }
129 | if(fragShaderId) {
130 | glDeleteShader(fragShaderId);
131 | }
132 | return programId;
133 | }
134 |
135 | void presentBackBuffer(SDL_Renderer *renderer, SDL_Window* win, SDL_Texture* backBuffer, GLuint programId) {
136 | GLint oldProgramId;
137 | // Guarrada para obtener el textureid (en driverdata->texture)
138 | //Detach the texture
139 | SDL_SetRenderTarget(renderer, NULL);
140 | SDL_RenderClear(renderer);
141 |
142 | SDL_GL_BindTexture(backBuffer, NULL, NULL);
143 | if(programId != 0) {
144 | glGetIntegerv(GL_CURRENT_PROGRAM,&oldProgramId);
145 | glUseProgram(programId);
146 | }
147 |
148 | GLfloat minx, miny, maxx, maxy;
149 | GLfloat minu, maxu, minv, maxv;
150 |
151 | // Coordenadas de la ventana donde pintar.
152 | minx = 0.0f;
153 | miny = 0.0f;
154 | maxx = WIN_WIDTH;
155 | maxy = WIN_HEIGHT;
156 |
157 | minu = 0.0f;
158 | maxu = 1.0f;
159 | minv = 0.0f;
160 | maxv = 1.0f;
161 |
162 | glBegin(GL_TRIANGLE_STRIP);
163 | glTexCoord2f(minu, minv);
164 | glVertex2f(minx, miny);
165 | glTexCoord2f(maxu, minv);
166 | glVertex2f(maxx, miny);
167 | glTexCoord2f(minu, maxv);
168 | glVertex2f(minx, maxy);
169 | glTexCoord2f(maxu, maxv);
170 | glVertex2f(maxx, maxy);
171 | glEnd();
172 | SDL_GL_SwapWindow(win);
173 |
174 | if(programId != 0) {
175 | glUseProgram(oldProgramId);
176 | }
177 | }
178 |
179 | #ifdef __APPLE__
180 | void initializeFileSystem() {
181 | CFBundleRef mainBundle = CFBundleGetMainBundle();
182 | CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
183 | char path[PATH_MAX];
184 | if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
185 | {
186 | std::cerr << "Couldn't get file system representation! " << std::endl;
187 | }
188 | CFRelease(resourcesURL);
189 | chdir(path);
190 | }
191 | #endif
192 |
193 | int main(int argc, char **argv){
194 | GLuint programId;
195 |
196 | #ifdef __APPLE__
197 | initializeFileSystem();
198 | #endif
199 |
200 | if (SDL_Init(SDL_INIT_EVERYTHING | SDL_VIDEO_OPENGL) != 0){
201 | std::cerr << "SDL_Init failed: " << SDL_GetError() << "\n";
202 | return 1;
203 | }
204 |
205 | SDL_Window *win = SDL_CreateWindow("Custom shader with SDL2 renderer!", SDL_WINDOWPOS_CENTERED,
206 | SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, 0);
207 |
208 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
209 |
210 | SDL_Renderer *renderer = SDL_CreateRenderer(win, -1,
211 | SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
212 |
213 | SDL_RendererInfo rendererInfo;
214 | SDL_GetRendererInfo(renderer, &rendererInfo);
215 |
216 | if(!strncmp(rendererInfo.name, "opengl", 6)) {
217 | std::cout << "Es OpenGL!" << std::endl;
218 | #ifndef __APPLE__
219 | // If you want to use GLEW or some other GL extension handler, do it here!
220 | if (!initGLExtensions()) {
221 | std::cout << "Couldn't init GL extensions!" << std::endl;
222 | SDL_Quit();
223 | exit(-1);
224 | }
225 | #endif
226 | // Compilar el shader y dejarlo listo para usar.
227 | programId = compileProgram("std.vertex", "crt.fragment");
228 | std::cout << "programId = " << programId << std::endl;
229 | }
230 |
231 | //Put your own bmp image here
232 | SDL_Surface *bmpSurf = IMG_Load("image.png");
233 | SDL_Texture *bmpTex = SDL_CreateTextureFromSurface(renderer, bmpSurf);
234 | SDL_FreeSurface(bmpSurf);
235 |
236 | //Make a target texture to render too
237 | SDL_Texture *texTarget = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
238 | SDL_TEXTUREACCESS_TARGET, WORLD_WIDTH, WORLD_HEIGHT);
239 |
240 | int done = 0;
241 | int useShader = 0;
242 | SDL_Rect targetRect;
243 |
244 | targetRect.x = 0; targetRect.y=0; targetRect.w=32; targetRect.h=32;
245 |
246 | struct sprite sprites[MAX_SPRITES];
247 |
248 | for(int i=0;i < MAX_SPRITES;++i) {
249 | sprites[i].x = (float) (rand() % (WORLD_WIDTH - targetRect.w));
250 | sprites[i].y = (float) (rand() % (WORLD_HEIGHT - targetRect.h));
251 | sprites[i].vx = (float) (rand() % 5 / 10.0f) - 0.2f;
252 | sprites[i].vy = (float) (rand() % 5 / 10.0f) - 0.2f;
253 | }
254 |
255 | // Voy a poner el fondo blanco para que se vea el shader
256 | SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
257 |
258 | while ( ! done ) {
259 | //Render to the texture
260 | SDL_SetRenderTarget(renderer, texTarget);
261 | SDL_RenderClear(renderer);
262 |
263 | // Pintamos MAX_SPRITES UWOLes
264 | struct sprite* spr;
265 | for(int i=0;i < MAX_SPRITES;++i) {
266 | spr = &(sprites[i]);
267 | spr->x += spr->vx;
268 | if(spr->x < 0) {
269 | spr->x = 0;
270 | spr->vx *= -1;
271 | }
272 | if(spr->x > WORLD_WIDTH - targetRect.w) {
273 | spr->x = (float) (WORLD_WIDTH - targetRect.w);
274 | spr->vx *= -1;
275 | }
276 | spr->y += spr->vy;
277 | if(spr->y < 0) {
278 | spr->y = 0;
279 | spr->vy *= -1;
280 | }
281 | if(spr->y > WORLD_HEIGHT - targetRect.h) {
282 | spr->y = (float) (WORLD_HEIGHT - targetRect.h);
283 | spr->vy *= -1;
284 | }
285 |
286 | targetRect.x = (int)spr->x;
287 | targetRect.y = (int)spr->y;
288 |
289 | SDL_RenderCopy(renderer, bmpTex, NULL, &targetRect);
290 | }
291 |
292 | presentBackBuffer(renderer, win, texTarget, programId);
293 |
294 | /* This could go in a separate function */
295 | SDL_Event event;
296 | while ( SDL_PollEvent(&event) ) {
297 | if ( event.type == SDL_QUIT ) {
298 | done = 1;
299 | }
300 | if ( event.type == SDL_KEYDOWN ) {
301 | if ( event.key.keysym.sym == SDLK_SPACE ) {
302 | useShader ^= 1;
303 | std::cout << "useShader = " << (useShader ? "true" : "false") << std::endl;
304 | }
305 | if ( event.key.keysym.sym == SDLK_ESCAPE ) {
306 | done = 1;
307 | }
308 | }
309 | }
310 | }
311 |
312 | SDL_DestroyTexture(texTarget);
313 | SDL_DestroyTexture(bmpTex);
314 | SDL_DestroyRenderer(renderer);
315 | SDL_DestroyWindow(win);
316 | SDL_Quit();
317 | return 0;
318 | }
319 |
--------------------------------------------------------------------------------