Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.63 KB | None | 0 0
  1. Index: include/render.h
  2. ===================================================================
  3. --- include/render.h (revision 4309)
  4. +++ include/render.h (working copy)
  5. @@ -80,11 +80,18 @@
  6. Bit8u *cacheRead;
  7. Bitu inHeight, inLine, outLine;
  8. } scale;
  9. +#if C_OPENGL
  10. + struct {
  11. + char* vertex_src;
  12. + char* fragment_src;
  13. + } gl;
  14. +#endif
  15. RenderPal_t pal;
  16. bool updating;
  17. bool active;
  18. bool aspect;
  19. bool fullFrame;
  20. + bool forceUpdate;
  21. } Render_t;
  22.  
  23. extern Render_t render;
  24. @@ -93,6 +100,8 @@
  25. bool RENDER_StartUpdate(void);
  26. void RENDER_EndUpdate(bool abort);
  27. void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
  28. +bool RENDER_GetForceUpdate(void);
  29. +void RENDER_SetForceUpdate(bool);
  30.  
  31.  
  32. #endif
  33. Index: include/video.h
  34. ===================================================================
  35. --- include/video.h (revision 4309)
  36. +++ include/video.h (working copy)
  37. @@ -59,6 +59,7 @@
  38. Bitu GFX_GetBestMode(Bitu flags);
  39. Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
  40. Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t cb);
  41. +void GFX_SetShaders(const char* vertex, const char* fragment);
  42.  
  43. void GFX_ResetScreen(void);
  44. void GFX_Start(void);
  45. Index: src/dosbox.cpp
  46. ===================================================================
  47. --- src/dosbox.cpp (revision 4309)
  48. +++ src/dosbox.cpp (working copy)
  49. @@ -473,6 +473,14 @@
  50. Pstring = Pmulti->GetSection()->Add_string("force",Property::Changeable::Always,"");
  51. Pstring->Set_values(force);
  52.  
  53. + Pstring = secprop->Add_string("glshader",Property::Changeable::Always,"none");
  54. + Pstring->Set_help("What set of GLSL shaders to use with an OpenGL output.\n"
  55. + "Note that in case it is used, the respective shader files must be found in the\n"
  56. + "\"glshaders\" subdirectory relative to where the default DOSBox configuration\n"
  57. + "file is stored. For shader file naming convention, suppose that you have a pair\n"
  58. + "of shader files ready: mysample.glslv and mysample.glslf.\n"
  59. + "Then glshader=mysample should be set.");
  60. +
  61. secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done
  62. const char* cores[] = { "auto",
  63. #if (C_DYNAMIC_X86) || (C_DYNREC)
  64. Index: src/gui/render.cpp
  65. ===================================================================
  66. --- src/gui/render.cpp (revision 4309)
  67. +++ src/gui/render.cpp (working copy)
  68. @@ -20,6 +20,9 @@
  69. #include <sys/types.h>
  70. #include <assert.h>
  71. #include <math.h>
  72. +#include <stdlib.h>
  73. +#include <fstream>
  74. +#include <sstream>
  75.  
  76. #include "dosbox.h"
  77. #include "video.h"
  78. @@ -229,6 +232,7 @@
  79. total += render.frameskip.hadSkip[i];
  80. LOG_MSG( "Skipped frame %d %d", PIC_Ticks, (total * 100) / RENDER_SKIP_CACHE );
  81. #endif
  82. + if (RENDER_GetForceUpdate()) GFX_EndUpdate(0);
  83. }
  84. render.frameskip.index = (render.frameskip.index + 1) & (RENDER_SKIP_CACHE - 1);
  85. render.updating=false;
  86. @@ -419,6 +423,9 @@
  87. }
  88. }
  89. /* Setup the scaler variables */
  90. +#if C_OPENGL
  91. + GFX_SetShaders(render.gl.vertex_src, render.gl.fragment_src);
  92. +#endif
  93. gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_CallBack);
  94. if (gfx_flags & GFX_CAN_8)
  95. render.scale.outMode = scalerMode8;
  96. @@ -563,6 +570,58 @@
  97. RENDER_CallBack( GFX_CallBackReset );
  98. } */
  99.  
  100. +bool RENDER_GetForceUpdate(void) {
  101. + return render.forceUpdate;
  102. +}
  103. +
  104. +void RENDER_SetForceUpdate(bool f) {
  105. + render.forceUpdate = f;
  106. +}
  107. +
  108. +#if C_OPENGL
  109. +static void RENDER_GetShaders(std::string &glshader) {
  110. + std::string shader_path;
  111. + Cross::GetPlatformConfigDir(shader_path);
  112. + shader_path = shader_path + "glshaders" + CROSS_FILESPLIT + glshader + ".glsl";
  113. + char* src;
  114. + std::ifstream vshader((shader_path + "v").c_str(), std::ios_base::binary);
  115. + if (vshader) {
  116. + std::stringstream buf;
  117. + buf << vshader.rdbuf();
  118. + vshader.close();
  119. + // keep the same buffer if contents aren't different
  120. + if (render.gl.vertex_src==NULL || buf.str() != render.gl.vertex_src) {
  121. + src = strdup(buf.str().c_str());
  122. + if (src==NULL) LOG_MSG("WARNING: Couldn't copy vertex shader source");
  123. + } else {
  124. + src = render.gl.vertex_src;
  125. + render.gl.vertex_src = NULL;
  126. + }
  127. + } else src = NULL;
  128. + free(render.gl.vertex_src);
  129. + render.gl.vertex_src = src;
  130. +
  131. + std::ifstream fshader((shader_path + "f").c_str(), std::ios_base::binary);
  132. + if (fshader) {
  133. + std::stringstream buf;
  134. + buf << fshader.rdbuf();
  135. + fshader.close();
  136. + if (render.gl.fragment_src==NULL || buf.str() != render.gl.fragment_src) {
  137. + src = strdup(buf.str().c_str());
  138. + if (src==NULL) LOG_MSG("WARNING: Couldn't copy fragment shader source");
  139. + } else {
  140. + src = render.gl.fragment_src;
  141. + render.gl.fragment_src = NULL;
  142. + }
  143. + } else src = NULL;
  144. + free(render.gl.fragment_src);
  145. + render.gl.fragment_src = src;
  146. +
  147. + if (render.gl.vertex_src==NULL && render.gl.fragment_src==NULL)
  148. + LOG_MSG("Unable to find any shaders matching %s", glshader.c_str());
  149. +}
  150. +#endif
  151. +
  152. void RENDER_Init(Section * sec) {
  153. Section_prop * section=static_cast<Section_prop *>(sec);
  154.  
  155. @@ -616,10 +675,25 @@
  156. else if (scaler == "scan3x"){ render.scale.op = scalerOpScan;render.scale.size = 3; }
  157. #endif
  158.  
  159. +#if C_OPENGL
  160. + char* vertex_src = render.gl.vertex_src;
  161. + char* fragment_src = render.gl.fragment_src;
  162. + f = section->Get_string("glshader");
  163. + if (f.empty() || f=="none") {
  164. + free(render.gl.vertex_src);
  165. + render.gl.vertex_src = NULL;
  166. + free(render.gl.fragment_src);
  167. + render.gl.fragment_src = NULL;
  168. + } else RENDER_GetShaders(f);
  169. +#endif
  170. +
  171. //If something changed that needs a ReInit
  172. // Only ReInit when there is a src.bpp (fixes crashes on startup and directly changing the scaler without a screen specified yet)
  173. if(running && render.src.bpp && ((render.aspect != aspect) || (render.scale.op != scaleOp) ||
  174. (render.scale.size != scalersize) || (render.scale.forced != scalerforced) ||
  175. +#if C_OPENGL
  176. + (render.gl.vertex_src != vertex_src) || (render.gl.fragment_src != fragment_src) ||
  177. +#endif
  178. render.scale.forced))
  179. RENDER_CallBack( GFX_CallBackReset );
  180.  
  181. Index: src/gui/sdlmain.cpp
  182. ===================================================================
  183. --- src/gui/sdlmain.cpp (revision 4309)
  184. +++ src/gui/sdlmain.cpp (working copy)
  185. @@ -49,6 +49,7 @@
  186. #include "cpu.h"
  187. #include "cross.h"
  188. #include "control.h"
  189. +#include "render.h"
  190.  
  191. #define MAPPERFILE "mapper-" VERSION ".map"
  192. //#define DISABLE_JOYSTICK
  193. @@ -92,6 +93,53 @@
  194. PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
  195. PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
  196.  
  197. +#ifndef GL_VERSION_2_0
  198. +#define GL_VERSION_2_0 1
  199. +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
  200. +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
  201. +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
  202. +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
  203. +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
  204. +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
  205. +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
  206. +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
  207. +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
  208. +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
  209. +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
  210. +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
  211. +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
  212. +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
  213. +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
  214. +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
  215. +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
  216. +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
  217. +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
  218. +#endif
  219. +
  220. +PFNGLATTACHSHADERPROC glAttachShader = NULL;
  221. +PFNGLCOMPILESHADERPROC glCompileShader = NULL;
  222. +PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
  223. +PFNGLCREATESHADERPROC glCreateShader = NULL;
  224. +PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
  225. +PFNGLDELETESHADERPROC glDeleteShader = NULL;
  226. +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
  227. +PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
  228. +PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
  229. +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
  230. +PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
  231. +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
  232. +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
  233. +PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
  234. +PFNGLSHADERSOURCEPROC glShaderSource = NULL;
  235. +PFNGLUNIFORM2FPROC glUniform2f = NULL;
  236. +PFNGLUNIFORM1IPROC glUniform1i = NULL;
  237. +PFNGLUSEPROGRAMPROC glUseProgram = NULL;
  238. +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
  239. +
  240. +#ifndef GL_SHADER_COMPILER
  241. +#define GL_SHADER_COMPILER 0x8DFA
  242. +#endif
  243. +
  244. #endif //C_OPENGL
  245.  
  246. #if !(ENVIRON_INCLUDED)
  247. @@ -190,6 +238,19 @@
  248. bool packed_pixel;
  249. bool paletted_texture;
  250. bool pixel_buffer_object;
  251. +
  252. + bool use_shader;
  253. + GLuint program_object;
  254. + const char *vertex_src;
  255. + const char *fragment_src;
  256. + struct {
  257. + GLint texture_size;
  258. + GLint input_size;
  259. + GLint output_size;
  260. + GLint frame_count;
  261. + } ruby;
  262. + GLint actual_frame_count;
  263. + GLfloat vertex_data[2*3];
  264. } opengl;
  265. #endif
  266. struct {
  267. @@ -229,6 +290,26 @@
  268. static SDL_Block sdl;
  269.  
  270. #if C_OPENGL
  271. +static char const vertex_shader_default[] =
  272. + "attribute vec4 a_position;\n"
  273. + "varying vec2 v_texCoord;\n"
  274. + "uniform vec2 rubyTextureSize;\n"
  275. + "uniform vec2 rubyInputSize;\n"
  276. + "uniform vec2 rubyOutputSize;\n\n"
  277. + "void main() {\n"
  278. + " gl_Position = a_position;\n"
  279. + " v_texCoord = vec2(a_position.x+1.0,1.0-a_position.y)/2.0*rubyInputSize/rubyTextureSize;\n"
  280. + "}\n";
  281. +static char const fragment_shader_default[] =
  282. + "#ifdef GL_ES\n"
  283. + "precision mediump float;\n"
  284. + "#endif\n"
  285. + "varying vec2 v_texCoord;\n"
  286. + "uniform sampler2D rubyTexture;\n\n"
  287. + "void main() {\n"
  288. + " gl_FragColor = texture2D(rubyTexture, v_texCoord);\n"
  289. + "}\n";
  290. +
  291. #ifdef DB_OPENGL_ERROR
  292. void OPENGL_ERROR(const char* message) {
  293. GLenum r = glGetError();
  294. @@ -583,6 +664,50 @@
  295. }
  296. }
  297.  
  298. +#if C_OPENGL
  299. +/* Create a GLSL shader object, load the shader source, and compile the shader. */
  300. +static GLuint GFX_LoadGLShader ( GLenum type, const char *shaderSrc ) {
  301. + GLuint shader;
  302. + GLint compiled;
  303. +
  304. + // Create the shader object
  305. + shader = glCreateShader(type);
  306. +
  307. + if (shader == 0) return 0;
  308. +
  309. + // Load the shader source
  310. + glShaderSource(shader, 1, &shaderSrc, NULL);
  311. +
  312. + // Compile the shader
  313. + glCompileShader(shader);
  314. +
  315. + // Check the compile status
  316. + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  317. +
  318. + if (!compiled) {
  319. + char* infoLog = NULL;
  320. + GLint infoLen = 0;
  321. + LOG_MSG("SDL:OPENGL:Error compiling %s shader:", type==GL_VERTEX_SHADER ? "vertex":"fragment");
  322. +
  323. + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
  324. + if (infoLen>1) {
  325. + infoLog = (char*)malloc(infoLen);
  326. + if (infoLog) glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
  327. + }
  328. +
  329. + if (infoLog) {
  330. + LOG_MSG("%s", infoLog);
  331. + free(infoLog);
  332. + } else LOG_MSG("Unable to get error log");
  333. +
  334. + glDeleteShader(shader);
  335. + return 0;
  336. + }
  337. +
  338. + return shader;
  339. +}
  340. +#endif
  341. +
  342. Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) {
  343. if (sdl.updating)
  344. GFX_EndUpdate( 0 );
  345. @@ -752,11 +877,123 @@
  346. #if SDL_VERSION_ATLEAST(1, 2, 11)
  347. SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
  348. #endif
  349. - GFX_SetupSurfaceScaled(SDL_OPENGL,0);
  350. + GFX_SetupSurfaceScaled(SDL_OPENGL,32);
  351. if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) {
  352. LOG_MSG("SDL:OPENGL: Can't open drawing surface, are you running in 16bpp (or higher) mode?");
  353. goto dosurface;
  354. }
  355. +
  356. + if (sdl.opengl.use_shader) {
  357. + GLboolean t;
  358. + // confirm current context supports shaders
  359. + glGetBooleanv(GL_SHADER_COMPILER, &t);
  360. + if (t) {
  361. + // check if existing program is valid
  362. + if (sdl.opengl.program_object) {
  363. + // reset error
  364. + glGetError();
  365. + glUseProgram(sdl.opengl.program_object);
  366. + if (glGetError() != GL_NO_ERROR) {
  367. + // program is not usable (probably new context), purge it
  368. + glDeleteProgram(sdl.opengl.program_object);
  369. + sdl.opengl.program_object = 0;
  370. + }
  371. + }
  372. +
  373. + // does program need to be rebuilt?
  374. + if (sdl.opengl.program_object == 0) {
  375. + GLuint vertexShader = 0;
  376. + if (sdl.opengl.vertex_src) {
  377. + vertexShader = GFX_LoadGLShader(GL_VERTEX_SHADER, sdl.opengl.vertex_src);
  378. + if (!vertexShader) LOG_MSG("Falling back to default vertex shader...");
  379. + }
  380. + if (!vertexShader) {
  381. + vertexShader = GFX_LoadGLShader(GL_VERTEX_SHADER, vertex_shader_default);
  382. + if (!vertexShader)
  383. + goto dosurface;
  384. + }
  385. +
  386. + GLuint fragmentShader = 0;
  387. + if (sdl.opengl.fragment_src) {
  388. + fragmentShader = GFX_LoadGLShader(GL_FRAGMENT_SHADER, sdl.opengl.fragment_src);
  389. + if (!fragmentShader) LOG_MSG("Falling back to default fragment shader...");
  390. + }
  391. + if (!fragmentShader) {
  392. + fragmentShader = GFX_LoadGLShader(GL_FRAGMENT_SHADER, fragment_shader_default);
  393. + if (!fragmentShader) {
  394. + glDeleteShader(vertexShader);
  395. + goto dosurface;
  396. + }
  397. + }
  398. +
  399. + sdl.opengl.program_object = glCreateProgram();
  400. + if (!sdl.opengl.program_object) {
  401. + glDeleteShader(vertexShader);
  402. + glDeleteShader(fragmentShader);
  403. + LOG_MSG("SDL:OPENGL:Can't create program object, falling back to surface");
  404. + goto dosurface;
  405. + }
  406. + glAttachShader(sdl.opengl.program_object, vertexShader);
  407. + glAttachShader(sdl.opengl.program_object, fragmentShader);
  408. + // Link the program
  409. + glLinkProgram(sdl.opengl.program_object);
  410. + // Even if we *are* successful, we may delete the shader objects
  411. + glDeleteShader(vertexShader);
  412. + glDeleteShader(fragmentShader);
  413. +
  414. + // Check the link status
  415. + GLint isProgramLinked;
  416. + glGetProgramiv(sdl.opengl.program_object, GL_LINK_STATUS, &isProgramLinked);
  417. + if (!isProgramLinked) {
  418. + char *infoLog = NULL;
  419. + GLint infoLen = 0;
  420. + LOG_MSG("SDL:OPENGL:Error linking program:");
  421. +
  422. + glGetProgramiv(sdl.opengl.program_object, GL_INFO_LOG_LENGTH, &infoLen);
  423. + if (infoLen>1) {
  424. + infoLog = (char*)malloc(infoLen);
  425. + if (infoLog) glGetProgramInfoLog(sdl.opengl.program_object, infoLen, NULL, infoLog);
  426. + }
  427. +
  428. + if (infoLog) {
  429. + LOG_MSG("%s", infoLog);
  430. + free(infoLog);
  431. + } else LOG_MSG("Unable to get error log");
  432. +
  433. + glDeleteProgram(sdl.opengl.program_object);
  434. + sdl.opengl.program_object = 0;
  435. + goto dosurface;
  436. + }
  437. +
  438. + glUseProgram(sdl.opengl.program_object);
  439. +
  440. + GLint u = glGetAttribLocation(sdl.opengl.program_object, "a_position");
  441. + // upper left
  442. + sdl.opengl.vertex_data[0] = -1.0f;
  443. + sdl.opengl.vertex_data[1] = 1.0f;
  444. + // lower left
  445. + sdl.opengl.vertex_data[2] = -1.0f;
  446. + sdl.opengl.vertex_data[3] = -3.0f;
  447. + // upper right
  448. + sdl.opengl.vertex_data[4] = 3.0f;
  449. + sdl.opengl.vertex_data[5] = 1.0f;
  450. + // Load the vertex positions
  451. + glVertexAttribPointer(u, 2, GL_FLOAT, GL_FALSE, 0, sdl.opengl.vertex_data);
  452. + glEnableVertexAttribArray(u);
  453. +
  454. + u = glGetUniformLocation(sdl.opengl.program_object, "rubyTexture");
  455. + glUniform1i(u, 0);
  456. +
  457. + sdl.opengl.ruby.texture_size = glGetUniformLocation(sdl.opengl.program_object, "rubyTextureSize");
  458. + sdl.opengl.ruby.input_size = glGetUniformLocation(sdl.opengl.program_object, "rubyInputSize");
  459. + sdl.opengl.ruby.output_size = glGetUniformLocation(sdl.opengl.program_object, "rubyOutputSize");
  460. + sdl.opengl.ruby.frame_count = glGetUniformLocation(sdl.opengl.program_object, "rubyFrameCount");
  461. + // Don't force updating unless a shader depends on frame_count
  462. + RENDER_SetForceUpdate(sdl.opengl.ruby.frame_count != (GLint)-1);
  463. + }
  464. + }
  465. + }
  466. +
  467. /* Create the texture and display list */
  468. if (sdl.opengl.pixel_buffer_object) {
  469. glGenBuffersARB(1, &sdl.opengl.buffer);
  470. @@ -773,10 +1010,8 @@
  471. glViewport((sdl.surface->w-sdl.clip.w)/2,(sdl.surface->h-sdl.clip.h)/2,sdl.clip.w,sdl.clip.h);
  472. } else {
  473. glViewport(sdl.clip.x,sdl.clip.y,sdl.clip.w,sdl.clip.h);
  474. - }
  475. + }
  476.  
  477. - glMatrixMode (GL_PROJECTION);
  478. -
  479. if (sdl.opengl.texture > 0) {
  480. glDeleteTextures(1,&sdl.opengl.texture);
  481. }
  482. @@ -802,33 +1037,43 @@
  483. glClear(GL_COLOR_BUFFER_BIT);
  484. SDL_GL_SwapBuffers();
  485. glClear(GL_COLOR_BUFFER_BIT);
  486. - glShadeModel (GL_FLAT);
  487. glDisable (GL_DEPTH_TEST);
  488. glDisable (GL_LIGHTING);
  489. glDisable(GL_CULL_FACE);
  490. glEnable(GL_TEXTURE_2D);
  491. - glMatrixMode (GL_MODELVIEW);
  492. - glLoadIdentity ();
  493.  
  494. - GLfloat tex_width=((GLfloat)(width)/(GLfloat)texsize);
  495. - GLfloat tex_height=((GLfloat)(height)/(GLfloat)texsize);
  496. + if (sdl.opengl.program_object) {
  497. + // Set shader variables
  498. + glUniform2f(sdl.opengl.ruby.texture_size, (float)texsize, (float)texsize);
  499. + glUniform2f(sdl.opengl.ruby.input_size, (float)width, (float)height);
  500. + glUniform2f(sdl.opengl.ruby.output_size, sdl.clip.w, sdl.clip.h);
  501. + // The following uniform is *not* set right now
  502. + sdl.opengl.actual_frame_count = 0;
  503. + } else {
  504. + GLfloat tex_width=((GLfloat)(width)/(GLfloat)texsize);
  505. + GLfloat tex_height=((GLfloat)(height)/(GLfloat)texsize);
  506.  
  507. - if (glIsList(sdl.opengl.displaylist)) glDeleteLists(sdl.opengl.displaylist, 1);
  508. - sdl.opengl.displaylist = glGenLists(1);
  509. - glNewList(sdl.opengl.displaylist, GL_COMPILE);
  510. - glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
  511. + glShadeModel(GL_FLAT);
  512. + glMatrixMode(GL_MODELVIEW);
  513. + glLoadIdentity();
  514.  
  515. - glBegin(GL_TRIANGLES);
  516. - // upper left
  517. - glTexCoord2f(0,0); glVertex2f(-1.0f, 1.0f);
  518. - // lower left
  519. - glTexCoord2f(0,tex_height*2); glVertex2f(-1.0f,-3.0f);
  520. - // upper right
  521. - glTexCoord2f(tex_width*2,0); glVertex2f(3.0f, 1.0f);
  522. - glEnd();
  523. + if (glIsList(sdl.opengl.displaylist)) glDeleteLists(sdl.opengl.displaylist, 1);
  524. + sdl.opengl.displaylist = glGenLists(1);
  525. + glNewList(sdl.opengl.displaylist, GL_COMPILE);
  526. + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
  527.  
  528. - glEndList();
  529. + glBegin(GL_TRIANGLES);
  530. + // upper left
  531. + glTexCoord2f(0,0); glVertex2f(-1.0f, 1.0f);
  532. + // lower left
  533. + glTexCoord2f(0,tex_height*2); glVertex2f(-1.0f,-3.0f);
  534. + // upper right
  535. + glTexCoord2f(tex_width*2,0); glVertex2f(3.0f, 1.0f);
  536. + glEnd();
  537.  
  538. + glEndList();
  539. + }
  540. +
  541. OPENGL_ERROR("End of setsize");
  542.  
  543. sdl.desktop.type=SCREEN_OPENGL;
  544. @@ -835,7 +1080,7 @@
  545. retFlags = GFX_CAN_32 | GFX_SCALING;
  546. if (sdl.opengl.pixel_buffer_object)
  547. retFlags |= GFX_HARDWARE;
  548. - break;
  549. + break;
  550. }//OPENGL
  551. #endif //C_OPENGL
  552. default:
  553. @@ -848,6 +1093,20 @@
  554. return retFlags;
  555. }
  556.  
  557. +void GFX_SetShaders(const char* vertex, const char* fragment) {
  558. +#if C_OPENGL
  559. + if (!sdl.opengl.use_shader || (vertex == sdl.opengl.vertex_src && fragment == sdl.opengl.fragment_src))
  560. + return;
  561. +
  562. + sdl.opengl.vertex_src = vertex;
  563. + sdl.opengl.fragment_src = fragment;
  564. + if (sdl.opengl.program_object) {
  565. + glDeleteProgram(sdl.opengl.program_object);
  566. + sdl.opengl.program_object = 0;
  567. + }
  568. +#endif
  569. +}
  570. +
  571. void GFX_CaptureMouse(void) {
  572. sdl.mouse.locked=!sdl.mouse.locked;
  573. if (sdl.mouse.locked) {
  574. @@ -1011,8 +1270,9 @@
  575. #if C_DDRAW
  576. int ret;
  577. #endif
  578. - if (!sdl.updating)
  579. + if (((sdl.desktop.type != SCREEN_OPENGL) || !RENDER_GetForceUpdate()) && !sdl.updating)
  580. return;
  581. + bool actually_updating = sdl.updating;
  582. sdl.updating=false;
  583. switch (sdl.desktop.type) {
  584. case SCREEN_SURFACE:
  585. @@ -1077,6 +1337,15 @@
  586. case SCREEN_OPENGL:
  587. // Clear drawing area. Some drivers (on Linux) have more than 2 buffers and the screen might
  588. // be dirty because of other programs.
  589. + if (!actually_updating) {
  590. + /* Don't really update; Just increase the frame counter.
  591. + * If we tried to update it may have not worked so well
  592. + * with VSync...
  593. + * (Think of 60Hz on the host with 70Hz on the client.)
  594. + */
  595. + sdl.opengl.actual_frame_count++;
  596. + return;
  597. + }
  598. glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
  599. glClear(GL_COLOR_BUFFER_BIT);
  600. if (sdl.opengl.pixel_buffer_object) {
  601. @@ -1086,8 +1355,6 @@
  602. sdl.draw.width, sdl.draw.height, GL_BGRA_EXT,
  603. GL_UNSIGNED_INT_8_8_8_8_REV, 0);
  604. glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
  605. - glCallList(sdl.opengl.displaylist);
  606. - SDL_GL_SwapBuffers();
  607. } else if (changedLines) {
  608. Bitu y = 0, index = 0;
  609. glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
  610. @@ -1104,9 +1371,14 @@
  611. }
  612. index++;
  613. }
  614. - glCallList(sdl.opengl.displaylist);
  615. - SDL_GL_SwapBuffers();
  616. - }
  617. + } else
  618. + return;
  619. +
  620. + if (sdl.opengl.program_object) {
  621. + glUniform1i(sdl.opengl.ruby.frame_count, sdl.opengl.actual_frame_count++);
  622. + glDrawArrays(GL_TRIANGLES, 0, 3);
  623. + } else glCallList(sdl.opengl.displaylist);
  624. + SDL_GL_SwapBuffers();
  625. break;
  626. #endif
  627. default:
  628. @@ -1430,6 +1702,31 @@
  629. LOG_MSG("Could not initialize OpenGL, switching back to surface");
  630. sdl.desktop.want_type = SCREEN_SURFACE;
  631. } else {
  632. + sdl.opengl.program_object = 0;
  633. + glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader");
  634. + glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
  635. + glCreateProgram = (PFNGLCREATEPROGRAMPROC)SDL_GL_GetProcAddress("glCreateProgram");
  636. + glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader");
  637. + glDeleteProgram = (PFNGLDELETEPROGRAMPROC)SDL_GL_GetProcAddress("glDeleteProgram");
  638. + glDeleteShader = (PFNGLDELETESHADERPROC)SDL_GL_GetProcAddress("glDeleteShader");
  639. + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)SDL_GL_GetProcAddress("glEnableVertexAttribArray");
  640. + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)SDL_GL_GetProcAddress("glGetAttribLocation");
  641. + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)SDL_GL_GetProcAddress("glGetProgramiv");
  642. + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog");
  643. + glGetShaderiv = (PFNGLGETSHADERIVPROC)SDL_GL_GetProcAddress("glGetShaderiv");
  644. + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)SDL_GL_GetProcAddress("glGetShaderInfoLog");
  645. + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)SDL_GL_GetProcAddress("glGetUniformLocation");
  646. + glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram");
  647. + glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource");
  648. + glUniform2f = (PFNGLUNIFORM2FPROC)SDL_GL_GetProcAddress("glUniform2f");
  649. + glUniform1i = (PFNGLUNIFORM1IPROC)SDL_GL_GetProcAddress("glUniform1i");
  650. + glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
  651. + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)SDL_GL_GetProcAddress("glVertexAttribPointer");
  652. + sdl.opengl.use_shader = (glAttachShader && glCompileShader && glCreateProgram && glDeleteProgram && glDeleteShader && \
  653. + glEnableVertexAttribArray && glGetAttribLocation && glGetProgramiv && glGetProgramInfoLog && \
  654. + glGetShaderiv && glGetShaderInfoLog && glGetUniformLocation && glLinkProgram && glShaderSource && \
  655. + glUniform2f && glUniform1i && glUseProgram && glVertexAttribPointer);
  656. +
  657. sdl.opengl.buffer=0;
  658. sdl.opengl.framebuf=0;
  659. sdl.opengl.texture=0;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement