Merge lp:~timfelgentreff/stratagus/shaders into lp:stratagus

Proposed by timfelgentreff on 2015-10-16
Status: Merged
Merged at revision: 9033
Proposed branch: lp:~timfelgentreff/stratagus/shaders
Merge into: lp:stratagus
Diff against target: 687 lines (+557/-4)
6 files modified
CMakeLists.txt (+10/-1)
src/include/shaders.h (+11/-0)
src/include/video.h (+1/-0)
src/stratagus/stratagus.cpp (+7/-1)
src/video/sdl.cpp (+26/-2)
src/video/shaders.cpp (+502/-0)
To merge this branch: bzr merge lp:~timfelgentreff/stratagus/shaders
Reviewer Review Type Date Requested Status
Stratagus 2015-10-16 Pending
Review via email: mp+274693@code.launchpad.net

Description of the change

Adds shaders that are used with OpenGL to scale the entire screen. For now, the 'ctrl+alt+/' (backslash) key is globally bound to cycle through available shaders so you can try it.

To post a comment you must log in.
lp:~timfelgentreff/stratagus/shaders updated on 2015-10-19
9032. By timfelgentreff on 2015-10-19

add scale2x (aka advmame2x) as scaling shader

9033. By timfelgentreff on 2015-10-19

add cmdline switches for shaders, add ctrl+alt+/ as hard cycle keybinding, remove debug prints

timfelgentreff (timfelgentreff) wrote :

