summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/client.txt7
-rw-r--r--src/refresh/gl/gl.h1
-rw-r--r--src/refresh/gl/hq2x.c405
-rw-r--r--src/refresh/gl/images.c38
-rw-r--r--src/refresh/gl/tess.c2
5 files changed, 358 insertions, 95 deletions
diff --git a/doc/client.txt b/doc/client.txt
index 91ad038..6331ae7 100644
--- a/doc/client.txt
+++ b/doc/client.txt
@@ -546,8 +546,11 @@ gl_bilerp_pics::
- 2 — enabled for all pictures, including the scrap texture itself
gl_upscale_pcx::
- Enables upscaling of PCX images using HQ2x filter. This improves rendering
- quality when screen scaling is used. Default value is 0.
+ Enables upscaling of PCX images using HQ2x and HQ4x filters. This improves
+ rendering quality when screen scaling is used. Default value is 0.
+ - 0 — don't upscale
+ - 1 — upscale 2x (takes 5x more memory)
+ - 2 — upscale 4x (takes 21x more memory)
gl_maxmip::
When set to a positive integer N, limits maximum texture size to 2^N^.
diff --git a/src/refresh/gl/gl.h b/src/refresh/gl/gl.h
index 345de59..358d2d2 100644
--- a/src/refresh/gl/gl.h
+++ b/src/refresh/gl/gl.h
@@ -481,4 +481,5 @@ void GL_DrawAliasModel(model_t *model);
*
*/
void HQ2x_Render(uint32_t *output, const uint8_t *input, int width, int height);
+void HQ4x_Render(uint32_t *output, const uint8_t *input, int width, int height);
void HQ2x_Init(void);
diff --git a/src/refresh/gl/hq2x.c b/src/refresh/gl/hq2x.c
index 40c73e7..7eda311 100644
--- a/src/refresh/gl/hq2x.c
+++ b/src/refresh/gl/hq2x.c
@@ -26,6 +26,7 @@ written by Maxim Stepin (MaxSt). it is not 100% identical, but very similar.
*/
#include "shared/shared.h"
+#include "common/cvar.h"
#include "refresh/images.h"
#define MASK_G 0x0000ff00
@@ -34,47 +35,44 @@ written by Maxim Stepin (MaxSt). it is not 100% identical, but very similar.
#define MASK_ALPHA 0xff000000
static const uint8_t hqTable[256] = {
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 15, 12, 5, 3, 17, 13,
- 4, 4, 6, 18, 4, 4, 6, 18, 5, 3, 12, 12, 5, 3, 1, 12,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 17, 13, 5, 3, 16, 14,
- 4, 4, 6, 18, 4, 4, 6, 18, 5, 3, 16, 12, 5, 3, 1, 14,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 19, 12, 12, 5, 19, 16, 12,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 16, 12, 5, 3, 16, 12,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 19, 1, 12, 5, 19, 1, 14,
- 4, 4, 6, 2, 4, 4, 6, 18, 5, 3, 16, 12, 5, 19, 1, 14,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 15, 12, 5, 3, 17, 13,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 16, 12, 5, 3, 16, 12,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 17, 13, 5, 3, 16, 14,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 16, 13, 5, 3, 1, 14,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 16, 12, 5, 3, 16, 13,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 16, 12, 5, 3, 1, 12,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 16, 12, 5, 3, 1, 14,
- 4, 4, 6, 2, 4, 4, 6, 2, 5, 3, 1, 12, 5, 3, 1, 14,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 7, 8, 3, 5, 13, 15,
+ 1, 1, 2, 10, 1, 1, 2, 10, 3, 5, 8, 8, 3, 5, 6, 8,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 12, 14, 3, 5, 9, 16,
+ 1, 1, 2, 10, 1, 1, 2, 10, 3, 5, 9, 8, 3, 5, 6, 16,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 11, 8, 8, 3, 11, 9, 8,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 9, 8, 3, 5, 9, 8,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 11, 6, 8, 3, 11, 6, 16,
+ 1, 1, 2, 4, 1, 1, 2, 10, 3, 5, 9, 8, 3, 11, 6, 16,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 7, 8, 3, 5, 13, 15,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 9, 8, 3, 5, 9, 8,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 12, 14, 3, 5, 9, 16,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 9, 14, 3, 5, 6, 16,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 9, 8, 3, 5, 9, 15,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 9, 8, 3, 5, 6, 8,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 9, 8, 3, 5, 6, 16,
+ 1, 1, 2, 4, 1, 1, 2, 4, 3, 5, 6, 8, 3, 5, 6, 16,
};
static uint8_t rotTable[256];
static uint8_t equBitmap[65536 / CHAR_BIT];
-static int same(int A, int B)
+static inline int same(int A, int B)
{
return Q_IsBitSet(equBitmap, (A << 8) + B);
}
-static int diff(int A, int B)
+static inline int diff(int A, int B)
{
return !same(A, B);
}
-static uint32_t generic(int A, int B, int C, int w1, int w2, int w3, int s)
+static inline uint32_t generic(int A, int B, int C, int w1, int w2, int w3, int s)
{
uint32_t a = d_8to24table[A];
uint32_t b = d_8to24table[B];
uint32_t c = d_8to24table[C];
uint32_t g, rb, alpha;
- if ((A & B & C) == 255)
- return 0;
-
// if transparent, scan around for another color to avoid alpha fringes
if (A == 255) {
if (B == 255)
@@ -94,68 +92,258 @@ static uint32_t generic(int A, int B, int C, int w1, int w2, int w3, int s)
return (g & MASK_G) | (rb & MASK_RB) | (alpha & MASK_ALPHA);
}
-static uint32_t blend0(int A)
+static uint32_t blend_1(int A)
{
- if (A == 255)
- return 0;
-
return d_8to24table[A];
}
-static uint32_t blend1(int A, int B)
+static uint32_t blend_1_1(int A, int B)
+{
+ return generic(A, B, 0, 1, 1, 0, 1);
+}
+
+static uint32_t blend_3_1(int A, int B)
{
return generic(A, B, 0, 3, 1, 0, 2);
}
-static uint32_t blend2(int A, int B, int C)
+static uint32_t blend_7_1(int A, int B)
+{
+ return generic(A, B, 0, 7, 1, 0, 3);
+}
+
+static uint32_t blend_5_3(int A, int B)
+{
+ return generic(A, B, 0, 5, 3, 0, 3);
+}
+
+static uint32_t blend_2_1_1(int A, int B, int C)
{
return generic(A, B, C, 2, 1, 1, 2);
}
-static uint32_t blend3(int A, int B, int C)
+static uint32_t blend_5_2_1(int A, int B, int C)
{
return generic(A, B, C, 5, 2, 1, 3);
}
-static uint32_t blend4(int A, int B, int C)
+static uint32_t blend_6_1_1(int A, int B, int C)
{
return generic(A, B, C, 6, 1, 1, 3);
}
-static uint32_t blend5(int A, int B, int C)
+static uint32_t blend_2_3_3(int A, int B, int C)
{
return generic(A, B, C, 2, 3, 3, 3);
}
-static uint32_t blend6(int A, int B, int C)
+static uint32_t blend_14_1_1(int A, int B, int C)
{
return generic(A, B, C, 14, 1, 1, 4);
}
-static uint32_t blend(int rule, int E, int A, int B, int D, int F, int H)
+static uint32_t hq2x_blend(int rule, int E, int A, int B, int D, int F, int H)
{
switch (rule) {
- default:
- case 0: return blend0(E);
- case 1: return blend1(E, A);
- case 2: return blend1(E, D);
- case 3: return blend1(E, B);
- case 4: return blend2(E, D, B);
- case 5: return blend2(E, A, B);
- case 6: return blend2(E, A, D);
- case 7: return blend3(E, B, D);
- case 8: return blend3(E, D, B);
- case 9: return blend4(E, D, B);
- case 10: return blend5(E, D, B);
- case 11: return blend6(E, D, B);
- case 12: return same(B, D) ? blend2(E, D, B) : blend0(E);
- case 13: return same(B, D) ? blend5(E, D, B) : blend0(E);
- case 14: return same(B, D) ? blend6(E, D, B) : blend0(E);
- case 15: return same(B, D) ? blend2(E, D, B) : blend1(E, A);
- case 16: return same(B, D) ? blend4(E, D, B) : blend1(E, A);
- case 17: return same(B, D) ? blend5(E, D, B) : blend1(E, A);
- case 18: return same(B, F) ? blend3(E, B, D) : blend1(E, D);
- case 19: return same(D, H) ? blend3(E, D, B) : blend1(E, B);
+ case 1:
+ return blend_2_1_1(E, D, B);
+ case 2:
+ return blend_2_1_1(E, A, D);
+ case 3:
+ return blend_2_1_1(E, A, B);
+ case 4:
+ return blend_3_1(E, D);
+ case 5:
+ return blend_3_1(E, B);
+ case 6:
+ return blend_3_1(E, A);
+ case 7:
+ return same(B, D) ? blend_2_1_1(E, D, B) : blend_3_1(E, A);
+ case 8:
+ return same(B, D) ? blend_2_1_1(E, D, B) : blend_1(E);
+ case 9:
+ return same(B, D) ? blend_6_1_1(E, D, B) : blend_3_1(E, A);
+ case 10:
+ return same(B, F) ? blend_5_2_1(E, B, D) : blend_3_1(E, D);
+ case 11:
+ return same(D, H) ? blend_5_2_1(E, D, B) : blend_3_1(E, B);
+ case 12:
+ case 13:
+ return same(B, D) ? blend_2_3_3(E, D, B) : blend_3_1(E, A);
+ case 14:
+ case 15:
+ return same(B, D) ? blend_2_3_3(E, D, B) : blend_1(E);
+ case 16:
+ return same(B, D) ? blend_14_1_1(E, D, B) : blend_1(E);
+ default:
+ Com_Error(ERR_FATAL, "%s: bad rule %d", __func__, rule);
+ return 0;
+ }
+}
+
+static void hq4x_blend(int rule, uint32_t *p00, uint32_t *p01, uint32_t *p10, uint32_t *p11, int E, int A, int B, int D, int F, int H)
+{
+ switch (rule) {
+ case 1:
+ *p00 = blend_2_1_1(E, B, D);
+ *p01 = blend_5_2_1(E, B, D);
+ *p10 = blend_5_2_1(E, D, B);
+ *p11 = blend_6_1_1(E, D, B);
+ break;
+ case 2:
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_3_1(E, A);
+ *p10 = blend_5_2_1(E, D, A);
+ *p11 = blend_7_1(E, A);
+ break;
+ case 3:
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_5_2_1(E, B, A);
+ *p10 = blend_3_1(E, A);
+ *p11 = blend_7_1(E, A);
+ break;
+ case 4:
+ *p00 = blend_5_3(E, D);
+ *p01 = blend_7_1(E, D);
+ *p10 = blend_5_3(E, D);
+ *p11 = blend_7_1(E, D);
+ break;
+ case 5:
+ *p00 = blend_5_3(E, B);
+ *p01 = blend_5_3(E, B);
+ *p10 = blend_7_1(E, B);
+ *p11 = blend_7_1(E, B);
+ break;
+ case 6:
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_3_1(E, A);
+ *p10 = blend_3_1(E, A);
+ *p11 = blend_7_1(E, A);
+ break;
+ case 7:
+ if (same(B, D)) {
+ *p00 = blend_1_1(B, D);
+ *p01 = blend_1_1(B, E);
+ *p10 = blend_1_1(D, E);
+ *p11 = blend_1(E);
+ } else {
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_3_1(E, A);
+ *p10 = blend_3_1(E, A);
+ *p11 = blend_7_1(E, A);
+ }
+ break;
+ case 8:
+ if (same(B, D)) {
+ *p00 = blend_1_1(B, D);
+ *p01 = blend_1_1(B, E);
+ *p10 = blend_1_1(D, E);
+ } else {
+ *p00 = blend_1(E);
+ *p01 = blend_1(E);
+ *p10 = blend_1(E);
+ }
+ *p11 = blend_1(E);
+ break;
+ case 9:
+ if (same(B, D)) {
+ *p00 = blend_2_1_1(E, B, D);
+ *p01 = blend_3_1(E, B);
+ *p10 = blend_3_1(E, D);
+ *p11 = blend_1(E);
+ } else {
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_3_1(E, A);
+ *p10 = blend_3_1(E, A);
+ *p11 = blend_7_1(E, A);
+ }
+ break;
+ case 10:
+ if (same(B, F)) {
+ *p00 = blend_3_1(E, B);
+ *p01 = blend_3_1(B, E);
+ } else {
+ *p00 = blend_5_3(E, D);
+ *p01 = blend_7_1(E, D);
+ }
+ *p10 = blend_5_3(E, D);
+ *p11 = blend_7_1(E, D);
+ break;
+ case 11:
+ if (same(D, H)) {
+ *p00 = blend_3_1(E, D);
+ *p10 = blend_3_1(D, E);
+ } else {
+ *p00 = blend_5_3(E, B);
+ *p10 = blend_7_1(E, B);
+ }
+ *p01 = blend_5_3(E, B);
+ *p11 = blend_7_1(E, B);
+ break;
+ case 12:
+ if (same(B, D)) {
+ *p00 = blend_1_1(B, D);
+ *p01 = blend_2_1_1(B, E, D);
+ *p10 = blend_5_3(D, B);
+ *p11 = blend_6_1_1(E, D, B);
+ } else {
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_3_1(E, A);
+ *p10 = blend_3_1(E, A);
+ *p11 = blend_7_1(E, A);
+ }
+ break;
+ case 13:
+ if (same(B, D)) {
+ *p00 = blend_1_1(B, D);
+ *p01 = blend_5_3(B, D);
+ *p10 = blend_2_1_1(D, E, B);
+ *p11 = blend_6_1_1(E, D, B);
+ } else {
+ *p00 = blend_5_3(E, A);
+ *p01 = blend_3_1(E, A);
+ *p10 = blend_3_1(E, A);
+ *p11 = blend_7_1(E, A);
+ }
+ break;
+ case 14:
+ if (same(B, D)) {
+ *p00 = blend_1_1(B, D);
+ *p01 = blend_2_1_1(B, E, D);
+ *p10 = blend_5_3(D, B);
+ *p11 = blend_6_1_1(E, D, B);
+ } else {
+ *p00 = blend_1(E);
+ *p01 = blend_1(E);
+ *p10 = blend_1(E);
+ *p11 = blend_1(E);
+ }
+ break;
+ case 15:
+ if (same(B, D)) {
+ *p00 = blend_1_1(B, D);
+ *p01 = blend_5_3(B, D);
+ *p10 = blend_2_1_1(D, E, B);
+ *p11 = blend_6_1_1(E, D, B);
+ } else {
+ *p00 = blend_1(E);
+ *p01 = blend_1(E);
+ *p10 = blend_1(E);
+ *p11 = blend_1(E);
+ }
+ break;
+ case 16:
+ if (same(B, D))
+ *p00 = blend_2_1_1(E, B, D);
+ else
+ *p00 = blend_1(E);
+ *p01 = blend_1(E);
+ *p10 = blend_1(E);
+ *p11 = blend_1(E);
+ break;
+ default:
+ Com_Error(ERR_FATAL, "%s: bad rule %d", __func__, rule);
+ break;
}
}
@@ -165,8 +353,8 @@ void HQ2x_Render(uint32_t *output, const uint8_t *input, int width, int height)
for (y = 0; y < height; y++) {
const uint8_t *in = input + y * width;
- uint32_t *out0 = output + y * width * 4;
- uint32_t *out1 = output + y * width * 4 + width * 2;
+ uint32_t *out0 = output + (y * 2 + 0) * width * 2;
+ uint32_t *out1 = output + (y * 2 + 1) * width * 2;
int prevline = (y == 0 ? 0 : width);
int nextline = (y == height - 1 ? 0 : width);
@@ -195,10 +383,10 @@ void HQ2x_Render(uint32_t *output, const uint8_t *input, int width, int height)
pattern |= diff(E, H) << 6;
pattern |= diff(E, I) << 7;
- *(out0 + 0) = blend(hqTable[pattern], E, A, B, D, F, H); pattern = rotTable[pattern];
- *(out0 + 1) = blend(hqTable[pattern], E, C, F, B, H, D); pattern = rotTable[pattern];
- *(out1 + 1) = blend(hqTable[pattern], E, I, H, F, D, B); pattern = rotTable[pattern];
- *(out1 + 0) = blend(hqTable[pattern], E, G, D, H, B, F);
+ *(out0 + 0) = hq2x_blend(hqTable[pattern], E, A, B, D, F, H); pattern = rotTable[pattern];
+ *(out0 + 1) = hq2x_blend(hqTable[pattern], E, C, F, B, H, D); pattern = rotTable[pattern];
+ *(out1 + 1) = hq2x_blend(hqTable[pattern], E, I, H, F, D, B); pattern = rotTable[pattern];
+ *(out1 + 0) = hq2x_blend(hqTable[pattern], E, G, D, H, B, F);
in++;
out0 += 2;
@@ -207,6 +395,58 @@ void HQ2x_Render(uint32_t *output, const uint8_t *input, int width, int height)
}
}
+void HQ4x_Render(uint32_t *output, const uint8_t *input, int width, int height)
+{
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ const uint8_t *in = input + y * width;
+ uint32_t *out0 = output + (y * 4 + 0) * width * 4;
+ uint32_t *out1 = output + (y * 4 + 1) * width * 4;
+ uint32_t *out2 = output + (y * 4 + 2) * width * 4;
+ uint32_t *out3 = output + (y * 4 + 3) * width * 4;
+
+ int prevline = (y == 0 ? 0 : width);
+ int nextline = (y == height - 1 ? 0 : width);
+
+ for (x = 0; x < width; x++) {
+ int prev = (x == 0 ? 0 : 1);
+ int next = (x == width - 1 ? 0 : 1);
+
+ int A = *(in - prevline - prev);
+ int B = *(in - prevline);
+ int C = *(in - prevline + next);
+ int D = *(in - prev);
+ int E = *(in);
+ int F = *(in + next);
+ int G = *(in + nextline - prev);
+ int H = *(in + nextline);
+ int I = *(in + nextline + next);
+
+ int pattern;
+ pattern = diff(E, A) << 0;
+ pattern |= diff(E, B) << 1;
+ pattern |= diff(E, C) << 2;
+ pattern |= diff(E, D) << 3;
+ pattern |= diff(E, F) << 4;
+ pattern |= diff(E, G) << 5;
+ pattern |= diff(E, H) << 6;
+ pattern |= diff(E, I) << 7;
+
+ hq4x_blend(hqTable[pattern], out0 + 0, out0 + 1, out1 + 0, out1 + 1, E, A, B, D, F, H); pattern = rotTable[pattern];
+ hq4x_blend(hqTable[pattern], out0 + 3, out1 + 3, out0 + 2, out1 + 2, E, C, F, B, H, D); pattern = rotTable[pattern];
+ hq4x_blend(hqTable[pattern], out3 + 3, out3 + 2, out2 + 3, out2 + 2, E, I, H, F, D, B); pattern = rotTable[pattern];
+ hq4x_blend(hqTable[pattern], out3 + 0, out2 + 0, out3 + 1, out2 + 1, E, G, D, H, B, F);
+
+ in++;
+ out0 += 4;
+ out1 += 4;
+ out2 += 4;
+ out3 += 4;
+ }
+ }
+}
+
static void pix2ycc(float c[3], int C)
{
int r = d_8to24table[C] & 255;
@@ -220,7 +460,11 @@ static void pix2ycc(float c[3], int C)
void HQ2x_Init(void)
{
- int n;
+ int n, A, B;
+
+ cvar_t *hqx_y = Cvar_Get("hqx_y", "48", CVAR_FILES);
+ cvar_t *hqx_cb = Cvar_Get("hqx_cb", "7", CVAR_FILES);
+ cvar_t *hqx_cr = Cvar_Get("hqx_cr", "6", CVAR_FILES);
for (n = 0; n < 256; n++) {
rotTable[n] = ((n >> 2) & 0x11) | ((n << 2) & 0x88)
@@ -230,30 +474,25 @@ void HQ2x_Init(void)
memset(equBitmap, 0, sizeof(equBitmap));
- for (n = 0; n < 65536; n++) {
- int A = n >> 8;
- int B = n & 255;
- float a[3];
- float b[3];
+ for (A = 0; A < 255; A++) {
+ for (B = 0; B <= A; B++) {
+ float a[3];
+ float b[3];
- if (A == 255 && B == 255) {
- Q_SetBit(equBitmap, n);
- continue;
- }
+ pix2ycc(a, A);
+ pix2ycc(b, B);
- if (A == 255 || B == 255)
- continue;
+ if (fabs(a[0] - b[0]) > hqx_y->value)
+ continue;
+ if (fabs(a[1] - b[1]) > hqx_cb->value)
+ continue;
+ if (fabs(a[2] - b[2]) > hqx_cr->value)
+ continue;
- pix2ycc(a, A);
- pix2ycc(b, B);
-
- if (fabs(a[0] - b[0]) > 0x30)
- continue;
- if (fabs(a[1] - b[1]) > 0x07)
- continue;
- if (fabs(a[2] - b[2]) > 0x06)
- continue;
-
- Q_SetBit(equBitmap, n);
+ Q_SetBit(equBitmap, (A << 8) + B);
+ Q_SetBit(equBitmap, (B << 8) + A);
+ }
}
+
+ Q_SetBit(equBitmap, 65535);
}
diff --git a/src/refresh/gl/images.c b/src/refresh/gl/images.c
index 777e4d8..551ad92 100644
--- a/src/refresh/gl/images.c
+++ b/src/refresh/gl/images.c
@@ -592,14 +592,33 @@ static void GL_Upload8(byte *data, int width, int height, int baselevel, imagety
static void GL_Upscale8(byte *data, int width, int height, imagetype_t type, imageflags_t flags)
{
- byte *buffer;
+ int maxlevel;
+ byte *buffer;
+ uint32_t saved;
+
+ maxlevel = Cvar_ClampInteger(gl_upscale_pcx, 1, 2);
+ buffer = FS_AllocTempMem((width * height) << ((maxlevel + 1) * 2));
+
+ // small hack for optimization
+ saved = d_8to24table[255];
+ d_8to24table[255] = 0;
+
+ if (maxlevel >= 2) {
+ HQ4x_Render((uint32_t *)buffer, data, width, height);
+ GL_Upload32(buffer, width * 4, height * 4, maxlevel - 2, type, flags);
+ }
+
+ if (maxlevel >= 1) {
+ HQ2x_Render((uint32_t *)buffer, data, width, height);
+ GL_Upload32(buffer, width * 2, height * 2, maxlevel - 1, type, flags);
+ }
+
+ d_8to24table[255] = saved;
- buffer = FS_AllocTempMem(width * height * 16);
- HQ2x_Render((uint32_t *)buffer, data, width, height);
- GL_Upload32(buffer, width * 2, height * 2, 0, type, flags);
FS_FreeTempMem(buffer);
- GL_Upload8(data, width, height, 1, type, flags);
- qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+
+ GL_Upload8(data, width, height, maxlevel, type, flags);
+ qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxlevel);
}
static void GL_SetFilterAndRepeat(imagetype_t type, imageflags_t flags)
@@ -697,9 +716,6 @@ void IMG_Load(image_t *image, byte *pic, int width, int height)
image->flags |= IF_UPSCALED;
scrap_dirty = qtrue;
- if (!gl_static.registering) {
- Scrap_Upload();
- }
return;
}
@@ -941,7 +957,9 @@ void GL_InitImages(void)
IMG_GetPalette();
- HQ2x_Init();
+ if (gl_upscale_pcx->integer) {
+ HQ2x_Init();
+ }
GL_BuildIntensityTable();
diff --git a/src/refresh/gl/tess.c b/src/refresh/gl/tess.c
index 0571ef4..56cd3bc 100644
--- a/src/refresh/gl/tess.c
+++ b/src/refresh/gl/tess.c
@@ -43,6 +43,8 @@ void GL_Flush2D(void)
bits |= GLS_ALPHATEST_ENABLE;
}
+ Scrap_Upload();
+
GL_BindTexture(0, tess.texnum[0]);
GL_StateBits(bits);
GL_ArrayBits(GLA_VERTEX | GLA_TC | GLA_COLOR);