mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-24 17:49:52 +01:00
preliminary libretro GLSL shader support https://github.com/libretro/glsl-shaders
This commit is contained in:
parent
0e511f1a7d
commit
87450e320f
@ -90,6 +90,7 @@ typedef struct IDirectDrawImpl
|
|||||||
BOOL maintas;
|
BOOL maintas;
|
||||||
BOOL fakecursorpos;
|
BOOL fakecursorpos;
|
||||||
BOOL noactivateapp;
|
BOOL noactivateapp;
|
||||||
|
char shader[MAX_PATH];
|
||||||
|
|
||||||
} IDirectDrawImpl;
|
} IDirectDrawImpl;
|
||||||
|
|
||||||
|
12
inc/opengl.h
12
inc/opengl.h
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
void OpenGL_Init();
|
void OpenGL_Init();
|
||||||
BOOL OpenGL_ExtExists(char *ext);
|
BOOL OpenGL_ExtExists(char *ext);
|
||||||
GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource);
|
GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource);
|
||||||
|
GLuint OpenGL_BuildProgramFromFile(const char *filePath);
|
||||||
|
|
||||||
// Program
|
// Program
|
||||||
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||||
@ -27,6 +28,7 @@ extern PFNGLUNIFORM1FVPROC glUniform1fv;
|
|||||||
extern PFNGLUNIFORM2FVPROC glUniform2fv;
|
extern PFNGLUNIFORM2FVPROC glUniform2fv;
|
||||||
extern PFNGLUNIFORM3FVPROC glUniform3fv;
|
extern PFNGLUNIFORM3FVPROC glUniform3fv;
|
||||||
extern PFNGLUNIFORM4FVPROC glUniform4fv;
|
extern PFNGLUNIFORM4FVPROC glUniform4fv;
|
||||||
|
extern PFNGLUNIFORM4FPROC glUniform4f;
|
||||||
extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||||
extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
|
||||||
extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f;
|
extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f;
|
||||||
@ -51,6 +53,7 @@ extern PFNGLGENBUFFERSPROC glGenBuffers;
|
|||||||
extern PFNGLBINDBUFFERPROC glBindBuffer;
|
extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||||
extern PFNGLBUFFERDATAPROC glBufferData;
|
extern PFNGLBUFFERDATAPROC glBufferData;
|
||||||
extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||||
|
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||||
|
|
||||||
extern PFNGLGENBUFFERSARBPROC glGenBuffersARB;
|
extern PFNGLGENBUFFERSARBPROC glGenBuffersARB;
|
||||||
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
|
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
|
||||||
@ -62,3 +65,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
|
|||||||
extern PFNGLACTIVETEXTUREARBPROC glActiveTexture;
|
extern PFNGLACTIVETEXTUREARBPROC glActiveTexture;
|
||||||
extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
|
extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
|
||||||
extern PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f;
|
extern PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f;
|
||||||
|
|
||||||
|
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||||
|
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||||
|
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||||
|
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||||
|
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||||
|
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||||
|
@ -978,7 +978,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
|
|||||||
"adjmouse=false\n"
|
"adjmouse=false\n"
|
||||||
"; enable C&C video resize hack, auto = auto-detect game, true = forced, false = disabled\n"
|
"; enable C&C video resize hack, auto = auto-detect game, true = forced, false = disabled\n"
|
||||||
"vhack=false\n"
|
"vhack=false\n"
|
||||||
"; switch between OpenGL (opengl) and software (gdi) renderers, latter supports less features but might be faster depending on the GPU\n"
|
"; switch between OpenGL (opengl) and software (gdi) renderers\n"
|
||||||
"renderer=gdi\n"
|
"renderer=gdi\n"
|
||||||
"; force CPU0 affinity, avoids crashes with RA, *might* have a performance impact\n"
|
"; force CPU0 affinity, avoids crashes with RA, *might* have a performance impact\n"
|
||||||
"singlecpu=true\n"
|
"singlecpu=true\n"
|
||||||
@ -1146,6 +1146,9 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
|
|||||||
This->renderer = render_main;
|
This->renderer = render_main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to do: read .glslp config file instead of the shader and apply the correct settings
|
||||||
|
GetPrivateProfileStringA("ddraw", "shader", "", This->shader, sizeof(This->shader), SettingsIniPath);
|
||||||
|
|
||||||
GetPrivateProfileStringA("ddraw", "singlecpu", "true", tmp, sizeof(tmp), SettingsIniPath);
|
GetPrivateProfileStringA("ddraw", "singlecpu", "true", tmp, sizeof(tmp), SettingsIniPath);
|
||||||
if (tolower(tmp[0]) == 'y' || tolower(tmp[0]) == 't' || tolower(tmp[0]) == 'e' || tmp[0] == '1')
|
if (tolower(tmp[0]) == 'y' || tolower(tmp[0]) == 't' || tolower(tmp[0]) == 'e' || tmp[0] == '1')
|
||||||
{
|
{
|
||||||
|
54
src/opengl.c
54
src/opengl.c
@ -23,6 +23,7 @@ PFNGLUNIFORM1FVPROC glUniform1fv = NULL;
|
|||||||
PFNGLUNIFORM2FVPROC glUniform2fv = NULL;
|
PFNGLUNIFORM2FVPROC glUniform2fv = NULL;
|
||||||
PFNGLUNIFORM3FVPROC glUniform3fv = NULL;
|
PFNGLUNIFORM3FVPROC glUniform3fv = NULL;
|
||||||
PFNGLUNIFORM4FVPROC glUniform4fv = NULL;
|
PFNGLUNIFORM4FVPROC glUniform4fv = NULL;
|
||||||
|
PFNGLUNIFORM4FPROC glUniform4f = NULL;
|
||||||
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL;
|
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL;
|
||||||
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
|
PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
|
||||||
PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL;
|
PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL;
|
||||||
@ -47,6 +48,7 @@ PFNGLGENBUFFERSPROC glGenBuffers = NULL;
|
|||||||
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
|
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
|
||||||
PFNGLBUFFERDATAPROC glBufferData = NULL;
|
PFNGLBUFFERDATAPROC glBufferData = NULL;
|
||||||
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
|
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
|
||||||
|
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;
|
||||||
|
|
||||||
PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
|
PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
|
||||||
PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
|
PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
|
||||||
@ -59,6 +61,13 @@ PFNGLACTIVETEXTUREARBPROC glActiveTexture = NULL;
|
|||||||
PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture = NULL;
|
PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture = NULL;
|
||||||
PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f = NULL;
|
PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f = NULL;
|
||||||
|
|
||||||
|
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL;
|
||||||
|
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL;
|
||||||
|
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL;
|
||||||
|
PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL;
|
||||||
|
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL;
|
||||||
|
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL;
|
||||||
|
|
||||||
void OpenGL_Init()
|
void OpenGL_Init()
|
||||||
{
|
{
|
||||||
// Program
|
// Program
|
||||||
@ -81,6 +90,7 @@ void OpenGL_Init()
|
|||||||
glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv");
|
glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv");
|
||||||
glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv");
|
glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv");
|
||||||
glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv");
|
glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv");
|
||||||
|
glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f");
|
||||||
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
|
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv");
|
||||||
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
|
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
|
||||||
glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)wglGetProcAddress("glVertexAttrib1f");
|
glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)wglGetProcAddress("glVertexAttrib1f");
|
||||||
@ -103,6 +113,7 @@ void OpenGL_Init()
|
|||||||
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
|
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
|
||||||
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
|
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
|
||||||
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
|
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
|
||||||
|
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
|
||||||
|
|
||||||
glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
|
glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
|
||||||
glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
|
glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
|
||||||
@ -114,6 +125,13 @@ void OpenGL_Init()
|
|||||||
glActiveTexture = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTexture");
|
glActiveTexture = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTexture");
|
||||||
glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)wglGetProcAddress("glClientActiveTexture");
|
glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)wglGetProcAddress("glClientActiveTexture");
|
||||||
glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)wglGetProcAddress("glMultiTexCoord2f");
|
glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)wglGetProcAddress("glMultiTexCoord2f");
|
||||||
|
|
||||||
|
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers");
|
||||||
|
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer");
|
||||||
|
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D");
|
||||||
|
glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffers");
|
||||||
|
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus");
|
||||||
|
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL OpenGL_ExtExists(char *ext)
|
BOOL OpenGL_ExtExists(char *ext)
|
||||||
@ -127,7 +145,7 @@ BOOL OpenGL_ExtExists(char *ext)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource)
|
GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource)
|
||||||
{
|
{
|
||||||
if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram ||
|
if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram ||
|
||||||
!glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader)
|
!glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader)
|
||||||
@ -139,8 +157,11 @@ GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource)
|
|||||||
if (!vertShader || !fragShader)
|
if (!vertShader || !fragShader)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
glShaderSource(vertShader, 1, vertSource, NULL);
|
const GLchar *vertSrc[2] = { "#define VERTEX\n", vertSource };
|
||||||
glShaderSource(fragShader, 1, fragSource, NULL);
|
const GLchar *fragSrc[2] = { "#define FRAGMENT\n", fragSource };
|
||||||
|
|
||||||
|
glShaderSource(vertShader, 2, vertSrc, NULL);
|
||||||
|
glShaderSource(fragShader, 2, fragSrc, NULL);
|
||||||
|
|
||||||
GLint isCompiled = 0;
|
GLint isCompiled = 0;
|
||||||
|
|
||||||
@ -199,3 +220,30 @@ GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource)
|
|||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint OpenGL_BuildProgramFromFile(const char *filePath)
|
||||||
|
{
|
||||||
|
GLuint program = 0;
|
||||||
|
|
||||||
|
FILE *file = fopen(filePath, "rb");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
long fileSize = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
char *source = malloc(fileSize + 1);
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
fread(source, fileSize, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
source[fileSize] = 0;
|
||||||
|
|
||||||
|
program = OpenGL_BuildProgram(source, source);
|
||||||
|
free(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
239
src/render.c
239
src/render.c
@ -21,7 +21,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "surface.h"
|
#include "surface.h"
|
||||||
|
|
||||||
const GLchar *PaletteVertShaderSrc =
|
const GLchar *PassthroughVertShaderSrc =
|
||||||
"//Vertex shader\n"
|
"//Vertex shader\n"
|
||||||
"#version 110\n"
|
"#version 110\n"
|
||||||
"varying vec2 TexCoord0; \n"
|
"varying vec2 TexCoord0; \n"
|
||||||
@ -80,6 +80,9 @@ DWORD WINAPI render_main(void)
|
|||||||
if (ddraw->render.maxfps == 0)
|
if (ddraw->render.maxfps == 0)
|
||||||
ddraw->render.maxfps = 125;
|
ddraw->render.maxfps = 125;
|
||||||
|
|
||||||
|
if (ddraw->render.maxfps >= 1000)
|
||||||
|
ddraw->render.maxfps = 0;
|
||||||
|
|
||||||
if (ddraw->render.maxfps > 0)
|
if (ddraw->render.maxfps > 0)
|
||||||
frame_len = 1000.0f / ddraw->render.maxfps;
|
frame_len = 1000.0f / ddraw->render.maxfps;
|
||||||
|
|
||||||
@ -90,7 +93,14 @@ DWORD WINAPI render_main(void)
|
|||||||
|
|
||||||
GLuint paletteConvProgram = 0;
|
GLuint paletteConvProgram = 0;
|
||||||
if (glGetUniformLocation && glActiveTexture && glUniform1i)
|
if (glGetUniformLocation && glActiveTexture && glUniform1i)
|
||||||
paletteConvProgram = OpenGL_BuildProgram(&PaletteVertShaderSrc, &PaletteFragShaderSrc);
|
paletteConvProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PaletteFragShaderSrc);
|
||||||
|
|
||||||
|
GLuint scaleProgram = 0;
|
||||||
|
if (glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D && glDrawBuffers &&
|
||||||
|
glCheckFramebufferStatus && glUniform4f && glActiveTexture && glUniform1i &&
|
||||||
|
glGetAttribLocation && glGenBuffers && glBindBuffer && glBufferData && glVertexAttribPointer &&
|
||||||
|
glEnableVertexAttribArray && glUniform2fv && glUniformMatrix4fv)
|
||||||
|
scaleProgram = OpenGL_BuildProgramFromFile(ddraw->shader);
|
||||||
|
|
||||||
// primary surface texture
|
// primary surface texture
|
||||||
GLuint surfaceTexId = 0;
|
GLuint surfaceTexId = 0;
|
||||||
@ -125,22 +135,122 @@ DWORD WINAPI render_main(void)
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
while (glGetError() != GL_NO_ERROR);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
if (glGetError() != GL_NO_ERROR)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
glViewport(
|
glViewport(
|
||||||
ddraw->render.viewport.x, ddraw->render.viewport.y,
|
ddraw->render.viewport.x, ddraw->render.viewport.y,
|
||||||
ddraw->render.viewport.width, ddraw->render.viewport.height);
|
ddraw->render.viewport.width, ddraw->render.viewport.height);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
GLint surfaceUniLoc = 0, paletteUniLoc = 0;
|
GLint surfaceUniLoc = 0, paletteUniLoc = 0;
|
||||||
if (paletteConvProgram)
|
if (paletteConvProgram)
|
||||||
{
|
{
|
||||||
glUseProgram(paletteConvProgram);
|
|
||||||
surfaceUniLoc = glGetUniformLocation(paletteConvProgram, "SurfaceTex");
|
surfaceUniLoc = glGetUniformLocation(paletteConvProgram, "SurfaceTex");
|
||||||
paletteUniLoc = glGetUniformLocation(paletteConvProgram, "PaletteTex");
|
paletteUniLoc = glGetUniformLocation(paletteConvProgram, "PaletteTex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLint textureUniLoc = -1, texCoordUniLoc = -1, frameCountUniLoc = -1;
|
||||||
|
GLuint frameBufferId = 0;
|
||||||
|
GLuint frameBufferTexId = 0;
|
||||||
|
GLuint vboBuffers[3];
|
||||||
|
|
||||||
|
if (scaleProgram)
|
||||||
|
{
|
||||||
|
glUseProgram(scaleProgram);
|
||||||
|
|
||||||
|
GLint vertexCoordUniLoc = glGetAttribLocation(scaleProgram, "VertexCoord");
|
||||||
|
texCoordUniLoc = glGetAttribLocation(scaleProgram, "TexCoord");
|
||||||
|
textureUniLoc = glGetUniformLocation(scaleProgram, "Texture");
|
||||||
|
frameCountUniLoc = glGetUniformLocation(scaleProgram, "FrameCount");
|
||||||
|
|
||||||
|
glGenBuffers(3, vboBuffers);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vboBuffers[0]);
|
||||||
|
static const GLfloat vertexCoord[] = {
|
||||||
|
-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f,
|
||||||
|
1.0f,-1.0f,
|
||||||
|
-1.0f,-1.0f,
|
||||||
|
};
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(vertexCoordUniLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||||
|
glEnableVertexAttribArray(vertexCoordUniLoc);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboBuffers[2]);
|
||||||
|
static const GLushort indices[] =
|
||||||
|
{
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
};
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
float inputSize[2], outputSize[2], textureSize[2];
|
||||||
|
|
||||||
|
inputSize[0] = ddraw->width;
|
||||||
|
inputSize[1] = ddraw->height;
|
||||||
|
textureSize[0] = tex_width;
|
||||||
|
textureSize[1] = tex_height;
|
||||||
|
outputSize[0] = ddraw->render.viewport.width;
|
||||||
|
outputSize[1] = ddraw->render.viewport.height;
|
||||||
|
|
||||||
|
glUniform2fv(glGetUniformLocation(scaleProgram, "OutputSize"), 1, outputSize);
|
||||||
|
glUniform2fv(glGetUniformLocation(scaleProgram, "TextureSize"), 1, textureSize);
|
||||||
|
glUniform2fv(glGetUniformLocation(scaleProgram, "InputSize"), 1, inputSize);
|
||||||
|
|
||||||
|
glUniform4f(glGetAttribLocation(scaleProgram, "Color"), 1, 1, 1, 1);
|
||||||
|
glUniform1i(glGetUniformLocation(scaleProgram, "FrameDirection"), 1);
|
||||||
|
|
||||||
|
const float mvpMatrix[16] = {
|
||||||
|
1,0,0,0,
|
||||||
|
0,1,0,0,
|
||||||
|
0,0,1,0,
|
||||||
|
0,0,0,1,
|
||||||
|
};
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(scaleProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix);
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &frameBufferId);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
|
||||||
|
|
||||||
|
glGenTextures(1, &frameBufferTexId);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, frameBufferTexId);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexId, 0);
|
||||||
|
|
||||||
|
GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
|
||||||
|
glDrawBuffers(1, drawBuffers);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &frameBufferTexId);
|
||||||
|
|
||||||
|
if (glDeleteFramebuffers)
|
||||||
|
glDeleteFramebuffers(1, &frameBufferId);
|
||||||
|
|
||||||
|
if (glDeleteProgram)
|
||||||
|
glDeleteProgram(scaleProgram);
|
||||||
|
|
||||||
|
scaleProgram = 0;
|
||||||
|
|
||||||
|
if (glDeleteBuffers)
|
||||||
|
glDeleteBuffers(3, vboBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
||||||
@ -164,19 +274,6 @@ DWORD WINAPI render_main(void)
|
|||||||
if (ddraw->render.maxfps > 0)
|
if (ddraw->render.maxfps > 0)
|
||||||
tick_start = timeGetTime();
|
tick_start = timeGetTime();
|
||||||
|
|
||||||
if (paletteConvProgram)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, paletteTexId);
|
|
||||||
glUniform1i(paletteUniLoc, 0);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, surfaceTexId);
|
|
||||||
glUniform1i(surfaceUniLoc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection(&ddraw->cs);
|
EnterCriticalSection(&ddraw->cs);
|
||||||
|
|
||||||
if (ddraw->primary && ddraw->primary->palette)
|
if (ddraw->primary && ddraw->primary->palette)
|
||||||
@ -230,12 +327,90 @@ DWORD WINAPI render_main(void)
|
|||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ddraw->width, ddraw->height, GL_RGBA, GL_UNSIGNED_BYTE, tex);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ddraw->width, ddraw->height, GL_RGBA, GL_UNSIGNED_BYTE, tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
if (paletteConvProgram)
|
||||||
glTexCoord2f(0, 0); glVertex2f(-1, 1);
|
{
|
||||||
glTexCoord2f(scale_w, 0); glVertex2f(1, 1);
|
glUseProgram(paletteConvProgram);
|
||||||
glTexCoord2f(scale_w, scale_h); glVertex2f(1, -1);
|
|
||||||
glTexCoord2f(0, scale_h); glVertex2f(-1, -1);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnd();
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, paletteTexId);
|
||||||
|
glUniform1i(paletteUniLoc, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, surfaceTexId);
|
||||||
|
glUniform1i(surfaceUniLoc, 1);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scaleProgram)
|
||||||
|
{
|
||||||
|
// draw surface into framebuffer
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
|
||||||
|
|
||||||
|
glPushAttrib(GL_VIEWPORT_BIT);
|
||||||
|
glViewport(0, 0, tex_width, tex_height);
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
|
glTexCoord2f(0, 0); glVertex2f(-1, -1);
|
||||||
|
glTexCoord2f(0, 1); glVertex2f(-1, 1);
|
||||||
|
glTexCoord2f(1, 1); glVertex2f(1, 1);
|
||||||
|
glTexCoord2f(1, 0); glVertex2f(1, -1);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
// apply filter
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vboBuffers[1]);
|
||||||
|
|
||||||
|
GLfloat texCoord[] = {
|
||||||
|
0.0f, 0.0f,
|
||||||
|
scale_w, 0.0f,
|
||||||
|
scale_w, scale_h,
|
||||||
|
0, scale_h,
|
||||||
|
};
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(texCoordUniLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||||
|
glEnableVertexAttribArray(texCoordUniLoc);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboBuffers[2]);
|
||||||
|
|
||||||
|
glUseProgram(scaleProgram);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, frameBufferTexId);
|
||||||
|
glUniform1i(textureUniLoc, 0);
|
||||||
|
|
||||||
|
static int frames = 1;
|
||||||
|
if (frameCountUniLoc != -1)
|
||||||
|
glUniform1i(frameCountUniLoc, frames++);
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
|
glTexCoord2f(0, 0); glVertex2f(-1, 1);
|
||||||
|
glTexCoord2f(scale_w, 0); glVertex2f(1, 1);
|
||||||
|
glTexCoord2f(scale_w, scale_h); glVertex2f(1, -1);
|
||||||
|
glTexCoord2f(0, scale_h); glVertex2f(-1, -1);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scaleProgram && !paletteConvProgram)
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
@ -253,14 +428,28 @@ DWORD WINAPI render_main(void)
|
|||||||
HeapFree(GetProcessHeap(), 0, tex);
|
HeapFree(GetProcessHeap(), 0, tex);
|
||||||
glDeleteTextures(1, &surfaceTexId);
|
glDeleteTextures(1, &surfaceTexId);
|
||||||
glDeleteTextures(1, &paletteTexId);
|
glDeleteTextures(1, &paletteTexId);
|
||||||
|
|
||||||
if (glUseProgram)
|
if (glUseProgram)
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
|
if (scaleProgram)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &frameBufferTexId);
|
||||||
|
|
||||||
|
if (glDeleteBuffers)
|
||||||
|
glDeleteBuffers(3, vboBuffers);
|
||||||
|
|
||||||
|
if (glDeleteFramebuffers)
|
||||||
|
glDeleteFramebuffers(1, &frameBufferId);
|
||||||
|
}
|
||||||
|
|
||||||
if (glDeleteProgram)
|
if (glDeleteProgram)
|
||||||
{
|
{
|
||||||
if (paletteConvProgram)
|
if (paletteConvProgram)
|
||||||
glDeleteProgram(paletteConvProgram);
|
glDeleteProgram(paletteConvProgram);
|
||||||
|
|
||||||
|
if (scaleProgram)
|
||||||
|
glDeleteProgram(scaleProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
wglMakeCurrent(NULL, NULL);
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
@ -72,14 +72,13 @@ DWORD WINAPI render_soft_main(void)
|
|||||||
DWORD frame_len = 0;
|
DWORD frame_len = 0;
|
||||||
|
|
||||||
if(ddraw->render.maxfps < 0)
|
if(ddraw->render.maxfps < 0)
|
||||||
{
|
|
||||||
ddraw->render.maxfps = ddraw->mode.dmDisplayFrequency;
|
ddraw->render.maxfps = ddraw->mode.dmDisplayFrequency;
|
||||||
}
|
|
||||||
|
if (ddraw->render.maxfps >= 1000)
|
||||||
|
ddraw->render.maxfps = 0;
|
||||||
|
|
||||||
if(ddraw->render.maxfps > 0)
|
if(ddraw->render.maxfps > 0)
|
||||||
{
|
|
||||||
frame_len = 1000.0f / ddraw->render.maxfps;
|
frame_len = 1000.0f / ddraw->render.maxfps;
|
||||||
}
|
|
||||||
|
|
||||||
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user