[RELEASE] u22-v03
This version is submitted to U22 breau.
This commit is contained in:
14
util/gleasy/CMakeLists.txt
Normal file
14
util/gleasy/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
add_library(gleasy
|
||||
atlas.c
|
||||
framebuffer.c
|
||||
program.c
|
||||
shader.c
|
||||
)
|
||||
target_link_libraries(gleasy
|
||||
GLEW::GLEW
|
||||
OpenGL::GL
|
||||
|
||||
container
|
||||
math
|
||||
memory
|
||||
)
|
194
util/gleasy/atlas.c
Normal file
194
util/gleasy/atlas.c
Normal file
@@ -0,0 +1,194 @@
|
||||
#include "./atlas.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/container/array.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./misc.h"
|
||||
#include "./texture.h"
|
||||
|
||||
struct gleasy_atlas_t {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
|
||||
int32_t consumed_y;
|
||||
int32_t consumed_x;
|
||||
|
||||
int32_t line_height;
|
||||
|
||||
gleasy_texture_2d_t tex;
|
||||
|
||||
CONTAINER_ARRAY uint8_t* resize_buffer;
|
||||
};
|
||||
|
||||
static void gleasy_atlas_resize_bitmap_(
|
||||
gleasy_atlas_t* atlas,
|
||||
gleasy_atlas_bitmap_t* out,
|
||||
const gleasy_atlas_bitmap_t* in) {
|
||||
assert(atlas != NULL);
|
||||
assert(out != NULL);
|
||||
assert(in != NULL);
|
||||
|
||||
*out = (typeof(*out)) {
|
||||
.width = math_int32_next_power2(MATH_MAX(in->width, 4)),
|
||||
.height = math_int32_next_power2(MATH_MAX(in->height, 4)),
|
||||
.format = in->format,
|
||||
.type = in->type,
|
||||
.buffer = in->buffer,
|
||||
};
|
||||
if (out->width == in->width && out->height == in->height) return;
|
||||
|
||||
const size_t type = GLEASY_GET_BYTE_SIZE_OF_TYPE(out->type);
|
||||
const size_t fmt = GLEASY_GET_CHANNELS_OF_TEXTURE_FORMAT(out->format);
|
||||
|
||||
const size_t pixel = type*fmt;
|
||||
assert(pixel > 0);
|
||||
|
||||
container_array_resize(atlas->resize_buffer, out->width*out->height*pixel);
|
||||
out->buffer = atlas->resize_buffer;
|
||||
|
||||
const int32_t ymax = out->height * pixel;
|
||||
const int32_t xmax = out->width * pixel;
|
||||
|
||||
const uint8_t* src = in->buffer;
|
||||
uint8_t* dst = atlas->resize_buffer;
|
||||
for (int32_t y = 0; y < ymax; ++y) {
|
||||
for (int32_t x = 0; x < xmax; ++x) {
|
||||
if (x < in->width && y < in->height) {
|
||||
*dst = *(src++);
|
||||
} else {
|
||||
*dst = 0;
|
||||
}
|
||||
++dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool gleasy_atlas_allocate_area_(
|
||||
gleasy_atlas_t* atlas,
|
||||
int32_t* x,
|
||||
int32_t* y,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t actual_width,
|
||||
int32_t actual_height) {
|
||||
assert(atlas != NULL);
|
||||
assert(x != NULL);
|
||||
assert(y != NULL);
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
assert(actual_width > 0);
|
||||
assert(actual_height > 0);
|
||||
|
||||
if (atlas->consumed_x + actual_width > atlas->width) {
|
||||
atlas->consumed_x = 0;
|
||||
atlas->consumed_y += atlas->line_height+1;
|
||||
atlas->line_height = 0;
|
||||
}
|
||||
if (atlas->consumed_y + actual_height > atlas->height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*x = atlas->consumed_x;
|
||||
*y = atlas->consumed_y;
|
||||
|
||||
atlas->consumed_x += width+1;
|
||||
atlas->line_height = MATH_MAX(atlas->line_height, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
gleasy_atlas_t* gleasy_atlas_new(
|
||||
GLenum format, int32_t width, int32_t height, bool aa) {
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
|
||||
gleasy_atlas_t* atlas = memory_new(sizeof(*atlas));
|
||||
*atlas = (typeof(*atlas)) {
|
||||
.width = math_int32_next_power2(width),
|
||||
.height = math_int32_next_power2(height),
|
||||
};
|
||||
|
||||
glGenTextures(1, &atlas->tex);
|
||||
glBindTexture(GL_TEXTURE_2D, atlas->tex);
|
||||
|
||||
const GLenum filter = aa? GL_LINEAR: 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);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format,
|
||||
atlas->width, atlas->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
container_array_reserve(atlas->resize_buffer, width*height*4);
|
||||
return atlas;
|
||||
}
|
||||
|
||||
void gleasy_atlas_delete(gleasy_atlas_t* atlas) {
|
||||
if (atlas == NULL) return;
|
||||
|
||||
glDeleteTextures(1, &atlas->tex);
|
||||
|
||||
container_array_delete(atlas->resize_buffer);
|
||||
|
||||
memory_delete(atlas);
|
||||
}
|
||||
|
||||
void gleasy_atlas_clear(gleasy_atlas_t* atlas) {
|
||||
assert(atlas != NULL);
|
||||
|
||||
atlas->consumed_y = 0;
|
||||
atlas->consumed_x = 0;
|
||||
|
||||
atlas->line_height = 0;
|
||||
}
|
||||
|
||||
bool gleasy_atlas_add(
|
||||
gleasy_atlas_t* atlas,
|
||||
gleasy_atlas_geometry_t* geo,
|
||||
const gleasy_atlas_bitmap_t* bitmap) {
|
||||
assert(atlas != NULL);
|
||||
assert(geo != NULL);
|
||||
assert(bitmap != NULL);
|
||||
|
||||
gleasy_atlas_bitmap_t resized;
|
||||
gleasy_atlas_resize_bitmap_(atlas, &resized, bitmap);
|
||||
|
||||
int32_t x, y;
|
||||
if (!gleasy_atlas_allocate_area_(atlas,
|
||||
&x, &y, bitmap->width, bitmap->height, resized.width, resized.height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*geo = (typeof(*geo)) {
|
||||
.left = x*1.0f / atlas->width,
|
||||
.right = (x+bitmap->width)*1.0f / atlas->width,
|
||||
.top = y*1.0f / atlas->height,
|
||||
.bottom = (y+bitmap->height)*1.0f / atlas->height,
|
||||
};
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, atlas->tex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
|
||||
resized.width,
|
||||
resized.height,
|
||||
resized.format,
|
||||
resized.type,
|
||||
resized.buffer);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gleasy_texture_2d_t gleasy_atlas_get_texture(const gleasy_atlas_t* atlas) {
|
||||
assert(atlas != NULL);
|
||||
|
||||
return atlas->tex;
|
||||
}
|
56
util/gleasy/atlas.h
Normal file
56
util/gleasy/atlas.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "./texture.h"
|
||||
|
||||
struct gleasy_atlas_t;
|
||||
typedef struct gleasy_atlas_t gleasy_atlas_t;
|
||||
|
||||
typedef struct {
|
||||
float left;
|
||||
float right;
|
||||
float top;
|
||||
float bottom;
|
||||
} gleasy_atlas_geometry_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
const uint8_t* buffer;
|
||||
} gleasy_atlas_bitmap_t;
|
||||
|
||||
gleasy_atlas_t*
|
||||
gleasy_atlas_new(
|
||||
GLenum format,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
bool aa
|
||||
);
|
||||
|
||||
void
|
||||
gleasy_atlas_delete(
|
||||
gleasy_atlas_t* atlas
|
||||
);
|
||||
|
||||
void
|
||||
gleasy_atlas_clear(
|
||||
gleasy_atlas_t* atlas
|
||||
);
|
||||
|
||||
bool
|
||||
gleasy_atlas_add(
|
||||
gleasy_atlas_t* atlas,
|
||||
gleasy_atlas_geometry_t* geo,
|
||||
const gleasy_atlas_bitmap_t* bitmap
|
||||
);
|
||||
|
||||
gleasy_texture_2d_t
|
||||
gleasy_atlas_get_texture(
|
||||
const gleasy_atlas_t* atlas
|
||||
);
|
7
util/gleasy/buffer.h
Normal file
7
util/gleasy/buffer.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
typedef GLuint gleasy_buffer_array_t;
|
||||
typedef GLuint gleasy_buffer_element_array_t;
|
||||
typedef GLuint gleasy_buffer_uniform_t;
|
96
util/gleasy/framebuffer.c
Normal file
96
util/gleasy/framebuffer.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "./framebuffer.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "./texture.h"
|
||||
|
||||
void gleasy_framebuffer_initialize(
|
||||
gleasy_framebuffer_t* fb, int32_t width, int32_t height, int32_t samples) {
|
||||
assert(fb != NULL);
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
assert(0 < samples && samples < GL_MAX_SAMPLES);
|
||||
|
||||
*fb = (typeof(*fb)) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
glGenRenderbuffers(1, &fb->colorbuf_msaa);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, fb->colorbuf_msaa);
|
||||
glRenderbufferStorageMultisample(
|
||||
GL_RENDERBUFFER, samples, GL_RGBA, width, height);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glGenTextures(1, &fb->colorbuf);
|
||||
glBindTexture(GL_TEXTURE_2D, fb->colorbuf);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
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_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
GLuint fbo[2];
|
||||
glGenFramebuffers(2, fbo);
|
||||
fb->id_msaa = fbo[0];
|
||||
fb->id = fbo[1];
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->id_msaa);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fb->colorbuf_msaa);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->id);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->colorbuf, 0);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
|
||||
void gleasy_framebuffer_deinitialize(gleasy_framebuffer_t* fb) {
|
||||
assert(fb != NULL);
|
||||
|
||||
GLuint fbo[] = {fb->id_msaa, fb->id};
|
||||
glDeleteFramebuffers(2, fbo);
|
||||
|
||||
glDeleteTextures(1, &fb->colorbuf);
|
||||
|
||||
glDeleteRenderbuffers(1, &fb->colorbuf_msaa);
|
||||
}
|
||||
|
||||
void gleasy_framebuffer_bind(const gleasy_framebuffer_t* fb) {
|
||||
assert(fb != NULL);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->id_msaa);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
fprintf(stderr, "gleasy: framebuffer is in invalid state\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void gleasy_framebuffer_flush(const gleasy_framebuffer_t* fb) {
|
||||
assert(fb != NULL);
|
||||
|
||||
gleasy_framebuffer_flush_to_other(fb, fb->id);
|
||||
}
|
||||
|
||||
void gleasy_framebuffer_flush_to_other(const gleasy_framebuffer_t* fb, GLuint id) {
|
||||
assert(fb != NULL);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb->id_msaa);
|
||||
glBlitFramebuffer(
|
||||
0, 0, fb->width, fb->height,
|
||||
0, 0, fb->width, fb->height,
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
}
|
47
util/gleasy/framebuffer.h
Normal file
47
util/gleasy/framebuffer.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "./texture.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
|
||||
GLuint id_msaa;
|
||||
GLuint colorbuf_msaa;
|
||||
|
||||
GLuint id;
|
||||
gleasy_texture_2d_t colorbuf;
|
||||
} gleasy_framebuffer_t;
|
||||
|
||||
void
|
||||
gleasy_framebuffer_initialize(
|
||||
gleasy_framebuffer_t* fb,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t samples
|
||||
);
|
||||
|
||||
void
|
||||
gleasy_framebuffer_deinitialize(
|
||||
gleasy_framebuffer_t* fb
|
||||
);
|
||||
|
||||
void
|
||||
gleasy_framebuffer_bind(
|
||||
const gleasy_framebuffer_t* fb
|
||||
);
|
||||
|
||||
void
|
||||
gleasy_framebuffer_flush(
|
||||
const gleasy_framebuffer_t* fb
|
||||
);
|
||||
|
||||
void
|
||||
gleasy_framebuffer_flush_to_other(
|
||||
const gleasy_framebuffer_t* fb,
|
||||
GLuint id
|
||||
);
|
18
util/gleasy/misc.h
Normal file
18
util/gleasy/misc.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#define GLEASY_GET_BYTE_SIZE_OF_TYPE(t) ( \
|
||||
(t) == GL_UNSIGNED_BYTE? 1: \
|
||||
(t) == GL_BYTE? 1: \
|
||||
(t) == GL_SHORT? 2: \
|
||||
(t) == GL_UNSIGNED_SHORT? 2: \
|
||||
(t) == GL_INT? 4: \
|
||||
(t) == GL_UNSIGNED_INT? 4: \
|
||||
(t) == GL_FLOAT? 4: 0)
|
||||
|
||||
#define GLEASY_GET_CHANNELS_OF_TEXTURE_FORMAT(f) ( \
|
||||
(f) == GL_RGBA? 4: \
|
||||
(f) == GL_RGB? 3: \
|
||||
(f) == GL_RG? 2: \
|
||||
(f) == GL_RED? 1: 0)
|
66
util/gleasy/program.c
Normal file
66
util/gleasy/program.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "./program.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/math/algorithm.h"
|
||||
|
||||
#include "./shader.h"
|
||||
|
||||
gleasy_program_t gleasy_program_new(
|
||||
const char* header, size_t header_len,
|
||||
const char* vsrc, size_t vsrc_len,
|
||||
const char* fsrc, size_t fsrc_len) {
|
||||
assert(header != NULL || header_len == 0);
|
||||
assert(vsrc != NULL || vsrc_len == 0);
|
||||
assert(fsrc != NULL || fsrc_len == 0);
|
||||
|
||||
gleasy_program_t program = glCreateProgram();
|
||||
if (program == 0) {
|
||||
fprintf(stderr, "failed to create program");
|
||||
abort();
|
||||
}
|
||||
|
||||
const gleasy_shader_t vshader =
|
||||
gleasy_shader_new(GL_VERTEX_SHADER, header, header_len, vsrc, vsrc_len);
|
||||
const gleasy_shader_t fshader =
|
||||
gleasy_shader_new(GL_FRAGMENT_SHADER, header, header_len, fsrc, fsrc_len);
|
||||
|
||||
glAttachShader(program, vshader);
|
||||
glDeleteShader(vshader);
|
||||
|
||||
glAttachShader(program, fshader);
|
||||
glDeleteShader(fshader);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint ok;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &ok);
|
||||
if (ok == GL_FALSE) {
|
||||
char log[1024];
|
||||
const int len =
|
||||
gleasy_program_get_log(program, log, sizeof(log)/sizeof(log[0]));
|
||||
fprintf(stderr, "failed to link program\n%.*s\n", len, log);
|
||||
abort();
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
size_t gleasy_program_get_log(
|
||||
gleasy_program_t program, char* dst, size_t maxlen) {
|
||||
assert(program != 0);
|
||||
|
||||
GLint len;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
|
||||
if (dst == NULL) return len;
|
||||
|
||||
len = MATH_MIN(len, (GLint) maxlen);
|
||||
if (len == 0) return 0;
|
||||
|
||||
glGetProgramInfoLog(program, len, &len, (GLchar*) dst);
|
||||
return len;
|
||||
}
|
24
util/gleasy/program.h
Normal file
24
util/gleasy/program.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
typedef GLuint gleasy_program_t;
|
||||
|
||||
gleasy_program_t /* OWNERSHIP */
|
||||
gleasy_program_new(
|
||||
const char* header,
|
||||
size_t header_len,
|
||||
const char* vsrc,
|
||||
size_t vsrc_len,
|
||||
const char* fsrc,
|
||||
size_t fsrc_len
|
||||
);
|
||||
|
||||
size_t
|
||||
gleasy_program_get_log(
|
||||
gleasy_program_t program,
|
||||
char* dst, /* when NULL, returns actual size */
|
||||
size_t maxlen
|
||||
);
|
57
util/gleasy/shader.c
Normal file
57
util/gleasy/shader.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "./shader.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/math/algorithm.h"
|
||||
|
||||
gleasy_shader_t gleasy_shader_new(
|
||||
GLenum type,
|
||||
const char* header, size_t header_len,
|
||||
const char* src, size_t src_len) {
|
||||
assert(header != NULL || header_len == 0);
|
||||
assert(src != NULL || src_len == 0);
|
||||
|
||||
const GLuint shader = glCreateShader(type);
|
||||
if (shader == 0) {
|
||||
fprintf(stderr, "failed to create shader\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const GLchar* srcs[] = { header, src, };
|
||||
const GLint lens[] = { header_len, src_len, };
|
||||
const size_t offset = (header_len == 0? 1: 0);
|
||||
glShaderSource(shader, 2-offset, srcs+offset, lens+offset);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint ok;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
|
||||
if (ok == GL_FALSE) {
|
||||
char log[1024];
|
||||
const int loglen =
|
||||
gleasy_shader_get_log(shader, log, sizeof(log)/sizeof(log[0]));
|
||||
fprintf(stderr, "failed to compile shader\n%.*s\n", loglen, log);
|
||||
abort();
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
size_t gleasy_shader_get_log(
|
||||
gleasy_shader_t shader, char* dst, size_t maxlen) {
|
||||
assert(shader != 0);
|
||||
|
||||
GLint len;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
if (dst == NULL) return len;
|
||||
|
||||
len = MATH_MIN(len, (GLint) maxlen);
|
||||
if (len == 0) return 0;
|
||||
|
||||
glGetShaderInfoLog(shader, len, &len, (GLchar*) dst);
|
||||
return len;
|
||||
}
|
23
util/gleasy/shader.h
Normal file
23
util/gleasy/shader.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
typedef GLuint gleasy_shader_t;
|
||||
|
||||
gleasy_shader_t /* OWNERSHIP */
|
||||
gleasy_shader_new(
|
||||
GLenum type,
|
||||
const char* header,
|
||||
size_t header_len,
|
||||
const char* src,
|
||||
size_t src_len
|
||||
);
|
||||
|
||||
size_t
|
||||
gleasy_shader_get_log(
|
||||
gleasy_shader_t shader,
|
||||
char* dst, /* when NULL, returns actual size */
|
||||
size_t maxlen
|
||||
);
|
5
util/gleasy/texture.h
Normal file
5
util/gleasy/texture.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
typedef GLuint gleasy_texture_2d_t;
|
Reference in New Issue
Block a user