#include "gl_local.h"
image_t *draw_chars;
void Draw_InitLocal(void) {
draw_chars = GL_FindImage("pics/conchars.pcx", it_pic);
glTextureParameterf(draw_chars->texnum, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTextureParameterf(draw_chars->texnum, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
ALIAS_GL_SHADER(vertex,
code(
layout(location = 0) out vec2 out_st;
layout(location = 1) out vec4 out_rgba;
),
main(
gl_Position = u_view_projection_matrix * vec4(in_xy, 0, 1);
out_st = in_st;
out_rgba = in_rgba;
)
)
ALIAS_GL_SHADER(fragment,
code(
layout(location = 0) in vec2 in_st;
layout(location = 1) in vec4 in_rgba;
layout(location = 0) out vec4 out_color;
),
main(
out_color = texture(u_img, in_st) * in_rgba;
)
)
static struct alias_gl_DrawState draw_state = {.primitive = GL_TRIANGLES,
.attribute[0] = {0, alias_memory_Format_Float32, 2, "xy", 0},
.attribute[1] = {0, alias_memory_Format_Float32, 2, "st", 8},
.attribute[2] = {0, alias_memory_Format_Unorm8, 4, "rgba", 16},
.binding[0] = {sizeof(struct DrawVertex)},
.global[0] = {ALIAS_GL_VERTEX_BIT, &u_view_projection_matrix},
.image[0] = {ALIAS_GL_FRAGMENT_BIT, alias_gl_Type_sampler2D, "img"},
.vertex_shader = &vertex_shader,
.fragment_shader = &fragment_shader,
.depth_range_min = 0,
.depth_range_max = 1,
.blend_enable = true,
.blend_src_factor = GL_SRC_ALPHA,
.blend_dst_factor = GL_ONE_MINUS_SRC_ALPHA};
static void draw_triangles_internal(GLuint image, const struct DrawVertex *vertexes, uint32_t num_vertexes,
const uint32_t *indexes, uint32_t num_indexes) {
struct alias_gl_Buffer element_buffer =
alias_gl_allocateTemporaryBufferFrom(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * num_indexes, indexes);
struct alias_gl_Buffer vertex_buffer =
alias_gl_allocateTemporaryBufferFrom(GL_ARRAY_BUFFER, sizeof(struct DrawVertex) * num_vertexes, vertexes);
alias_gl_drawElements(&draw_state,
&(struct alias_gl_DrawAssets){
.image[0] = image, .element_buffer = &element_buffer, .vertex_buffers[0] = &vertex_buffer},
num_indexes, 1, 0, 0);
}
void Draw_Triangles(const struct BaseImage *image, const struct DrawVertex *vertexes, uint32_t num_vertexes,
const uint32_t *indexes, uint32_t num_indexes) {
draw_triangles_internal(((image_t *)image)->texnum, vertexes, num_vertexes, indexes, num_indexes);
}
void GL_draw_2d_quad(GLuint image, float x1, float y1, float x2, float y2, float s1, float t1, float s2, float t2,
float r, float g, float b, float a) {
struct DrawVertex vertexes[4] = {
{{x1, y1}, {s1, t1}, {r * 255, g * 255, b * 255, a * 255}},
{{x1, y2}, {s1, t2}, {r * 255, g * 255, b * 255, a * 255}},
{{x2, y2}, {s2, t2}, {r * 255, g * 255, b * 255, a * 255}},
{{x2, y1}, {s2, t1}, {r * 255, g * 255, b * 255, a * 255}},
};
uint32_t indexes[6] = {0, 1, 2, 0, 2, 3};
draw_triangles_internal(image, vertexes, 4, indexes, 6);
}
void Draw_Char(int x, int y, int num) {
int row, col;
float frow, fcol, size;
num &= 255;
if((num & 127) == 32)
return;
if(y <= -8)
return;
row = num >> 4;
col = num & 15;
frow = row * 0.0625;
fcol = col * 0.0625;
size = 0.0625;
GL_draw_2d_quad(draw_chars->texnum, x, y, x + 8, y + 8, fcol, frow, fcol + size, frow + size, 1, 1, 1, 1);
}
image_t *Draw_FindPic(const char *name) {
image_t *gl;
char fullname[MAX_QPATH];
if(name[0] != '/' && name[0] != '\\') {
Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name);
gl = GL_FindImage(fullname, it_pic);
} else
gl = GL_FindImage(name + 1, it_pic);
return gl;
}
void Draw_GetPicSize(int *w, int *h, const char *pic) {
image_t *gl;
gl = Draw_FindPic(pic);
if(!gl) {
*w = *h = -1;
return;
}
*w = gl->base.width;
*h = gl->base.height;
}
void Draw_StretchPic(int x, int y, int w, int h, const char *pic) {
image_t *gl;
gl = Draw_FindPic(pic);
if(!gl) {
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
GL_draw_2d_quad(gl->texnum, x, y, x + w, y + h, gl->base.s0, gl->base.t0, gl->base.s1, gl->base.t1, 1, 1, 1, 1);
}
void Draw_Pic(int x, int y, const char *pic) {
image_t *gl;
gl = Draw_FindPic(pic);
if(!gl) {
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
GL_draw_2d_quad(gl->texnum, x, y, x + gl->base.width, y + gl->base.height, gl->base.s0, gl->base.t0, gl->base.s1,
gl->base.t1, 1, 1, 1, 1);
}
void Draw_TileClear(int x, int y, int w, int h, const char *pic) {
image_t *image;
image = Draw_FindPic(pic);
if(!image) {
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
GL_draw_2d_quad(image->texnum, x, y, x + w, y + h, x / 64.0, y / 64.0, (x + w) / 64.0, (y + h) / 64.0, 1, 1, 1, 1);
}
void Draw_Fill(int x, int y, int w, int h, int c) {
union {
unsigned c;
byte v[4];
} color;
if((unsigned)c > 255)
ri.Sys_Error(ERR_FATAL, "Draw_Fill: bad color");
color.c = d_8to24table[c];
GL_draw_2d_quad(r_whitepcx->texnum, x, y, x + w, y + h, 0, 0, 1, 1, color.v[0] / 255.0, color.v[1] / 255.0,
color.v[2] / 255.0, 1);
}
void Draw_FadeScreen(void) {
GL_draw_2d_quad(r_whitepcx->texnum, 0, 0, vid.width, vid.height, 0, 0, 1, 1, 0, 0, 0, 0.8);
}
extern unsigned r_rawpalette[256];
void Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data) {
unsigned image32[256 * 256];
int i, j, trows;
byte *source;
int frac, fracstep;
float hscale;
int row;
float t;
glBindTexture(GL_TEXTURE_2D, 1);
if(rows <= 256) {
hscale = 1;
trows = rows;
} else {
hscale = rows / 256.0;
trows = 256;
}
t = rows * hscale / 256;
unsigned *dest;
for(i = 0; i < trows; i++) {
row = (int)(i * hscale);
if(row > rows)
break;
source = data + cols * row;
dest = &image32[i * 256];
fracstep = cols * 0x10000 / 256;
frac = fracstep >> 1;
for(j = 0; j < 256; j++) {
dest[j] = r_rawpalette[source[frac >> 16]];
frac += fracstep;
}
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, image32);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GL_draw_2d_quad(1, x, y, x + w, y + h, 0, 0, 1, t, 1, 1, 1, 1);
}