Ok, I've made a few cleanups, there is now a global key-combo to cycle through shaders (ctrl+alt+/) and the shaders can also be selected from the cmdline. If anyone has time to test this, that would be great. Otherwise, I'll just merge this in a couple of days

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2015-04-12 09:55:12 +0000
+++ CMakeLists.txt 2015-10-19 16:16:43 +0000
@@ -348,6 +348,7 @@
348 src/video/movie.cpp348 src/video/movie.cpp
349 src/video/png.cpp349 src/video/png.cpp
350 src/video/sdl.cpp350 src/video/sdl.cpp
351 src/video/shaders.cpp
351 src/video/sprite.cpp352 src/video/sprite.cpp
352 src/video/video.cpp353 src/video/video.cpp
353)354)
@@ -554,6 +555,7 @@
554 src/include/script.h555 src/include/script.h
555 src/include/script_sound.h556 src/include/script_sound.h
556 src/include/settings.h557 src/include/settings.h
558 src/include/shaders.h
557 src/include/sound.h559 src/include/sound.h
558 src/include/sound_server.h560 src/include/sound_server.h
559 src/include/spells.h561 src/include/spells.h
@@ -932,7 +934,14 @@
932934
933if(ENABLE_MULTIBUILD)935if(ENABLE_MULTIBUILD)
934 if(WIN32 AND MSVC)936 if(WIN32 AND MSVC)
935 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")937 if(MSVC_VERSION GREATER 1800) # if > VC13
938 message("The project must be compiled with VS2013 or older. VS2015 has deprecated many functions that we still use.")
939 set(CMAKE_GENERATOR_TOOLSET "v120" CACHE STRING "Platform Toolset" FORCE)
940 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO /NODEFAULTLIB:MSVCRT")
941 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO /NODEFAULTLIB:MSVCRT")
942 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO /NODEFAULTLIB:MSVCRT")
943 endif()
944 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
936 message(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")945 message(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
937 endif()946 endif()
938endif()947endif()
939948
=== added file 'src/include/shaders.h'
--- src/include/shaders.h 1970-01-01 00:00:00 +0000
+++ src/include/shaders.h 2015-10-19 16:16:43 +0000
@@ -0,0 +1,11 @@
1#ifndef __SHADERS_H__
2#define __SHADERS_H__
3#ifdef USE_OPENGL
4#define MAX_SHADERS 5
5extern unsigned ShaderIndex;
6extern void LoadShaders();
7extern bool LoadShaderExtensions();
8extern void SetupFramebuffer();
9extern void RenderFramebufferToScreen();
10#endif
11#endif
012
=== modified file 'src/include/video.h'
--- src/include/video.h 2015-03-11 19:07:07 +0000
+++ src/include/video.h 2015-10-19 16:16:43 +0000
@@ -41,6 +41,7 @@
4141
42#ifdef USE_OPENGL42#ifdef USE_OPENGL
43#include "SDL_opengl.h"43#include "SDL_opengl.h"
44#include "shaders.h"
44#endif45#endif
4546
46#include "guichan.h"47#include "guichan.h"
4748
=== modified file 'src/stratagus/stratagus.cpp'
--- src/stratagus/stratagus.cpp 2015-04-12 09:54:50 +0000
+++ src/stratagus/stratagus.cpp 2015-10-19 16:16:43 +0000
@@ -477,6 +477,9 @@
477 "\t-v mode\t\tVideo mode resolution in format <xres>x<yres>\n"477 "\t-v mode\t\tVideo mode resolution in format <xres>x<yres>\n"
478 "\t-W\t\tWindowed video mode\n"478 "\t-W\t\tWindowed video mode\n"
479#if defined(USE_OPENGL) || defined(USE_GLES)479#if defined(USE_OPENGL) || defined(USE_GLES)
480 "\t-x\t\tControls fullscreen scaling if your graphics card supports shaders.\n"\
481 "\t \t\tPass 1 for nearest-neigubour, 2 for EPX/AdvMame, 3 for HQx, 4 for SAL, 5 for SuperEagle\n"\
482 "\t \t\tYou can also use Ctrl+Alt+/ to cycle between these scaling algorithms at runtime.\n"
480 "\t-Z\t\tUse OpenGL to scale the screen to the viewport (retro-style). Implies -O.\n"483 "\t-Z\t\tUse OpenGL to scale the screen to the viewport (retro-style). Implies -O.\n"
481#endif484#endif
482 "map is relative to StratagusLibPath=datapath, use ./map for relative to cwd\n",485 "map is relative to StratagusLibPath=datapath, use ./map for relative to cwd\n",
@@ -529,7 +532,7 @@
529void ParseCommandLine(int argc, char **argv, Parameters &parameters)532void ParseCommandLine(int argc, char **argv, Parameters &parameters)
530{533{
531 for (;;) {534 for (;;) {
532 switch (getopt(argc, argv, "ac:d:D:eE:FhiI:lN:oOP:ps:S:u:v:WZ?")) {535 switch (getopt(argc, argv, "ac:d:D:eE:FhiI:lN:oOP:ps:S:u:v:Wx:Z?")) {
533 case 'a':536 case 'a':
534 EnableAssert = true;537 EnableAssert = true;
535 continue;538 continue;
@@ -629,6 +632,9 @@
629 Video.FullScreen = 0;632 Video.FullScreen = 0;
630 continue;633 continue;
631#if defined(USE_OPENGL) || defined(USE_GLES)634#if defined(USE_OPENGL) || defined(USE_GLES)
635 case 'x':
636 ShaderIndex = atoi(optarg) % MAX_SHADERS;
637 continue;
632 case 'Z':638 case 'Z':
633 ForceUseOpenGL = 1;639 ForceUseOpenGL = 1;
634 UseOpenGL = 1;640 UseOpenGL = 1;
635641
=== modified file 'src/video/sdl.cpp'
--- src/video/sdl.cpp 2015-03-05 17:12:52 +0000
+++ src/video/sdl.cpp 2015-10-19 16:16:43 +0000
@@ -70,6 +70,7 @@
7070
71#ifdef USE_OPENGL71#ifdef USE_OPENGL
72#include "SDL_opengl.h"72#include "SDL_opengl.h"
73#include "shaders.h"
73#endif74#endif
7475
75#ifdef USE_BEOS76#ifdef USE_BEOS
@@ -122,6 +123,7 @@
122GLint GLMaxTextureSizeOverride; /// User-specified limit for ::GLMaxTextureSize123GLint GLMaxTextureSizeOverride; /// User-specified limit for ::GLMaxTextureSize
123bool GLTextureCompressionSupported; /// Is OpenGL texture compression supported124bool GLTextureCompressionSupported; /// Is OpenGL texture compression supported
124bool UseGLTextureCompression; /// Use OpenGL texture compression125bool UseGLTextureCompression; /// Use OpenGL texture compression
126bool GLShaderPipelineSupported;
125#endif127#endif
126128
127static std::map<int, std::string> Key2Str;129static std::map<int, std::string> Key2Str;
@@ -256,8 +258,11 @@
256 } else {258 } else {
257 GLTextureCompressionSupported = false;259 GLTextureCompressionSupported = false;
258 }260 }
261
262 GLShaderPipelineSupported = LoadShaderExtensions();
259#else263#else
260 GLTextureCompressionSupported = false;264 GLTextureCompressionSupported = false;
265 GLShaderPipelineSupported = false;
261#endif266#endif
262}267}
263268
@@ -281,7 +286,11 @@
281#endif286#endif
282287
283#ifdef USE_OPENGL288#ifdef USE_OPENGL
284 glOrtho(0, Video.Width, Video.Height, 0, -1, 1);289 if (!GLShaderPipelineSupported) {
290 glOrtho(0, Video.Width, Video.Height, 0, -1, 1);
291 } else {
292 glOrtho(0, Video.ViewportWidth, Video.ViewportHeight, 0, -1, 1);
293 }
285#endif294#endif
286295
287 glMatrixMode(GL_MODELVIEW);296 glMatrixMode(GL_MODELVIEW);
@@ -299,6 +308,10 @@
299308
300#ifdef USE_OPENGL309#ifdef USE_OPENGL
301 glClearDepth(1.0f);310 glClearDepth(1.0f);
311
312 if (GLShaderPipelineSupported) {
313 SetupFramebuffer();
314 }
302#endif315#endif
303316
304 glShadeModel(GL_FLAT);317 glShadeModel(GL_FLAT);
@@ -879,6 +892,13 @@
879 break;892 break;
880893
881 case SDL_KEYDOWN:894 case SDL_KEYDOWN:
895 if (GLShaderPipelineSupported
896 && event.key.keysym.sym == SDLK_SLASH
897 && event.key.keysym.mod & KMOD_ALT
898 && event.key.keysym.mod & KMOD_CTRL) {
899 LoadShaders();
900 break;
901 }
882 InputKeyButtonPress(callbacks, SDL_GetTicks(),902 InputKeyButtonPress(callbacks, SDL_GetTicks(),
883 event.key.keysym.sym, event.key.keysym.unicode);903 event.key.keysym.sym, event.key.keysym.unicode);
884 break;904 break;
@@ -999,7 +1019,11 @@
999 eglSwapBuffers(eglDisplay, eglSurface);1019 eglSwapBuffers(eglDisplay, eglSurface);
1000#endif1020#endif
1001#if defined(USE_OPENGL) || defined(USE_GLES_NATIVE)1021#if defined(USE_OPENGL) || defined(USE_GLES_NATIVE)
1002 SDL_GL_SwapBuffers();1022 if (GLShaderPipelineSupported) {
1023 RenderFramebufferToScreen();
1024 } else {
1025 SDL_GL_SwapBuffers();
1026 }
1003#endif1027#endif
1004 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);1028 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1005 } else1029 } else
10061030
=== added file 'src/video/shaders.cpp'
--- src/video/shaders.cpp 1970-01-01 00:00:00 +0000
+++ src/video/shaders.cpp 2015-10-19 16:16:43 +0000
@@ -0,0 +1,502 @@
1#include "stratagus.h"
2#include "video.h"
3#ifdef USE_OPENGL
4const char* vertex_shader = "#version 130\n\
5\n\
6uniform sampler2D u_texture;\n\
7\n\
8void main()\n\
9{\n\
10 gl_TexCoord[0] = gl_MultiTexCoord0;\n\
11 gl_Position = ftransform();\n\
12}";
13
14const char* fragment_shaders[MAX_SHADERS] = {
15 // Nearest-neighbour
16 "#version 130\n\
17 \n\
18 uniform sampler2D u_texture;\n\
19 uniform float u_width;\n\
20 uniform float u_height;\n\
21 uniform float u_widthrel;\n\
22 uniform float u_heightrel;\n\
23 void main()\n\
24 {\n\
25 vec4 myColor = texture2D(u_texture, gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel));\n\
26 gl_FragColor = myColor;\n\
27 }",
28 // Scale2x
29 "#version 110\n\
30 \n\
31 uniform sampler2D u_texture;\n\
32 uniform float u_width;\n\
33 uniform float u_height;\n\
34 uniform float u_widthrel;\n\
35 uniform float u_heightrel;\n\
36 \n\
37 void main() {\n\
38 // o = offset, the width of a pixel\n\
39 vec2 texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
40 vec2 textureDimensions = vec2(u_width, u_height);\n\
41 vec2 o = 1.0 / textureDimensions;\n\
42 // texel arrangement\n\
43 // A B C\n\
44 // D E F\n\
45 // G H I\n\
46 vec4 A = texture2D(u_texture, texCoord + vec2( -o.x, o.y));\n\
47 vec4 B = texture2D(u_texture, texCoord + vec2( 0, o.y));\n\
48 vec4 C = texture2D(u_texture, texCoord + vec2( o.x, o.y));\n\
49 vec4 D = texture2D(u_texture, texCoord + vec2( -o.x, 0));\n\
50 vec4 E = texture2D(u_texture, texCoord + vec2( 0, 0));\n\
51 vec4 F = texture2D(u_texture, texCoord + vec2( o.x, 0));\n\
52 vec4 G = texture2D(u_texture, texCoord + vec2( -o.x, -o.y));\n\
53 vec4 H = texture2D(u_texture, texCoord + vec2( 0, -o.y));\n\
54 vec4 I = texture2D(u_texture, texCoord + vec2( o.x, -o.y));\n\
55 vec2 p = texCoord * textureDimensions;\n\
56 // p = the position within a pixel [0...1]\n\
57 p = p - floor(p);\n\
58 if (p.x > .5) {\n\
59 if (p.y > .5) {\n\
60 // Top Right\n\
61 gl_FragColor = B == F && B != D && F != H ? F : E;\n\
62 } else {\n\
63 // Bottom Right\n\
64 gl_FragColor = H == F && D != H && B != F ? F : E;\n\
65 }\n\
66 } else {\n\
67 if (p.y > .5) {\n\
68 // Top Left\n\
69 gl_FragColor = D == B && B != F && D != H ? D : E;\n\
70 } else {\n\
71 // Bottom Left\n\
72 gl_FragColor = D == H && D != B && H != F ? D : E;\n\
73 }\n\
74 }\n\
75 }",
76 // HQX
77 "#version 130\n\
78 \n\
79 uniform sampler2D u_texture;\n\
80 uniform float u_width;\n\
81 uniform float u_height;\n\
82 uniform float u_widthrel;\n\
83 uniform float u_heightrel;\n\
84 \n\
85 const float mx = 0.325; // start smoothing wt.\n\
86 const float k = -0.250; // wt. decrease factor\n\
87 const float max_w = 0.25; // max filter weigth\n\
88 const float min_w =-0.05; // min filter weigth\n\
89 const float lum_add = 0.25; // effects smoothing \n\
90 \n\
91 void main()\n\
92 {\n\
93 vec2 v_texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
94 \n\
95 // hq2x\n\
96 float x = 0.5 * (1.0 / u_width);\n\
97 float y = 0.5 * (1.0 / u_height);\n\
98 vec2 dg1 = vec2( x, y);\n\
99 vec2 dg2 = vec2(-x, y);\n\
100 vec2 dx = vec2(x, 0.0);\n\
101 vec2 dy = vec2(0.0, y);\n\
102 \n\
103 vec4 TexCoord[5];\n\
104 TexCoord[0] = vec4(v_texCoord, 0.0, 0.0);\n\
105 TexCoord[1].xy = TexCoord[0].xy - dg1;\n\
106 TexCoord[1].zw = TexCoord[0].xy - dy;\n\
107 TexCoord[2].xy = TexCoord[0].xy - dg2;\n\
108 TexCoord[2].zw = TexCoord[0].xy + dx;\n\
109 TexCoord[3].xy = TexCoord[0].xy + dg1;\n\
110 TexCoord[3].zw = TexCoord[0].xy + dy;\n\
111 TexCoord[4].xy = TexCoord[0].xy + dg2;\n\
112 TexCoord[4].zw = TexCoord[0].xy - dx;\n\
113 \n\
114 vec3 c00 = texture2D(u_texture, TexCoord[1].xy).xyz; \n\
115 vec3 c10 = texture2D(u_texture, TexCoord[1].zw).xyz; \n\
116 vec3 c20 = texture2D(u_texture, TexCoord[2].xy).xyz; \n\
117 vec3 c01 = texture2D(u_texture, TexCoord[4].zw).xyz; \n\
118 vec3 c11 = texture2D(u_texture, TexCoord[0].xy).xyz; \n\
119 vec3 c21 = texture2D(u_texture, TexCoord[2].zw).xyz; \n\
120 vec3 c02 = texture2D(u_texture, TexCoord[4].xy).xyz; \n\
121 vec3 c12 = texture2D(u_texture, TexCoord[3].zw).xyz; \n\
122 vec3 c22 = texture2D(u_texture, TexCoord[3].xy).xyz; \n\
123 vec3 dt = vec3(1.0, 1.0, 1.0);\n\
124 \n\
125 float md1 = dot(abs(c00 - c22), dt);\n\
126 float md2 = dot(abs(c02 - c20), dt);\n\
127 \n\
128 float w1 = dot(abs(c22 - c11), dt) * md2;\n\
129 float w2 = dot(abs(c02 - c11), dt) * md1;\n\
130 float w3 = dot(abs(c00 - c11), dt) * md2;\n\
131 float w4 = dot(abs(c20 - c11), dt) * md1;\n\
132 \n\
133 float t1 = w1 + w3;\n\
134 float t2 = w2 + w4;\n\
135 float ww = max(t1, t2) + 0.0001;\n\
136 \n\
137 c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);\n\
138 \n\
139 float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);\n\
140 float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);\n\
141 \n\
142 w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);\n\
143 w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);\n\
144 w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);\n\
145 w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);\n\
146 \n\
147 gl_FragColor = vec4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1);\n\
148 }",
149 // 2xSAL
150 "#version 130\n\
151 \n\
152 uniform sampler2D u_texture;\n\
153 uniform float u_width;\n\
154 uniform float u_height;\n\
155 uniform float u_widthrel;\n\
156 uniform float u_heightrel;\n\
157 \n\
158 void main()\n\
159 {\n\
160 vec2 texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
161 vec2 UL, UR, DL, DR;\n\
162 float dx = pow(u_width, -1.0) * 0.25;\n\
163 float dy = pow(u_height, -1.0) * 0.25;\n\
164 vec3 dt = vec3(1.0, 1.0, 1.0);\n\
165 UL = texCoord + vec2(-dx, -dy);\n\
166 UR = texCoord + vec2(dx, -dy);\n\
167 DL = texCoord + vec2(-dx, dy);\n\
168 DR = texCoord + vec2(dx, dy);\n\
169 vec3 c00 = texture2D(u_texture, UL).xyz;\n\
170 vec3 c20 = texture2D(u_texture, UR).xyz;\n\
171 vec3 c02 = texture2D(u_texture, DL).xyz;\n\
172 vec3 c22 = texture2D(u_texture, DR).xyz;\n\
173 float m1=dot(abs(c00-c22),dt)+0.001;\n\
174 float m2=dot(abs(c02-c20),dt)+0.001;\n\
175 gl_FragColor = vec4((m1*(c02+c20)+m2*(c22+c00))/(2.0*(m1+m2)),1.0); \n\
176 }",
177 // SuperEagle
178 "#version 130\n\
179 \n\
180 uniform sampler2D u_texture;\n\
181 uniform float u_width;\n\
182 uniform float u_height;\n\
183 uniform float u_widthrel;\n\
184 uniform float u_heightrel;\n\
185 \n\
186 int GET_RESULT(float A, float B, float C, float D)\n\
187 {\n\
188 int x = 0; int y = 0; int r = 0;\n\
189 if (A == C) x+=1; else if (B == C) y+=1;\n\
190 if (A == D) x+=1; else if (B == D) y+=1;\n\
191 if (x <= 1) r+=1; \n\
192 if (y <= 1) r-=1;\n\
193 return r;\n\
194 } \n\
195 \n\
196 const vec3 dtt = vec3(65536.0,255.0,1.0);\n\
197 \n\
198 float reduce(vec3 color)\n\
199 { \n\
200 return dot(color, dtt);\n\
201 }\n\
202 \n\
203 void main()\n\
204 {\n\
205 // get texel size \n\
206 vec2 ps = vec2(0.999/u_width, 0.999/u_height);\n\
207 \n\
208 vec2 v_texCoord = gl_TexCoord[0].xy * vec2(u_widthrel, -u_heightrel);\n\
209 \n\
210 // calculating offsets, coordinates\n\
211 vec2 dx = vec2( ps.x, 0.0); \n\
212 vec2 dy = vec2( 0.0, ps.y);\n\
213 vec2 g1 = vec2( ps.x,ps.y);\n\
214 vec2 g2 = vec2(-ps.x,ps.y); \n\
215 \n\
216 vec2 pixcoord = v_texCoord/ps; //VAR.CT\n\
217 vec2 fp = fract(pixcoord);\n\
218 vec2 pC4 = v_texCoord-fp*ps;\n\
219 vec2 pC8 = pC4+g1; //VAR.CT\n\
220 \n\
221 // Reading the texels\n\
222 vec3 C0 = texture2D(u_texture,pC4-g1).xyz; \n\
223 vec3 C1 = texture2D(u_texture,pC4-dy).xyz;\n\
224 vec3 C2 = texture2D(u_texture,pC4-g2).xyz;\n\
225 vec3 D3 = texture2D(u_texture,pC4-g2+dx).xyz;\n\
226 vec3 C3 = texture2D(u_texture,pC4-dx).xyz;\n\
227 vec3 C4 = texture2D(u_texture,pC4 ).xyz;\n\
228 vec3 C5 = texture2D(u_texture,pC4+dx).xyz;\n\
229 vec3 D4 = texture2D(u_texture,pC8-g2).xyz;\n\
230 vec3 C6 = texture2D(u_texture,pC4+g2).xyz;\n\
231 vec3 C7 = texture2D(u_texture,pC4+dy).xyz;\n\
232 vec3 C8 = texture2D(u_texture,pC4+g1).xyz;\n\
233 vec3 D5 = texture2D(u_texture,pC8+dx).xyz;\n\
234 vec3 D0 = texture2D(u_texture,pC4+g2+dy).xyz;\n\
235 vec3 D1 = texture2D(u_texture,pC8+g2).xyz;\n\
236 vec3 D2 = texture2D(u_texture,pC8+dy).xyz;\n\
237 vec3 D6 = texture2D(u_texture,pC8+g1).xyz;\n\
238 \n\
239 vec3 p00,p10,p01,p11;\n\
240 \n\
241 // reducing vec3 to float \n\
242 float c0 = reduce(C0);float c1 = reduce(C1);\n\
243 float c2 = reduce(C2);float c3 = reduce(C3);\n\
244 float c4 = reduce(C4);float c5 = reduce(C5);\n\
245 float c6 = reduce(C6);float c7 = reduce(C7);\n\
246 float c8 = reduce(C8);float d0 = reduce(D0);\n\
247 float d1 = reduce(D1);float d2 = reduce(D2);\n\
248 float d3 = reduce(D3);float d4 = reduce(D4);\n\
249 float d5 = reduce(D5);float d6 = reduce(D6);\n\
250 \n\
251 /* SuperEagle code */\n\
252 /* Copied from the Dosbox source code */\n\
253 /* Copyright (C) 2002-2007 The DOSBox Team */\n\
254 /* License: GNU-GPL */\n\
255 /* Adapted by guest(r) on 16.4.2007 */ \n\
256 if (c4 != c8) {\n\
257 if (c7 == c5) {\n\
258 p01 = p10 = C7;\n\
259 if ((c6 == c7) || (c5 == c2)) {\n\
260 p00 = 0.25*(3.0*C7+C4);\n\
261 } else {\n\
262 p00 = 0.5*(C4+C5);\n\
263 }\n\
264 \n\
265 if ((c5 == d4) || (c7 == d1)) {\n\
266 p11 = 0.25*(3.0*C7+C8);\n\
267 } else {\n\
268 p11 = 0.5*(C7+C8);\n\
269 }\n\
270 } else {\n\
271 p11 = 0.125*(6.0*C8+C7+C5);\n\
272 p00 = 0.125*(6.0*C4+C7+C5);\n\
273 \n\
274 p10 = 0.125*(6.0*C7+C4+C8);\n\
275 p01 = 0.125*(6.0*C5+C4+C8);\n\
276 }\n\
277 } else {\n\
278 if (c7 != c5) {\n\
279 p11 = p00 = C4;\n\
280 \n\
281 if ((c1 == c4) || (c8 == d5)) {\n\
282 p01 = 0.25*(3.0*C4+C5);\n\
283 } else {\n\
284 p01 = 0.5*(C4+C5);\n\
285 }\n\
286 \n\
287 if ((c8 == d2) || (c3 == c4)) {\n\
288 p10 = 0.25*(3.0*C4+C7);\n\
289 } else {\n\
290 p10 = 0.5*(C7+C8);\n\
291 }\n\
292 } else {\n\
293 int r = 0;\n\
294 r += GET_RESULT(c5,c4,c6,d1);\n\
295 r += GET_RESULT(c5,c4,c3,c1);\n\
296 r += GET_RESULT(c5,c4,d2,d5);\n\
297 r += GET_RESULT(c5,c4,c2,d4);\n\
298 \n\
299 if (r > 0) {\n\
300 p01 = p10 = C7;\n\
301 p00 = p11 = 0.5*(C4+C5);\n\
302 } else if (r < 0) {\n\
303 p11 = p00 = C4;\n\
304 p01 = p10 = 0.5*(C4+C5);\n\
305 } else {\n\
306 p11 = p00 = C4;\n\
307 p01 = p10 = C7;\n\
308 }\n\
309 }\n\
310 }\n\
311 \n\
312 // Distributing the four products \n\
313 if (fp.x < 0.50)\n\
314 { if (fp.y < 0.50) p10 = p00;}\n\
315 else\n\
316 { if (fp.y < 0.50) p10 = p01; else p10 = p11;}\n\
317 \n\
318 gl_FragColor = vec4(p10, 1);\n\
319 }"
320};
321
322
323PFNGLCREATESHADERPROC glCreateShader;
324PFNGLSHADERSOURCEPROC glShaderSource;
325PFNGLCOMPILESHADERPROC glCompileShader;
326PFNGLCREATEPROGRAMPROC glCreateProgram;
327PFNGLATTACHSHADERPROC glAttachShader;
328PFNGLLINKPROGRAMPROC glLinkProgram;
329PFNGLUSEPROGRAMPROC glUseProgram;
330PFNGLISPROGRAMPROC glIsProgram;
331PFNGLDELETEPROGRAMPROC glDeleteProgram;
332PFNGLDELETESHADERPROC glDeleteShader;
333PFNGLGETSHADERIVPROC glGetShaderiv;
334PFNGLGETPROGRAMIVPROC glGetProgramiv;
335PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
336PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
337PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
338PFNGLACTIVETEXTUREPROC glActiveTexture;
339PFNGLUNIFORM1FPROC glUniform1f;
340PFNGLUNIFORM1IPROC glUniform1i;
341
342GLuint fullscreenShader;
343GLuint fullscreenFramebuffer = 0;
344GLuint fullscreenTexture;
345PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffers;
346PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebuffer;
347PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture;
348PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffers;
349PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbuffer;
350PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorage;
351PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbuffer;
352PFNGLDRAWBUFFERSPROC glDrawBuffers;
353PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatus;
354
355void printShaderInfoLog(GLuint obj, const char* prefix)
356{
357 int infologLength = 0;
358 int charsWritten = 0;
359 char *infoLog;
360
361 glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength);
362
363 if (infologLength > 0)
364 {
365 infoLog = (char *)malloc(infologLength);
366 glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
367 fprintf(stdout, "%s: %s\n", prefix, infoLog);
368 free(infoLog);
369 }
370}
371void printProgramInfoLog(GLuint obj, const char* prefix)
372{
373 int infologLength = 0;
374 int charsWritten = 0;
375 char *infoLog;
376
377 glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infologLength);
378
379 if (infologLength > 0)
380 {
381 infoLog = (char *)malloc(infologLength);
382 glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
383 fprintf(stdout, "%s: %s\n", prefix, infoLog);
384 free(infoLog);
385 }
386}
387
388extern unsigned ShaderIndex = 0;
389
390extern void LoadShaders() {
391 GLuint vs, fs;
392 fs = glCreateShader(GL_FRAGMENT_SHADER);
393 glShaderSource(fs, 1, (const char**)&(fragment_shaders[ShaderIndex]), NULL);
394 glCompileShader(fs);
395 //printShaderInfoLog(fs, "Fragment Shader");
396 ShaderIndex = (ShaderIndex + 1) % MAX_SHADERS;
397 vs = glCreateShader(GL_VERTEX_SHADER);
398 glShaderSource(vs, 1, (const char**)&vertex_shader, NULL);
399 glCompileShader(vs);
400 //printShaderInfoLog(vs, "Vertex Shader");
401 if (glIsProgram(fullscreenShader)) {
402 glDeleteProgram(fullscreenShader);
403 }
404 fullscreenShader = glCreateProgram();
405 glAttachShader(fullscreenShader, vs);
406 glAttachShader(fullscreenShader, fs);
407 glLinkProgram(fullscreenShader);
408 glDeleteShader(fs);
409 glDeleteShader(vs);
410 //printProgramInfoLog(fullscreenShader, "Shader Program");
411}
412
413extern bool LoadShaderExtensions() {
414 glCreateShader = (PFNGLCREATESHADERPROC)(uintptr_t)SDL_GL_GetProcAddress("glCreateShader");
415 glShaderSource = (PFNGLSHADERSOURCEPROC)(uintptr_t)SDL_GL_GetProcAddress("glShaderSource");
416 glCompileShader = (PFNGLCOMPILESHADERPROC)(uintptr_t)SDL_GL_GetProcAddress("glCompileShader");
417 glCreateProgram = (PFNGLCREATEPROGRAMPROC)(uintptr_t)SDL_GL_GetProcAddress("glCreateProgram");
418 glAttachShader = (PFNGLATTACHSHADERPROC)(uintptr_t)SDL_GL_GetProcAddress("glAttachShader");
419 glLinkProgram = (PFNGLLINKPROGRAMPROC)(uintptr_t)SDL_GL_GetProcAddress("glLinkProgram");
420 glUseProgram = (PFNGLUSEPROGRAMPROC)(uintptr_t)SDL_GL_GetProcAddress("glUseProgram");
421 glGetShaderiv = (PFNGLGETSHADERIVPROC)(uintptr_t)SDL_GL_GetProcAddress("glGetShaderiv");
422 glGetProgramiv = (PFNGLGETPROGRAMIVPROC)(uintptr_t)SDL_GL_GetProcAddress("glGetProgramiv");
423 glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)(uintptr_t)SDL_GL_GetProcAddress("glGetShaderInfoLog");
424 glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)(uintptr_t)SDL_GL_GetProcAddress("glGetProgramInfoLog");
425 glIsProgram = (PFNGLISPROGRAMPROC)(uintptr_t)SDL_GL_GetProcAddress("glIsProgram");
426 glDeleteProgram = (PFNGLDELETEPROGRAMPROC)(uintptr_t)SDL_GL_GetProcAddress("glDeleteProgram");
427 glDeleteShader = (PFNGLDELETESHADERPROC)(uintptr_t)SDL_GL_GetProcAddress("glDeleteShader");
428
429 glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)(uintptr_t)SDL_GL_GetProcAddress("glGetUniformLocation");
430 glActiveTexture = (PFNGLACTIVETEXTUREPROC)(uintptr_t)SDL_GL_GetProcAddress("glActiveTexture");
431 glUniform1f = (PFNGLUNIFORM1FPROC)(uintptr_t)SDL_GL_GetProcAddress("glUniform1f");
432 glUniform1i = (PFNGLUNIFORM1IPROC)(uintptr_t)SDL_GL_GetProcAddress("glUniform1i");
433
434 glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glGenFramebuffers");
435 glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glBindFramebuffer");
436 glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glFramebufferTexture2D");
437 glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glGenRenderbuffers");
438 glBindRenderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glBindRenderbuffer");
439 glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glRenderbufferStorage");
440 glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glFramebufferRenderbuffer");
441 glDrawBuffers = (PFNGLDRAWBUFFERSPROC)(uintptr_t)SDL_GL_GetProcAddress("glDrawBuffers");
442 glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(uintptr_t)SDL_GL_GetProcAddress("glCheckFramebufferStatus");
443
444 if (glCreateShader && glGenFramebuffers && glGetUniformLocation && glActiveTexture) {
445 LoadShaders();
446 return true;
447 } else {
448 return false;
449 }
450}
451
452extern void SetupFramebuffer() {
453 glGenTextures(1, &fullscreenTexture); // generate a texture to render to off-screen
454 glBindTexture(GL_TEXTURE_2D, fullscreenTexture); // bind it, so all texture functions go to it
455 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Video.ViewportWidth, Video.ViewportHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // give an empty image to opengl
456 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // make sure we use nearest filtering
457 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
458 glGenFramebuffers(1, &fullscreenFramebuffer); // generate a framebuffer to render to
459 glBindFramebuffer(GL_FRAMEBUFFER_EXT, fullscreenFramebuffer); // bind it
460 glFramebufferTexture(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fullscreenTexture, 0); // set our texture as the "screen" of the framebuffer
461 GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0_EXT };
462 glDrawBuffers(1, DrawBuffers);
463 if (glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
464 fprintf(stderr, "FATAL: Error Creating Framebuffer! Try running without OpenGL.");
465 exit(-1);
466 }
467 glBindFramebuffer(GL_FRAMEBUFFER_EXT, fullscreenFramebuffer);
468}
469
470extern void RenderFramebufferToScreen() {
471 // switch the rendering target back to the real display
472 glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
473 // setup our shader program
474 glUseProgram(fullscreenShader);
475 GLint textureloc = glGetUniformLocation(fullscreenShader, "u_texture");
476 GLint widthloc = glGetUniformLocation(fullscreenShader, "u_width");
477 GLint heightloc = glGetUniformLocation(fullscreenShader, "u_height");
478 GLint widthrelloc = glGetUniformLocation(fullscreenShader, "u_widthrel");
479 GLint heightrelloc = glGetUniformLocation(fullscreenShader, "u_heightrel");
480 glUniform1f(widthloc, Video.ViewportWidth);
481 glUniform1f(heightloc, Video.ViewportHeight);
482 glUniform1f(widthrelloc, (float)Video.Width / (float)Video.ViewportWidth);
483 glUniform1f(heightrelloc, (float)Video.Height / (float)Video.ViewportHeight);
484 glUniform1i(textureloc, 0);
485 glActiveTexture(GL_TEXTURE0);
486 // render the framebuffer texture to a fullscreen quad on the real display
487 glBindTexture(GL_TEXTURE_2D, fullscreenTexture);
488 glBegin(GL_QUADS);
489 glTexCoord2f(0, 0);
490 glVertex2i(0, 0);
491 glTexCoord2f(1, 0);
492 glVertex2i(Video.ViewportWidth, 0);
493 glTexCoord2f(1, 1);
494 glVertex2i(Video.ViewportWidth, Video.ViewportHeight);
495 glTexCoord2f(0, 1);
496 glVertex2i(0, Video.ViewportHeight);
497 glEnd();
498 SDL_GL_SwapBuffers();
499 glUseProgram(0); // Disable shaders again, and render to framebuffer again
500 glBindFramebuffer(GL_FRAMEBUFFER_EXT, fullscreenFramebuffer);
501}
502#endif
0\ No newline at end of file503\ No newline at end of file

Subscribers

People subscribed via source and target branches

to status/vote changes: