1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-23 17:02:26 +01:00
cnc-ddraw/src/render.c

661 lines
22 KiB
C
Raw Normal View History

2010-11-06 08:28:11 +02:00
/*
* Copyright (c) 2010 Toni Spets <toni.spets@iki.fi>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
2010-11-06 08:28:11 +02:00
2010-11-06 08:28:11 +02:00
#include <windows.h>
#include <stdio.h>
#include "opengl.h"
2010-11-06 08:28:11 +02:00
#include "main.h"
#include "surface.h"
2018-05-20 06:27:53 +02:00
#include "paletteshader.h"
2011-03-24 19:41:36 +02:00
BOOL detect_cutscene();
2018-05-18 16:18:34 +02:00
DWORD WINAPI render_soft_main(void);
2011-03-24 19:41:36 +02:00
2010-11-13 10:49:46 +02:00
DWORD WINAPI render_main(void)
2010-11-06 08:28:11 +02:00
{
2018-05-10 14:45:39 +02:00
Sleep(500);
HGLRC hRC = wglCreateContext(ddraw->render.hDC);
2018-05-18 16:18:34 +02:00
BOOL madeCurrent = hRC && wglMakeCurrent(ddraw->render.hDC, hRC);
if (!madeCurrent || (ddraw->autorenderer && glGetError() != GL_NO_ERROR))
{
if (madeCurrent)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
}
ddraw->renderer = render_soft_main;
return render_soft_main();
}
2010-11-06 08:28:11 +02:00
OpenGL_Init();
if (OpenGL_ExtExists("WGL_EXT_swap_control"))
{
BOOL(APIENTRY *wglSwapIntervalEXT)(int) = (BOOL(APIENTRY *)(int))wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT)
{
if (ddraw->vsync)
wglSwapIntervalEXT(1);
else
wglSwapIntervalEXT(0);
}
}
2010-12-11 18:58:58 +02:00
DWORD tick_start = 0;
DWORD tick_end = 0;
DWORD frame_len = 0;
2018-05-18 16:18:34 +02:00
int maxfps = ddraw->render.maxfps;
2010-11-06 21:30:48 +02:00
2018-05-18 16:18:34 +02:00
if (maxfps < 0)
maxfps = ddraw->mode.dmDisplayFrequency;
2010-11-06 21:30:48 +02:00
2018-05-18 16:18:34 +02:00
if (maxfps == 0)
maxfps = 125;
2018-05-18 16:18:34 +02:00
if (maxfps >= 1000)
maxfps = 0;
2018-05-18 16:18:34 +02:00
if (maxfps > 0)
frame_len = 1000.0f / maxfps;
2010-11-06 08:28:11 +02:00
int tex_width =
ddraw->width <= 1024 ? 1024 : ddraw->width <= 2048 ? 2048 : ddraw->width <= 4096 ? 4096 : ddraw->width;
int tex_height =
ddraw->height <= tex_width ? tex_width : ddraw->height <= 2048 ? 2048 : ddraw->height <= 4096 ? 4096 : ddraw->height;
tex_width = tex_width > tex_height ? tex_width : tex_height;
2018-05-20 07:06:32 +02:00
float scale_w = (float)ddraw->width / tex_width;
float scale_h = (float)ddraw->height / tex_height;
int tex_size = tex_width * tex_height * sizeof(int);
int *tex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, tex_size);
2018-05-20 06:27:53 +02:00
BOOL got30 = glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D && glDrawBuffers &&
glCheckFramebufferStatus && glUniform4f && glActiveTexture && glUniform1i &&
glGetAttribLocation && glGenBuffers && glBindBuffer && glBufferData && glVertexAttribPointer &&
glEnableVertexAttribArray && glUniform2fv && glUniformMatrix4fv && glGenVertexArrays && glBindVertexArray;
BOOL got20 = glGetUniformLocation && glActiveTexture && glUniform1i;
GLuint paletteConvProgram = 0;
2018-05-20 06:27:53 +02:00
if (got30)
paletteConvProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PaletteFragShaderSrc);
2018-05-20 06:27:53 +02:00
else if (got20)
paletteConvProgram = OpenGL_BuildProgram(PassthroughVertShader110Src, PaletteFragShader110Src);
GLuint scaleProgram = 0;
2018-05-20 06:27:53 +02:00
if (got30)
scaleProgram = OpenGL_BuildProgramFromFile(ddraw->shader);
// primary surface texture
2018-05-09 05:56:44 +02:00
GLuint surfaceTexId = 0;
glGenTextures(1, &surfaceTexId);
glBindTexture(GL_TEXTURE_2D, surfaceTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
while (glGetError() != GL_NO_ERROR);
2018-05-09 05:56:44 +02:00
if (paletteConvProgram)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, tex_width, tex_height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
if (glGetError() != GL_NO_ERROR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, tex_width, tex_height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
2018-05-14 10:35:30 +02:00
if (glGetError() != GL_NO_ERROR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_width, tex_height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
}
else
{
2018-05-14 10:35:30 +02:00
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
// palette texture
2018-05-09 05:56:44 +02:00
GLuint paletteTexId = 0;
glGenTextures(1, &paletteTexId);
glBindTexture(GL_TEXTURE_2D, paletteTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glViewport(
ddraw->render.viewport.x, ddraw->render.viewport.y,
ddraw->render.viewport.width, ddraw->render.viewport.height);
2018-05-20 06:27:53 +02:00
GLint surfaceUniLoc = -1, paletteUniLoc = -1, mainTexCoordAttrLoc = -1;
GLuint mainVbos[3], mainVao;
2018-05-09 05:56:44 +02:00
if (paletteConvProgram)
2017-11-16 22:21:13 +01:00
{
2018-05-09 05:56:44 +02:00
surfaceUniLoc = glGetUniformLocation(paletteConvProgram, "SurfaceTex");
paletteUniLoc = glGetUniformLocation(paletteConvProgram, "PaletteTex");
2018-05-20 06:27:53 +02:00
if (got30)
{
glUseProgram(paletteConvProgram);
GLint vertexCoordAttrLoc = glGetAttribLocation(paletteConvProgram, "VertexCoord");
mainTexCoordAttrLoc = glGetAttribLocation(paletteConvProgram, "TexCoord");
glGenBuffers(3, mainVbos);
if (scaleProgram)
{
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[0]);
2018-05-20 07:06:32 +02:00
static const GLfloat vertexCoord[] = {
2018-05-20 06:27:53 +02:00
-1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
1.0f, -1.0f,
};
2018-05-20 07:06:32 +02:00
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[1]);
GLfloat texCoord[] = {
0.0f, 0.0f,
0.0f, scale_h,
scale_w, scale_h,
scale_w, 0.0f,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 06:27:53 +02:00
}
else
{
2018-05-20 07:06:32 +02:00
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[0]);
2018-05-20 06:27:53 +02:00
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);
2018-05-20 07:06:32 +02:00
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[1]);
GLfloat texCoord[] = {
0.0f, 0.0f,
scale_w, 0.0f,
scale_w, scale_h,
0.0f, scale_h,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 06:27:53 +02:00
}
2018-05-20 07:06:32 +02:00
2018-05-20 06:27:53 +02:00
glGenVertexArrays(1, &mainVao);
glBindVertexArray(mainVao);
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[0]);
glVertexAttribPointer(vertexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(vertexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 07:06:32 +02:00
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[1]);
glVertexAttribPointer(mainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(mainTexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 06:27:53 +02:00
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mainVbos[2]);
static const GLushort indices[] =
{
0, 1, 2,
0, 2, 3,
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUniform4f(glGetAttribLocation(paletteConvProgram, "Color"), 1, 1, 1, 1);
const float mvpMatrix[16] = {
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1,
};
glUniformMatrix4fv(glGetUniformLocation(paletteConvProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix);
}
2017-11-16 22:21:13 +01:00
}
2018-05-20 06:27:53 +02:00
GLint textureUniLoc = -1, scaleTexCoordAttrLoc = -1, frameCountUniLoc = -1;
GLuint frameBufferId = 0;
GLuint frameBufferTexId = 0;
2018-05-20 06:27:53 +02:00
GLuint scaleVbos[3], scaleVao;
if (scaleProgram)
{
glUseProgram(scaleProgram);
GLint vertexCoordAttrLoc = glGetAttribLocation(scaleProgram, "VertexCoord");
2018-05-20 06:27:53 +02:00
scaleTexCoordAttrLoc = glGetAttribLocation(scaleProgram, "TexCoord");
textureUniLoc = glGetUniformLocation(scaleProgram, "Texture");
frameCountUniLoc = glGetUniformLocation(scaleProgram, "FrameCount");
2018-05-20 06:27:53 +02:00
glGenBuffers(3, scaleVbos);
2018-05-20 06:27:53 +02:00
glBindBuffer(GL_ARRAY_BUFFER, scaleVbos[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);
2018-05-20 06:27:53 +02:00
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 07:06:32 +02:00
glBindBuffer(GL_ARRAY_BUFFER, scaleVbos[1]);
GLfloat texCoord[] = {
0.0f, 0.0f,
scale_w, 0.0f,
scale_w, scale_h,
0.0f, scale_h,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 06:27:53 +02:00
glGenVertexArrays(1, &scaleVao);
glBindVertexArray(scaleVao);
glBindBuffer(GL_ARRAY_BUFFER, scaleVbos[0]);
glVertexAttribPointer(vertexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(vertexCoordAttrLoc);
2018-05-20 06:27:53 +02:00
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 07:06:32 +02:00
glBindBuffer(GL_ARRAY_BUFFER, scaleVbos[1]);
glVertexAttribPointer(scaleTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(scaleTexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-05-20 06:27:53 +02:00
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, scaleVbos[2]);
static const GLushort indices[] =
{
0, 1, 2,
0, 2, 3,
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
2018-05-20 06:27:53 +02:00
glBindVertexArray(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);
2018-05-14 10:35:30 +02:00
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_width, tex_height, 0, GL_RGBA, 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)
2018-05-20 06:27:53 +02:00
glDeleteBuffers(3, scaleVbos);
if (glDeleteVertexArrays)
glDeleteVertexArrays(1, &scaleVao);
2018-05-20 07:45:51 +02:00
if (paletteConvProgram)
{
glBindVertexArray(mainVao);
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[1]);
GLfloat texCoord[] = {
0.0f, 0.0f,
scale_w, 0.0f,
scale_w, scale_h,
0.0f, scale_h,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glVertexAttribPointer(mainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(mainTexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
2018-05-18 16:18:34 +02:00
BOOL useOpenGL = !(ddraw->autorenderer && (!paletteConvProgram || glGetError() != GL_NO_ERROR));
while (useOpenGL && ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
2010-11-06 08:28:11 +02:00
{
2017-11-26 08:49:30 +01:00
#if _DEBUG
static DWORD tick_fps = 0;
static DWORD frame_count = 0;
tick_start = timeGetTime();
if (tick_start >= tick_fps)
{
printf("Frames: %lu - Elapsed: %lu ms\n", frame_count, (tick_start - tick_fps) + 1000);
frame_count = 0;
tick_fps = tick_start + 1000;
}
frame_count++;
#endif
2018-05-20 07:06:32 +02:00
scale_w = (float)ddraw->width / tex_width;
scale_h = (float)ddraw->height / tex_height;
2018-05-18 16:18:34 +02:00
if (maxfps > 0)
2017-11-12 01:27:14 +01:00
tick_start = timeGetTime();
2010-11-06 08:28:11 +02:00
EnterCriticalSection(&ddraw->cs);
if (ddraw->primary && ddraw->primary->palette)
2010-11-06 08:28:11 +02:00
{
2018-05-20 07:06:32 +02:00
BOOL scaleChanged = FALSE;
if (ddraw->vhack && detect_cutscene())
2011-03-24 19:41:36 +02:00
{
2011-04-02 21:37:04 +03:00
scale_w *= (float)CUTSCENE_WIDTH / ddraw->width;
scale_h *= (float)CUTSCENE_HEIGHT / ddraw->height;
2011-03-24 19:42:36 +02:00
2018-03-23 03:21:16 +01:00
if (!ddraw->incutscene)
2018-05-20 07:06:32 +02:00
{
scaleChanged = TRUE;
2018-03-23 03:21:16 +01:00
ddraw->incutscene = TRUE;
2018-05-20 07:06:32 +02:00
}
2011-03-24 19:42:36 +02:00
}
else
{
2018-03-23 03:21:16 +01:00
if (ddraw->incutscene)
2018-05-20 07:06:32 +02:00
{
scaleChanged = TRUE;
2018-03-23 03:21:16 +01:00
ddraw->incutscene = FALSE;
2018-05-20 07:06:32 +02:00
}
}
if (scaleChanged)
{
if (scaleProgram && paletteConvProgram)
{
glBindVertexArray(mainVao);
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[1]);
GLfloat texCoordPal[] = {
0.0f, 0.0f,
0.0f, scale_h,
scale_w, scale_h,
scale_w, 0.0f,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoordPal), texCoordPal, GL_STATIC_DRAW);
glVertexAttribPointer(mainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(mainTexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindVertexArray(scaleVao);
glBindBuffer(GL_ARRAY_BUFFER, scaleVbos[1]);
GLfloat texCoord[] = {
0.0f, 0.0f,
scale_w, 0.0f,
scale_w, scale_h,
0.0f, scale_h,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glVertexAttribPointer(scaleTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(scaleTexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
else if (got30 && paletteConvProgram)
{
glBindVertexArray(mainVao);
glBindBuffer(GL_ARRAY_BUFFER, mainVbos[1]);
GLfloat texCoord[] = {
0.0f, 0.0f,
scale_w, 0.0f,
scale_w, scale_h,
0.0f, scale_h,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glVertexAttribPointer(mainTexCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(mainTexCoordAttrLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
2011-03-24 19:41:36 +02:00
}
2018-05-09 05:56:44 +02:00
if (paletteConvProgram)
2017-11-16 22:21:13 +01:00
{
2018-05-09 05:56:44 +02:00
glBindTexture(GL_TEXTURE_2D, paletteTexId);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, ddraw->primary->palette->data_bgr);
2018-05-09 05:56:44 +02:00
glBindTexture(GL_TEXTURE_2D, surfaceTexId);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ddraw->width, ddraw->height, GL_RED, GL_UNSIGNED_BYTE, ddraw->primary->surface);
2017-11-16 22:21:13 +01:00
}
else
2010-11-06 08:28:11 +02:00
{
int i, j;
for (i = 0; i<ddraw->height; i++)
{
int i_dst = i*ddraw->width;
int i_src = i*ddraw->primary->lPitch;
for (j = 0; j<ddraw->width; j++)
2017-11-16 22:21:13 +01:00
{
tex[i_dst + j] =
ddraw->primary->palette->data_bgr[
((unsigned char *)ddraw->primary->surface)[i_src + j*ddraw->primary->lXPitch]];
2017-11-16 22:21:13 +01:00
}
}
2010-11-06 08:28:11 +02:00
}
}
LeaveCriticalSection(&ddraw->cs);
2010-11-06 08:28:11 +02:00
2018-05-09 05:56:44 +02:00
if (!paletteConvProgram)
2017-11-16 22:21:13 +01:00
{
2018-05-09 05:56:44 +02:00
glBindTexture(GL_TEXTURE_2D, surfaceTexId);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ddraw->width, ddraw->height, GL_RGBA, GL_UNSIGNED_BYTE, tex);
2017-11-16 22:21:13 +01:00
}
2010-11-06 08:28:11 +02:00
if (paletteConvProgram)
{
glUseProgram(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);
glActiveTexture(GL_TEXTURE0);
}
2018-05-20 06:27:53 +02:00
if (scaleProgram && paletteConvProgram)
{
// draw surface into framebuffer
2018-05-20 06:27:53 +02:00
glViewport(0, 0, ddraw->width, ddraw->height);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
2018-05-20 07:06:32 +02:00
glBindVertexArray(mainVao);
2018-05-20 06:27:53 +02:00
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
2018-05-20 07:06:32 +02:00
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
2018-05-20 06:27:53 +02:00
glViewport(
ddraw->render.viewport.x, ddraw->render.viewport.y,
ddraw->render.viewport.width, ddraw->render.viewport.height);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
// apply filter
2018-05-20 06:27:53 +02:00
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++);
2018-05-20 07:06:32 +02:00
glBindVertexArray(scaleVao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
2018-05-20 06:27:53 +02:00
glBindVertexArray(0);
}
else if (got30 && paletteConvProgram)
{
glBindVertexArray(mainVao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(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);
2017-11-16 22:21:13 +01:00
glBindTexture(GL_TEXTURE_2D, 0);
2017-11-16 22:21:13 +01:00
SwapBuffers(ddraw->render.hDC);
2018-05-18 16:18:34 +02:00
if (maxfps > 0)
{
tick_end = timeGetTime();
if (tick_end - tick_start < frame_len)
Sleep(frame_len - (tick_end - tick_start));
2010-11-06 08:28:11 +02:00
}
}
HeapFree(GetProcessHeap(), 0, tex);
2018-05-09 05:56:44 +02:00
glDeleteTextures(1, &surfaceTexId);
glDeleteTextures(1, &paletteTexId);
2018-05-09 05:56:44 +02:00
if (glUseProgram)
glUseProgram(0);
2018-05-09 05:41:58 +02:00
if (scaleProgram)
{
glDeleteTextures(1, &frameBufferTexId);
if (glDeleteBuffers)
2018-05-20 06:27:53 +02:00
glDeleteBuffers(3, scaleVbos);
if (glDeleteFramebuffers)
glDeleteFramebuffers(1, &frameBufferId);
2018-05-20 06:27:53 +02:00
if (glDeleteVertexArrays)
glDeleteVertexArrays(1, &scaleVao);
}
2018-05-09 05:56:44 +02:00
if (glDeleteProgram)
{
if (paletteConvProgram)
glDeleteProgram(paletteConvProgram);
if (scaleProgram)
glDeleteProgram(scaleProgram);
2018-05-09 05:56:44 +02:00
}
2018-05-20 06:27:53 +02:00
if (got30)
{
if (paletteConvProgram)
{
if (glDeleteBuffers)
glDeleteBuffers(3, mainVbos);
if (glDeleteVertexArrays)
glDeleteVertexArrays(1, &mainVao);
}
}
2018-05-09 05:56:44 +02:00
2010-11-06 08:28:11 +02:00
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
2018-05-18 16:18:34 +02:00
if (!useOpenGL)
{
ddraw->renderer = render_soft_main;
render_soft_main();
}
2010-11-06 08:28:11 +02:00
return 0;
}