Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: include/render.h
- ===================================================================
- --- include/render.h (revision 4309)
- +++ include/render.h (working copy)
- @@ -80,11 +80,18 @@
- Bit8u *cacheRead;
- Bitu inHeight, inLine, outLine;
- } scale;
- +#if C_OPENGL
- + struct {
- + char* vertex_src;
- + char* fragment_src;
- + } gl;
- +#endif
- RenderPal_t pal;
- bool updating;
- bool active;
- bool aspect;
- bool fullFrame;
- + bool forceUpdate;
- } Render_t;
- extern Render_t render;
- @@ -93,6 +100,8 @@
- bool RENDER_StartUpdate(void);
- void RENDER_EndUpdate(bool abort);
- void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
- +bool RENDER_GetForceUpdate(void);
- +void RENDER_SetForceUpdate(bool);
- #endif
- Index: include/video.h
- ===================================================================
- --- include/video.h (revision 4309)
- +++ include/video.h (working copy)
- @@ -59,6 +59,7 @@
- Bitu GFX_GetBestMode(Bitu flags);
- Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
- Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t cb);
- +void GFX_SetShaders(const char* vertex, const char* fragment);
- void GFX_ResetScreen(void);
- void GFX_Start(void);
- Index: src/dosbox.cpp
- ===================================================================
- --- src/dosbox.cpp (revision 4309)
- +++ src/dosbox.cpp (working copy)
- @@ -473,6 +473,14 @@
- Pstring = Pmulti->GetSection()->Add_string("force",Property::Changeable::Always,"");
- Pstring->Set_values(force);
- + Pstring = secprop->Add_string("glshader",Property::Changeable::Always,"none");
- + Pstring->Set_help("What set of GLSL shaders to use with an OpenGL output.\n"
- + "Note that in case it is used, the respective shader files must be found in the\n"
- + "\"glshaders\" subdirectory relative to where the default DOSBox configuration\n"
- + "file is stored. For shader file naming convention, suppose that you have a pair\n"
- + "of shader files ready: mysample.glslv and mysample.glslf.\n"
- + "Then glshader=mysample should be set.");
- +
- secprop=control->AddSection_prop("cpu",&CPU_Init,true);//done
- const char* cores[] = { "auto",
- #if (C_DYNAMIC_X86) || (C_DYNREC)
- Index: src/gui/render.cpp
- ===================================================================
- --- src/gui/render.cpp (revision 4309)
- +++ src/gui/render.cpp (working copy)
- @@ -20,6 +20,9 @@
- #include <sys/types.h>
- #include <assert.h>
- #include <math.h>
- +#include <stdlib.h>
- +#include <fstream>
- +#include <sstream>
- #include "dosbox.h"
- #include "video.h"
- @@ -229,6 +232,7 @@
- total += render.frameskip.hadSkip[i];
- LOG_MSG( "Skipped frame %d %d", PIC_Ticks, (total * 100) / RENDER_SKIP_CACHE );
- #endif
- + if (RENDER_GetForceUpdate()) GFX_EndUpdate(0);
- }
- render.frameskip.index = (render.frameskip.index + 1) & (RENDER_SKIP_CACHE - 1);
- render.updating=false;
- @@ -419,6 +423,9 @@
- }
- }
- /* Setup the scaler variables */
- +#if C_OPENGL
- + GFX_SetShaders(render.gl.vertex_src, render.gl.fragment_src);
- +#endif
- gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_CallBack);
- if (gfx_flags & GFX_CAN_8)
- render.scale.outMode = scalerMode8;
- @@ -563,6 +570,58 @@
- RENDER_CallBack( GFX_CallBackReset );
- } */
- +bool RENDER_GetForceUpdate(void) {
- + return render.forceUpdate;
- +}
- +
- +void RENDER_SetForceUpdate(bool f) {
- + render.forceUpdate = f;
- +}
- +
- +#if C_OPENGL
- +static void RENDER_GetShaders(std::string &glshader) {
- + std::string shader_path;
- + Cross::GetPlatformConfigDir(shader_path);
- + shader_path = shader_path + "glshaders" + CROSS_FILESPLIT + glshader + ".glsl";
- + char* src;
- + std::ifstream vshader((shader_path + "v").c_str(), std::ios_base::binary);
- + if (vshader) {
- + std::stringstream buf;
- + buf << vshader.rdbuf();
- + vshader.close();
- + // keep the same buffer if contents aren't different
- + if (render.gl.vertex_src==NULL || buf.str() != render.gl.vertex_src) {
- + src = strdup(buf.str().c_str());
- + if (src==NULL) LOG_MSG("WARNING: Couldn't copy vertex shader source");
- + } else {
- + src = render.gl.vertex_src;
- + render.gl.vertex_src = NULL;
- + }
- + } else src = NULL;
- + free(render.gl.vertex_src);
- + render.gl.vertex_src = src;
- +
- + std::ifstream fshader((shader_path + "f").c_str(), std::ios_base::binary);
- + if (fshader) {
- + std::stringstream buf;
- + buf << fshader.rdbuf();
- + fshader.close();
- + if (render.gl.fragment_src==NULL || buf.str() != render.gl.fragment_src) {
- + src = strdup(buf.str().c_str());
- + if (src==NULL) LOG_MSG("WARNING: Couldn't copy fragment shader source");
- + } else {
- + src = render.gl.fragment_src;
- + render.gl.fragment_src = NULL;
- + }
- + } else src = NULL;
- + free(render.gl.fragment_src);
- + render.gl.fragment_src = src;
- +
- + if (render.gl.vertex_src==NULL && render.gl.fragment_src==NULL)
- + LOG_MSG("Unable to find any shaders matching %s", glshader.c_str());
- +}
- +#endif
- +
- void RENDER_Init(Section * sec) {
- Section_prop * section=static_cast<Section_prop *>(sec);
- @@ -616,10 +675,25 @@
- else if (scaler == "scan3x"){ render.scale.op = scalerOpScan;render.scale.size = 3; }
- #endif
- +#if C_OPENGL
- + char* vertex_src = render.gl.vertex_src;
- + char* fragment_src = render.gl.fragment_src;
- + f = section->Get_string("glshader");
- + if (f.empty() || f=="none") {
- + free(render.gl.vertex_src);
- + render.gl.vertex_src = NULL;
- + free(render.gl.fragment_src);
- + render.gl.fragment_src = NULL;
- + } else RENDER_GetShaders(f);
- +#endif
- +
- //If something changed that needs a ReInit
- // Only ReInit when there is a src.bpp (fixes crashes on startup and directly changing the scaler without a screen specified yet)
- if(running && render.src.bpp && ((render.aspect != aspect) || (render.scale.op != scaleOp) ||
- (render.scale.size != scalersize) || (render.scale.forced != scalerforced) ||
- +#if C_OPENGL
- + (render.gl.vertex_src != vertex_src) || (render.gl.fragment_src != fragment_src) ||
- +#endif
- render.scale.forced))
- RENDER_CallBack( GFX_CallBackReset );
- Index: src/gui/sdlmain.cpp
- ===================================================================
- --- src/gui/sdlmain.cpp (revision 4309)
- +++ src/gui/sdlmain.cpp (working copy)
- @@ -49,6 +49,7 @@
- #include "cpu.h"
- #include "cross.h"
- #include "control.h"
- +#include "render.h"
- #define MAPPERFILE "mapper-" VERSION ".map"
- //#define DISABLE_JOYSTICK
- @@ -92,6 +93,53 @@
- PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
- PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
- +#ifndef GL_VERSION_2_0
- +#define GL_VERSION_2_0 1
- +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
- +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
- +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
- +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
- +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
- +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
- +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
- +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
- +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
- +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
- +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
- +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
- +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
- +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
- +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
- +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
- +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
- +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
- +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
- +#endif
- +
- +PFNGLATTACHSHADERPROC glAttachShader = NULL;
- +PFNGLCOMPILESHADERPROC glCompileShader = NULL;
- +PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
- +PFNGLCREATESHADERPROC glCreateShader = NULL;
- +PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
- +PFNGLDELETESHADERPROC glDeleteShader = NULL;
- +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
- +PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
- +PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
- +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
- +PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
- +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
- +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
- +PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
- +PFNGLSHADERSOURCEPROC glShaderSource = NULL;
- +PFNGLUNIFORM2FPROC glUniform2f = NULL;
- +PFNGLUNIFORM1IPROC glUniform1i = NULL;
- +PFNGLUSEPROGRAMPROC glUseProgram = NULL;
- +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
- +
- +#ifndef GL_SHADER_COMPILER
- +#define GL_SHADER_COMPILER 0x8DFA
- +#endif
- +
- #endif //C_OPENGL
- #if !(ENVIRON_INCLUDED)
- @@ -190,6 +238,19 @@
- bool packed_pixel;
- bool paletted_texture;
- bool pixel_buffer_object;
- +
- + bool use_shader;
- + GLuint program_object;
- + const char *vertex_src;
- + const char *fragment_src;
- + struct {
- + GLint texture_size;
- + GLint input_size;
- + GLint output_size;
- + GLint frame_count;
- + } ruby;
- + GLint actual_frame_count;
- + GLfloat vertex_data[2*3];
- } opengl;
- #endif
- struct {
- @@ -229,6 +290,26 @@
- static SDL_Block sdl;
- #if C_OPENGL
- +static char const vertex_shader_default[] =
- + "attribute vec4 a_position;\n"
- + "varying vec2 v_texCoord;\n"
- + "uniform vec2 rubyTextureSize;\n"
- + "uniform vec2 rubyInputSize;\n"
- + "uniform vec2 rubyOutputSize;\n\n"
- + "void main() {\n"
- + " gl_Position = a_position;\n"
- + " v_texCoord = vec2(a_position.x+1.0,1.0-a_position.y)/2.0*rubyInputSize/rubyTextureSize;\n"
- + "}\n";
- +static char const fragment_shader_default[] =
- + "#ifdef GL_ES\n"
- + "precision mediump float;\n"
- + "#endif\n"
- + "varying vec2 v_texCoord;\n"
- + "uniform sampler2D rubyTexture;\n\n"
- + "void main() {\n"
- + " gl_FragColor = texture2D(rubyTexture, v_texCoord);\n"
- + "}\n";
- +
- #ifdef DB_OPENGL_ERROR
- void OPENGL_ERROR(const char* message) {
- GLenum r = glGetError();
- @@ -583,6 +664,50 @@
- }
- }
- +#if C_OPENGL
- +/* Create a GLSL shader object, load the shader source, and compile the shader. */
- +static GLuint GFX_LoadGLShader ( GLenum type, const char *shaderSrc ) {
- + GLuint shader;
- + GLint compiled;
- +
- + // Create the shader object
- + shader = glCreateShader(type);
- +
- + if (shader == 0) return 0;
- +
- + // Load the shader source
- + glShaderSource(shader, 1, &shaderSrc, NULL);
- +
- + // Compile the shader
- + glCompileShader(shader);
- +
- + // Check the compile status
- + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- +
- + if (!compiled) {
- + char* infoLog = NULL;
- + GLint infoLen = 0;
- + LOG_MSG("SDL:OPENGL:Error compiling %s shader:", type==GL_VERTEX_SHADER ? "vertex":"fragment");
- +
- + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
- + if (infoLen>1) {
- + infoLog = (char*)malloc(infoLen);
- + if (infoLog) glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
- + }
- +
- + if (infoLog) {
- + LOG_MSG("%s", infoLog);
- + free(infoLog);
- + } else LOG_MSG("Unable to get error log");
- +
- + glDeleteShader(shader);
- + return 0;
- + }
- +
- + return shader;
- +}
- +#endif
- +
- Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) {
- if (sdl.updating)
- GFX_EndUpdate( 0 );
- @@ -752,11 +877,123 @@
- #if SDL_VERSION_ATLEAST(1, 2, 11)
- SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
- #endif
- - GFX_SetupSurfaceScaled(SDL_OPENGL,0);
- + GFX_SetupSurfaceScaled(SDL_OPENGL,32);
- if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) {
- LOG_MSG("SDL:OPENGL: Can't open drawing surface, are you running in 16bpp (or higher) mode?");
- goto dosurface;
- }
- +
- + if (sdl.opengl.use_shader) {
- + GLboolean t;
- + // confirm current context supports shaders
- + glGetBooleanv(GL_SHADER_COMPILER, &t);
- + if (t) {
- + // check if existing program is valid
- + if (sdl.opengl.program_object) {
- + // reset error
- + glGetError();
- + glUseProgram(sdl.opengl.program_object);
- + if (glGetError() != GL_NO_ERROR) {
- + // program is not usable (probably new context), purge it
- + glDeleteProgram(sdl.opengl.program_object);
- + sdl.opengl.program_object = 0;
- + }
- + }
- +
- + // does program need to be rebuilt?
- + if (sdl.opengl.program_object == 0) {
- + GLuint vertexShader = 0;
- + if (sdl.opengl.vertex_src) {
- + vertexShader = GFX_LoadGLShader(GL_VERTEX_SHADER, sdl.opengl.vertex_src);
- + if (!vertexShader) LOG_MSG("Falling back to default vertex shader...");
- + }
- + if (!vertexShader) {
- + vertexShader = GFX_LoadGLShader(GL_VERTEX_SHADER, vertex_shader_default);
- + if (!vertexShader)
- + goto dosurface;
- + }
- +
- + GLuint fragmentShader = 0;
- + if (sdl.opengl.fragment_src) {
- + fragmentShader = GFX_LoadGLShader(GL_FRAGMENT_SHADER, sdl.opengl.fragment_src);
- + if (!fragmentShader) LOG_MSG("Falling back to default fragment shader...");
- + }
- + if (!fragmentShader) {
- + fragmentShader = GFX_LoadGLShader(GL_FRAGMENT_SHADER, fragment_shader_default);
- + if (!fragmentShader) {
- + glDeleteShader(vertexShader);
- + goto dosurface;
- + }
- + }
- +
- + sdl.opengl.program_object = glCreateProgram();
- + if (!sdl.opengl.program_object) {
- + glDeleteShader(vertexShader);
- + glDeleteShader(fragmentShader);
- + LOG_MSG("SDL:OPENGL:Can't create program object, falling back to surface");
- + goto dosurface;
- + }
- + glAttachShader(sdl.opengl.program_object, vertexShader);
- + glAttachShader(sdl.opengl.program_object, fragmentShader);
- + // Link the program
- + glLinkProgram(sdl.opengl.program_object);
- + // Even if we *are* successful, we may delete the shader objects
- + glDeleteShader(vertexShader);
- + glDeleteShader(fragmentShader);
- +
- + // Check the link status
- + GLint isProgramLinked;
- + glGetProgramiv(sdl.opengl.program_object, GL_LINK_STATUS, &isProgramLinked);
- + if (!isProgramLinked) {
- + char *infoLog = NULL;
- + GLint infoLen = 0;
- + LOG_MSG("SDL:OPENGL:Error linking program:");
- +
- + glGetProgramiv(sdl.opengl.program_object, GL_INFO_LOG_LENGTH, &infoLen);
- + if (infoLen>1) {
- + infoLog = (char*)malloc(infoLen);
- + if (infoLog) glGetProgramInfoLog(sdl.opengl.program_object, infoLen, NULL, infoLog);
- + }
- +
- + if (infoLog) {
- + LOG_MSG("%s", infoLog);
- + free(infoLog);
- + } else LOG_MSG("Unable to get error log");
- +
- + glDeleteProgram(sdl.opengl.program_object);
- + sdl.opengl.program_object = 0;
- + goto dosurface;
- + }
- +
- + glUseProgram(sdl.opengl.program_object);
- +
- + GLint u = glGetAttribLocation(sdl.opengl.program_object, "a_position");
- + // upper left
- + sdl.opengl.vertex_data[0] = -1.0f;
- + sdl.opengl.vertex_data[1] = 1.0f;
- + // lower left
- + sdl.opengl.vertex_data[2] = -1.0f;
- + sdl.opengl.vertex_data[3] = -3.0f;
- + // upper right
- + sdl.opengl.vertex_data[4] = 3.0f;
- + sdl.opengl.vertex_data[5] = 1.0f;
- + // Load the vertex positions
- + glVertexAttribPointer(u, 2, GL_FLOAT, GL_FALSE, 0, sdl.opengl.vertex_data);
- + glEnableVertexAttribArray(u);
- +
- + u = glGetUniformLocation(sdl.opengl.program_object, "rubyTexture");
- + glUniform1i(u, 0);
- +
- + sdl.opengl.ruby.texture_size = glGetUniformLocation(sdl.opengl.program_object, "rubyTextureSize");
- + sdl.opengl.ruby.input_size = glGetUniformLocation(sdl.opengl.program_object, "rubyInputSize");
- + sdl.opengl.ruby.output_size = glGetUniformLocation(sdl.opengl.program_object, "rubyOutputSize");
- + sdl.opengl.ruby.frame_count = glGetUniformLocation(sdl.opengl.program_object, "rubyFrameCount");
- + // Don't force updating unless a shader depends on frame_count
- + RENDER_SetForceUpdate(sdl.opengl.ruby.frame_count != (GLint)-1);
- + }
- + }
- + }
- +
- /* Create the texture and display list */
- if (sdl.opengl.pixel_buffer_object) {
- glGenBuffersARB(1, &sdl.opengl.buffer);
- @@ -773,10 +1010,8 @@
- glViewport((sdl.surface->w-sdl.clip.w)/2,(sdl.surface->h-sdl.clip.h)/2,sdl.clip.w,sdl.clip.h);
- } else {
- glViewport(sdl.clip.x,sdl.clip.y,sdl.clip.w,sdl.clip.h);
- - }
- + }
- - glMatrixMode (GL_PROJECTION);
- -
- if (sdl.opengl.texture > 0) {
- glDeleteTextures(1,&sdl.opengl.texture);
- }
- @@ -802,33 +1037,43 @@
- glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapBuffers();
- glClear(GL_COLOR_BUFFER_BIT);
- - glShadeModel (GL_FLAT);
- glDisable (GL_DEPTH_TEST);
- glDisable (GL_LIGHTING);
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
- - glMatrixMode (GL_MODELVIEW);
- - glLoadIdentity ();
- - GLfloat tex_width=((GLfloat)(width)/(GLfloat)texsize);
- - GLfloat tex_height=((GLfloat)(height)/(GLfloat)texsize);
- + if (sdl.opengl.program_object) {
- + // Set shader variables
- + glUniform2f(sdl.opengl.ruby.texture_size, (float)texsize, (float)texsize);
- + glUniform2f(sdl.opengl.ruby.input_size, (float)width, (float)height);
- + glUniform2f(sdl.opengl.ruby.output_size, sdl.clip.w, sdl.clip.h);
- + // The following uniform is *not* set right now
- + sdl.opengl.actual_frame_count = 0;
- + } else {
- + GLfloat tex_width=((GLfloat)(width)/(GLfloat)texsize);
- + GLfloat tex_height=((GLfloat)(height)/(GLfloat)texsize);
- - if (glIsList(sdl.opengl.displaylist)) glDeleteLists(sdl.opengl.displaylist, 1);
- - sdl.opengl.displaylist = glGenLists(1);
- - glNewList(sdl.opengl.displaylist, GL_COMPILE);
- - glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
- + glShadeModel(GL_FLAT);
- + glMatrixMode(GL_MODELVIEW);
- + glLoadIdentity();
- - glBegin(GL_TRIANGLES);
- - // upper left
- - glTexCoord2f(0,0); glVertex2f(-1.0f, 1.0f);
- - // lower left
- - glTexCoord2f(0,tex_height*2); glVertex2f(-1.0f,-3.0f);
- - // upper right
- - glTexCoord2f(tex_width*2,0); glVertex2f(3.0f, 1.0f);
- - glEnd();
- + if (glIsList(sdl.opengl.displaylist)) glDeleteLists(sdl.opengl.displaylist, 1);
- + sdl.opengl.displaylist = glGenLists(1);
- + glNewList(sdl.opengl.displaylist, GL_COMPILE);
- + glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
- - glEndList();
- + glBegin(GL_TRIANGLES);
- + // upper left
- + glTexCoord2f(0,0); glVertex2f(-1.0f, 1.0f);
- + // lower left
- + glTexCoord2f(0,tex_height*2); glVertex2f(-1.0f,-3.0f);
- + // upper right
- + glTexCoord2f(tex_width*2,0); glVertex2f(3.0f, 1.0f);
- + glEnd();
- + glEndList();
- + }
- +
- OPENGL_ERROR("End of setsize");
- sdl.desktop.type=SCREEN_OPENGL;
- @@ -835,7 +1080,7 @@
- retFlags = GFX_CAN_32 | GFX_SCALING;
- if (sdl.opengl.pixel_buffer_object)
- retFlags |= GFX_HARDWARE;
- - break;
- + break;
- }//OPENGL
- #endif //C_OPENGL
- default:
- @@ -848,6 +1093,20 @@
- return retFlags;
- }
- +void GFX_SetShaders(const char* vertex, const char* fragment) {
- +#if C_OPENGL
- + if (!sdl.opengl.use_shader || (vertex == sdl.opengl.vertex_src && fragment == sdl.opengl.fragment_src))
- + return;
- +
- + sdl.opengl.vertex_src = vertex;
- + sdl.opengl.fragment_src = fragment;
- + if (sdl.opengl.program_object) {
- + glDeleteProgram(sdl.opengl.program_object);
- + sdl.opengl.program_object = 0;
- + }
- +#endif
- +}
- +
- void GFX_CaptureMouse(void) {
- sdl.mouse.locked=!sdl.mouse.locked;
- if (sdl.mouse.locked) {
- @@ -1011,8 +1270,9 @@
- #if C_DDRAW
- int ret;
- #endif
- - if (!sdl.updating)
- + if (((sdl.desktop.type != SCREEN_OPENGL) || !RENDER_GetForceUpdate()) && !sdl.updating)
- return;
- + bool actually_updating = sdl.updating;
- sdl.updating=false;
- switch (sdl.desktop.type) {
- case SCREEN_SURFACE:
- @@ -1077,6 +1337,15 @@
- case SCREEN_OPENGL:
- // Clear drawing area. Some drivers (on Linux) have more than 2 buffers and the screen might
- // be dirty because of other programs.
- + if (!actually_updating) {
- + /* Don't really update; Just increase the frame counter.
- + * If we tried to update it may have not worked so well
- + * with VSync...
- + * (Think of 60Hz on the host with 70Hz on the client.)
- + */
- + sdl.opengl.actual_frame_count++;
- + return;
- + }
- glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- if (sdl.opengl.pixel_buffer_object) {
- @@ -1086,8 +1355,6 @@
- sdl.draw.width, sdl.draw.height, GL_BGRA_EXT,
- GL_UNSIGNED_INT_8_8_8_8_REV, 0);
- glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
- - glCallList(sdl.opengl.displaylist);
- - SDL_GL_SwapBuffers();
- } else if (changedLines) {
- Bitu y = 0, index = 0;
- glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
- @@ -1104,9 +1371,14 @@
- }
- index++;
- }
- - glCallList(sdl.opengl.displaylist);
- - SDL_GL_SwapBuffers();
- - }
- + } else
- + return;
- +
- + if (sdl.opengl.program_object) {
- + glUniform1i(sdl.opengl.ruby.frame_count, sdl.opengl.actual_frame_count++);
- + glDrawArrays(GL_TRIANGLES, 0, 3);
- + } else glCallList(sdl.opengl.displaylist);
- + SDL_GL_SwapBuffers();
- break;
- #endif
- default:
- @@ -1430,6 +1702,31 @@
- LOG_MSG("Could not initialize OpenGL, switching back to surface");
- sdl.desktop.want_type = SCREEN_SURFACE;
- } else {
- + sdl.opengl.program_object = 0;
- + glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader");
- + glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
- + glCreateProgram = (PFNGLCREATEPROGRAMPROC)SDL_GL_GetProcAddress("glCreateProgram");
- + glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader");
- + glDeleteProgram = (PFNGLDELETEPROGRAMPROC)SDL_GL_GetProcAddress("glDeleteProgram");
- + glDeleteShader = (PFNGLDELETESHADERPROC)SDL_GL_GetProcAddress("glDeleteShader");
- + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)SDL_GL_GetProcAddress("glEnableVertexAttribArray");
- + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)SDL_GL_GetProcAddress("glGetAttribLocation");
- + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)SDL_GL_GetProcAddress("glGetProgramiv");
- + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog");
- + glGetShaderiv = (PFNGLGETSHADERIVPROC)SDL_GL_GetProcAddress("glGetShaderiv");
- + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)SDL_GL_GetProcAddress("glGetShaderInfoLog");
- + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)SDL_GL_GetProcAddress("glGetUniformLocation");
- + glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram");
- + glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource");
- + glUniform2f = (PFNGLUNIFORM2FPROC)SDL_GL_GetProcAddress("glUniform2f");
- + glUniform1i = (PFNGLUNIFORM1IPROC)SDL_GL_GetProcAddress("glUniform1i");
- + glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
- + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)SDL_GL_GetProcAddress("glVertexAttribPointer");
- + sdl.opengl.use_shader = (glAttachShader && glCompileShader && glCreateProgram && glDeleteProgram && glDeleteShader && \
- + glEnableVertexAttribArray && glGetAttribLocation && glGetProgramiv && glGetProgramInfoLog && \
- + glGetShaderiv && glGetShaderInfoLog && glGetUniformLocation && glLinkProgram && glShaderSource && \
- + glUniform2f && glUniform1i && glUseProgram && glVertexAttribPointer);
- +
- sdl.opengl.buffer=0;
- sdl.opengl.framebuf=0;
- sdl.opengl.texture=0;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement