mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-10 08:08:35 +03:00
1875 lines
64 KiB
C++
1875 lines
64 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "gl_rend_state.hpp"
|
|
#include "shared.hpp"
|
|
|
|
enum gl_rend_state_update_flags : uint32_t {
|
|
GL_REND_STATE_UPDATE_PROGRAM = 1u << 0,
|
|
GL_REND_STATE_UPDATE_TEXTURE = 1u << 1,
|
|
GL_REND_STATE_UPDATE_ACTIVE_TEXTURE = 1u << 2,
|
|
GL_REND_STATE_UPDATE_SAMPLER = 1u << 3,
|
|
GL_REND_STATE_UPDATE_BLEND = 1u << 4,
|
|
GL_REND_STATE_UPDATE_BLEND_FUNC = 1u << 5,
|
|
GL_REND_STATE_UPDATE_BLEND_EQUATION = 1u << 6,
|
|
GL_REND_STATE_UPDATE_READ_FRAMEBUFFER = 1u << 7,
|
|
GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER = 1u << 8,
|
|
GL_REND_STATE_UPDATE_VERTEX_ARRAY = 1u << 9,
|
|
GL_REND_STATE_UPDATE_UNIFORM_BUFFER = 1u << 10,
|
|
GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER = 1u << 11,
|
|
GL_REND_STATE_UPDATE_COLOR_MASK = 1u << 12,
|
|
GL_REND_STATE_UPDATE_CULL_FACE = 1u << 13,
|
|
GL_REND_STATE_UPDATE_CULL_FACE_MODE = 1u << 14,
|
|
GL_REND_STATE_UPDATE_DEPTH_TEST = 1u << 15,
|
|
GL_REND_STATE_UPDATE_DEPTH_MASK = 1u << 16,
|
|
GL_REND_STATE_UPDATE_DEPTH_FUNC = 1u << 17,
|
|
GL_REND_STATE_UPDATE_LINE_WIDTH = 1u << 18,
|
|
GL_REND_STATE_UPDATE_MULTISAMPLE = 1u << 19,
|
|
GL_REND_STATE_UPDATE_PRIMITIVE_RESTART = 1u << 20,
|
|
GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX = 1u << 21,
|
|
GL_REND_STATE_UPDATE_SCISSOR_TEST = 1u << 22,
|
|
GL_REND_STATE_UPDATE_SCISSOR = 1u << 23,
|
|
GL_REND_STATE_UPDATE_STENCIL_TEST = 1u << 24,
|
|
GL_REND_STATE_UPDATE_STENCIL_MASK = 1u << 25,
|
|
GL_REND_STATE_UPDATE_STENCIL_FUNC = 1u << 26,
|
|
GL_REND_STATE_UPDATE_STENCIL_OP = 1u << 27,
|
|
GL_REND_STATE_UPDATE_VIEWPORT = 1u << 28,
|
|
GL_REND_STATE_UPDATE_CLEAR_COLOR = 1u << 29,
|
|
GL_REND_STATE_UPDATE_CLEAR_DEPTH = 1u << 30,
|
|
GL_REND_STATE_UPDATE_CLEAR_STENCIL = 1u << 31,
|
|
};
|
|
|
|
enum gl_rend_state_flags {
|
|
GL_REND_STATE_EXECUTE = 1u << 0,
|
|
};
|
|
|
|
struct gl_rend_state {
|
|
gl_rend_state_index index;
|
|
|
|
GLuint curr_program;
|
|
GLuint program;
|
|
|
|
GLuint curr_active_texture_index;
|
|
GLuint active_texture_index;
|
|
|
|
int32_t texture_binding_start_index;
|
|
int32_t texture_binding_end_index;
|
|
GLuint curr_texture_binding_2d[32];
|
|
GLuint texture_binding_2d[32];
|
|
GLuint curr_texture_binding_cube_map[32];
|
|
GLuint texture_binding_cube_map[32];
|
|
|
|
int32_t sampler_binding_start_index;
|
|
int32_t sampler_binding_end_index;
|
|
GLuint curr_sampler_binding[32];
|
|
GLuint sampler_binding[32];
|
|
|
|
GLboolean curr_blend;
|
|
GLboolean blend;
|
|
GLenum curr_blend_src_rgb;
|
|
GLenum blend_src_rgb;
|
|
GLenum curr_blend_src_alpha;
|
|
GLenum blend_src_alpha;
|
|
GLenum curr_blend_dst_rgb;
|
|
GLenum blend_dst_rgb;
|
|
GLenum curr_blend_dst_alpha;
|
|
GLenum blend_dst_alpha;
|
|
GLenum curr_blend_mode_rgb;
|
|
GLenum blend_mode_rgb;
|
|
GLenum curr_blend_mode_alpha;
|
|
GLenum blend_mode_alpha;
|
|
|
|
GLuint curr_read_framebuffer_binding;
|
|
GLuint read_framebuffer_binding;
|
|
GLuint curr_draw_framebuffer_binding;
|
|
GLuint draw_framebuffer_binding;
|
|
|
|
GLuint curr_vertex_array_binding;
|
|
GLuint vertex_array_binding;
|
|
|
|
GLuint array_buffer_binding;
|
|
GLuint element_array_buffer_binding;
|
|
|
|
GLuint uniform_buffer_binding;
|
|
|
|
int32_t uniform_buffer_start_index;
|
|
int32_t uniform_buffer_end_index;
|
|
GLuint curr_uniform_buffer_bindings[14];
|
|
GLuint uniform_buffer_bindings[14];
|
|
GLintptr curr_uniform_buffer_offsets[14];
|
|
GLintptr uniform_buffer_offsets[14];
|
|
GLsizeiptr curr_uniform_buffer_sizes[14];
|
|
GLsizeiptr uniform_buffer_sizes[14];
|
|
|
|
GLuint shader_storage_buffer_binding;
|
|
|
|
int32_t shader_storage_buffer_start_index;
|
|
int32_t shader_storage_buffer_end_index;
|
|
GLuint curr_shader_storage_buffer_bindings[14];
|
|
GLuint shader_storage_buffer_bindings[14];
|
|
GLintptr curr_shader_storage_buffer_offsets[14];
|
|
GLintptr shader_storage_buffer_offsets[14];
|
|
GLsizeiptr curr_shader_storage_buffer_sizes[14];
|
|
GLsizeiptr shader_storage_buffer_sizes[14];
|
|
|
|
GLboolean curr_color_mask[4];
|
|
GLboolean color_mask[4];
|
|
|
|
GLboolean curr_cull_face;
|
|
GLboolean cull_face;
|
|
GLenum curr_cull_face_mode;
|
|
GLenum cull_face_mode;
|
|
|
|
GLboolean curr_depth_test;
|
|
GLboolean depth_test;
|
|
GLenum curr_depth_func;
|
|
GLenum depth_func;
|
|
GLboolean curr_depth_mask;
|
|
GLboolean depth_mask;
|
|
|
|
GLfloat curr_line_width;
|
|
GLfloat line_width;
|
|
|
|
GLboolean curr_multisample;
|
|
GLboolean multisample;
|
|
|
|
GLboolean curr_primitive_restart;
|
|
GLboolean primitive_restart;
|
|
GLuint curr_primitive_restart_index;
|
|
GLuint primitive_restart_index;
|
|
|
|
gl_rend_state_rect curr_scissor_box;
|
|
gl_rend_state_rect scissor_box;
|
|
GLboolean curr_scissor_test;
|
|
GLboolean scissor_test;
|
|
|
|
GLboolean curr_stencil_test;
|
|
GLboolean stencil_test;
|
|
GLenum curr_stencil_func;
|
|
GLenum stencil_func;
|
|
GLenum curr_stencil_fail;
|
|
GLenum stencil_fail;
|
|
GLenum curr_stencil_dpfail;
|
|
GLenum stencil_dpfail;
|
|
GLenum curr_stencil_dppass;
|
|
GLenum stencil_dppass;
|
|
GLuint curr_stencil_mask;
|
|
GLuint stencil_mask;
|
|
GLint curr_stencil_ref;
|
|
GLint stencil_ref;
|
|
GLuint curr_stencil_value_mask;
|
|
GLuint stencil_value_mask;
|
|
|
|
gl_rend_state_rect curr_viewport;
|
|
gl_rend_state_rect viewport;
|
|
|
|
GLfloat curr_clear_color_value[4];
|
|
GLfloat clear_color_value[4];
|
|
|
|
GLfloat curr_clear_depth_value;
|
|
GLfloat clear_depth_value;
|
|
|
|
GLint curr_clear_stencil_value;
|
|
GLint clear_stencil_value;
|
|
|
|
gl_rend_state_flags flags;
|
|
gl_rend_state_update_flags update_flags;
|
|
|
|
void active_bind_texture_2d(int32_t index, GLuint texture);
|
|
void active_bind_texture_cube_map(int32_t index, GLuint texture);
|
|
void active_texture(int32_t index);
|
|
void begin_event(const char* message, int32_t length);
|
|
void bind_framebuffer(GLuint framebuffer);
|
|
void bind_read_framebuffer(GLuint framebuffer);
|
|
void bind_draw_framebuffer(GLuint framebuffer);
|
|
void bind_vertex_array(GLuint array);
|
|
void bind_array_buffer(GLuint buffer);
|
|
void bind_element_array_buffer(GLuint buffer);
|
|
void bind_uniform_buffer(GLuint buffer);
|
|
void bind_uniform_buffer_base(GLuint index, GLuint buffer);
|
|
void bind_uniform_buffer_range(GLuint index,
|
|
GLuint buffer, GLintptr offset, GLsizeiptr size);
|
|
void bind_shader_storage_buffer(GLuint buffer);
|
|
void bind_shader_storage_buffer_base(GLuint index, GLuint buffer);
|
|
void bind_shader_storage_buffer_range(GLuint index,
|
|
GLuint buffer, GLintptr offset, GLsizeiptr size);
|
|
void bind_texture_2d(GLuint texture);
|
|
void bind_texture_cube_map(GLuint texture);
|
|
void bind_sampler(int32_t index, GLuint sampler);
|
|
void blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
|
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
|
GLenum check_framebuffer_status(GLenum target);
|
|
void clear(GLbitfield mask);
|
|
void clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
|
void clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
|
void clear_depth(GLfloat depth);
|
|
void clear_stencil(GLint stencil);
|
|
void copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel,
|
|
GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel,
|
|
GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
|
|
void copy_tex_sub_image_2d(GLenum target, GLint level,
|
|
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
|
void disable_blend();
|
|
void disable_cull_face();
|
|
void disable_depth_test();
|
|
void disable_multisample();
|
|
void disable_primitive_restart();
|
|
void disable_scissor_test();
|
|
void disable_stencil_test();
|
|
void draw_arrays(GLenum mode, GLint first, GLsizei count);
|
|
void draw_arrays_instanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
|
|
void draw_elements(GLenum mode,
|
|
GLsizei count, GLenum type, const void* indices);
|
|
void draw_range_elements(GLenum mode,
|
|
GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices);
|
|
void enable_blend();
|
|
void enable_cull_face();
|
|
void enable_depth_test();
|
|
void enable_multisample();
|
|
void enable_primitive_restart();
|
|
void enable_scissor_test();
|
|
void enable_stencil_test();
|
|
void end_event();
|
|
void finish();
|
|
void generate_mipmap(GLenum target);
|
|
void generate_texture_mipmap(GLuint texture);
|
|
void get();
|
|
void get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha);
|
|
GLuint get_program();
|
|
gl_rend_state_rect get_scissor();
|
|
void get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height);
|
|
gl_rend_state_rect get_viewport();
|
|
void get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height);
|
|
void set_blend_func(GLenum src, GLenum dst);
|
|
void set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb,
|
|
GLenum src_alpha, GLenum dst_alpha);
|
|
void set_blend_equation(GLenum mode);
|
|
void set_blend_equation_separate(
|
|
GLenum mode_rgb, GLenum mode_alpha);
|
|
void set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
|
void set_cull_face_mode(GLenum mode);
|
|
void set_depth_func(GLenum func);
|
|
void set_depth_mask(GLboolean flag);
|
|
void set_line_width(GLfloat width);
|
|
void set_primitive_restart_index(GLuint index);
|
|
void set_scissor(const gl_rend_state_rect& rect);
|
|
void set_scissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
|
void set_stencil_func(GLenum func, GLint ref, GLuint mask);
|
|
void set_stencil_mask(GLuint mask);
|
|
void set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass);
|
|
void set_viewport(const gl_rend_state_rect& rect);
|
|
void set_viewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
|
void tex_sub_image_2d(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
|
GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
|
|
void update();
|
|
void update_program();
|
|
void update_active_texture();
|
|
void update_curr_active_texture();
|
|
void update_texture();
|
|
void update_sampler();
|
|
void update_blend();
|
|
void update_blend_func();
|
|
void update_blend_equation();
|
|
void update_read_framebuffer();
|
|
void update_draw_framebuffer();
|
|
void update_vertex_array();
|
|
void update_uniform_buffer();
|
|
void update_shader_storage_buffer();
|
|
void update_color_mask();
|
|
void update_cull_face();
|
|
void update_cull_face_mode();
|
|
void update_depth_test();
|
|
void update_depth_mask();
|
|
void update_depth_func();
|
|
void update_line_width();
|
|
void update_multisample();
|
|
void update_primitive_restart();
|
|
void update_primitive_restart_index();
|
|
void update_scissor_test();
|
|
void update_scissor();
|
|
void update_stencil_test();
|
|
void update_stencil_mask();
|
|
void update_stencil_func();
|
|
void update_stencil_op();
|
|
void update_viewport();
|
|
void update_clear_color();
|
|
void update_clear_depth();
|
|
void update_clear_stencil();
|
|
void use_program(GLuint program);
|
|
};
|
|
|
|
gl_rend_state gl_rend_state_data[GL_REND_STATE_COUNT] = {
|
|
{ GL_REND_STATE_PRE_3D },
|
|
{ GL_REND_STATE_3D },
|
|
{ GL_REND_STATE_2D },
|
|
{ GL_REND_STATE_POST_2D },
|
|
};
|
|
|
|
p_gl_rend_state::p_gl_rend_state(gl_rend_state_index index) : ptr(gl_rend_state_data[index]) {
|
|
|
|
}
|
|
|
|
void p_gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture) {
|
|
ptr.active_bind_texture_2d(index, texture);
|
|
}
|
|
|
|
void p_gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture) {
|
|
ptr.active_bind_texture_cube_map(index, texture);
|
|
}
|
|
|
|
void p_gl_rend_state::active_texture(int32_t index) {
|
|
ptr.active_texture(index);
|
|
}
|
|
|
|
void p_gl_rend_state::begin_event(const char* message, int32_t length) {
|
|
ptr.begin_event(message, length);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_framebuffer(GLuint framebuffer) {
|
|
ptr.bind_framebuffer(framebuffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_read_framebuffer(GLuint framebuffer) {
|
|
ptr.bind_read_framebuffer(framebuffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_draw_framebuffer(GLuint framebuffer) {
|
|
ptr.bind_draw_framebuffer(framebuffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_vertex_array(GLuint array) {
|
|
ptr.bind_vertex_array(array);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_array_buffer(GLuint buffer) {
|
|
ptr.bind_array_buffer(buffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_element_array_buffer(GLuint buffer) {
|
|
ptr.bind_element_array_buffer(buffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_uniform_buffer(GLuint buffer) {
|
|
ptr.bind_uniform_buffer(buffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer) {
|
|
ptr.bind_uniform_buffer_base(index, buffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_uniform_buffer_range(GLuint index,
|
|
GLuint buffer, GLintptr offset, GLsizeiptr size) {
|
|
ptr.bind_uniform_buffer_range(index, buffer, offset, size);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_shader_storage_buffer(GLuint buffer) {
|
|
ptr.bind_shader_storage_buffer(buffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer) {
|
|
ptr.bind_shader_storage_buffer_base(index, buffer);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_shader_storage_buffer_range(GLuint index,
|
|
GLuint buffer, GLintptr offset, GLsizeiptr size) {
|
|
ptr.bind_shader_storage_buffer_range(index, buffer, offset, size);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_texture_2d(GLuint texture) {
|
|
ptr.bind_texture_2d(texture);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_texture_cube_map(GLuint texture) {
|
|
ptr.bind_texture_cube_map(texture);
|
|
}
|
|
|
|
void p_gl_rend_state::bind_sampler(int32_t index, GLuint sampler) {
|
|
ptr.bind_sampler(index, sampler);
|
|
}
|
|
|
|
void p_gl_rend_state::blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
|
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
|
|
ptr.blit_framebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
|
}
|
|
|
|
GLenum p_gl_rend_state::check_framebuffer_status(GLenum target) {
|
|
return ptr.check_framebuffer_status(target);
|
|
}
|
|
|
|
void p_gl_rend_state::clear(GLbitfield mask) {
|
|
ptr.clear(mask);
|
|
}
|
|
|
|
void p_gl_rend_state::clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
|
|
ptr.clear_buffer(buffer, drawbuffer, value);
|
|
}
|
|
|
|
void p_gl_rend_state::clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
|
ptr.clear_color(red, green, blue, alpha);
|
|
}
|
|
|
|
void p_gl_rend_state::clear_depth(GLfloat depth) {
|
|
ptr.clear_depth(depth);
|
|
}
|
|
|
|
void p_gl_rend_state::clear_stencil(GLint stencil) {
|
|
ptr.clear_stencil(stencil);
|
|
}
|
|
|
|
void p_gl_rend_state::copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel,
|
|
GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel,
|
|
GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
|
|
ptr.copy_image_sub_data(srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
|
|
dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
|
|
}
|
|
|
|
void p_gl_rend_state::copy_tex_sub_image_2d(GLenum target, GLint level,
|
|
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
ptr.copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height);
|
|
}
|
|
|
|
void p_gl_rend_state::disable_blend() {
|
|
ptr.disable_blend();
|
|
}
|
|
|
|
void p_gl_rend_state::disable_cull_face() {
|
|
ptr.disable_cull_face();
|
|
}
|
|
|
|
void p_gl_rend_state::disable_depth_test() {
|
|
ptr.disable_depth_test();
|
|
}
|
|
|
|
void p_gl_rend_state::disable_multisample() {
|
|
ptr.disable_multisample();
|
|
}
|
|
|
|
void p_gl_rend_state::disable_primitive_restart() {
|
|
ptr.disable_primitive_restart();
|
|
}
|
|
|
|
void p_gl_rend_state::disable_scissor_test() {
|
|
ptr.disable_scissor_test();
|
|
}
|
|
|
|
void p_gl_rend_state::disable_stencil_test() {
|
|
ptr.disable_stencil_test();
|
|
}
|
|
|
|
void p_gl_rend_state::draw_arrays(GLenum mode, GLint first, GLsizei count) {
|
|
ptr.draw_arrays(mode, first, count);
|
|
}
|
|
|
|
void p_gl_rend_state::draw_arrays_instanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
|
|
ptr.draw_arrays_instanced(mode, first, count, instancecount);
|
|
}
|
|
|
|
void p_gl_rend_state::draw_elements(GLenum mode,
|
|
GLsizei count, GLenum type, const void* indices) {
|
|
ptr.draw_elements(mode, count, type, indices);
|
|
}
|
|
|
|
void p_gl_rend_state::draw_range_elements(GLenum mode,
|
|
GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) {
|
|
ptr.draw_range_elements(mode, start, end, count, type, indices);
|
|
}
|
|
|
|
void p_gl_rend_state::enable_blend() {
|
|
ptr.enable_blend();
|
|
}
|
|
|
|
void p_gl_rend_state::enable_cull_face() {
|
|
ptr.enable_cull_face();
|
|
}
|
|
|
|
void p_gl_rend_state::enable_depth_test() {
|
|
ptr.enable_depth_test();
|
|
}
|
|
|
|
void p_gl_rend_state::enable_multisample() {
|
|
ptr.enable_multisample();
|
|
}
|
|
|
|
void p_gl_rend_state::enable_primitive_restart() {
|
|
ptr.enable_primitive_restart();
|
|
}
|
|
|
|
void p_gl_rend_state::enable_scissor_test() {
|
|
ptr.enable_scissor_test();
|
|
}
|
|
|
|
void p_gl_rend_state::enable_stencil_test() {
|
|
ptr.enable_stencil_test();
|
|
}
|
|
|
|
void p_gl_rend_state::end_event() {
|
|
ptr.end_event();
|
|
}
|
|
|
|
void p_gl_rend_state::finish() {
|
|
ptr.finish();
|
|
}
|
|
|
|
void p_gl_rend_state::generate_mipmap(GLenum target) {
|
|
ptr.generate_mipmap(target);
|
|
}
|
|
|
|
void p_gl_rend_state::generate_texture_mipmap(GLuint texture) {
|
|
ptr.generate_texture_mipmap(texture);
|
|
}
|
|
|
|
void p_gl_rend_state::get() {
|
|
ptr.get();
|
|
}
|
|
|
|
void p_gl_rend_state::get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha) {
|
|
ptr.get_clear_color(red, green, blue, alpha);
|
|
}
|
|
|
|
GLuint p_gl_rend_state::get_program() {
|
|
return ptr.get_program();
|
|
}
|
|
|
|
gl_rend_state_rect p_gl_rend_state::get_scissor() {
|
|
return ptr.get_scissor();
|
|
}
|
|
|
|
void p_gl_rend_state::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) {
|
|
ptr.get_scissor(x, y, width, height);
|
|
}
|
|
|
|
gl_rend_state_rect p_gl_rend_state::get_viewport() {
|
|
return ptr.get_viewport();
|
|
}
|
|
|
|
void p_gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) {
|
|
ptr.get_viewport(x, y, width, height);
|
|
}
|
|
|
|
void p_gl_rend_state::set_blend_func(GLenum src, GLenum dst) {
|
|
ptr.set_blend_func(src, dst);
|
|
}
|
|
|
|
void p_gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb,
|
|
GLenum src_alpha, GLenum dst_alpha) {
|
|
ptr.set_blend_func_separate(src_rgb, dst_rgb, src_alpha, dst_alpha);
|
|
}
|
|
|
|
void p_gl_rend_state::set_blend_equation(GLenum mode) {
|
|
ptr.set_blend_equation(mode);
|
|
}
|
|
|
|
void p_gl_rend_state::set_blend_equation_separate(
|
|
GLenum mode_rgb, GLenum mode_alpha) {
|
|
ptr.set_blend_equation_separate(mode_rgb, mode_alpha);
|
|
}
|
|
|
|
void p_gl_rend_state::set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
|
ptr.set_color_mask(red, green, blue, alpha);
|
|
}
|
|
|
|
void p_gl_rend_state::set_cull_face_mode(GLenum mode) {
|
|
ptr.set_cull_face_mode(mode);
|
|
}
|
|
|
|
void p_gl_rend_state::set_depth_func(GLenum func) {
|
|
ptr.set_depth_func(func);
|
|
}
|
|
|
|
void p_gl_rend_state::set_depth_mask(GLboolean flag) {
|
|
ptr.set_depth_mask(flag);
|
|
}
|
|
|
|
void p_gl_rend_state::set_line_width(GLfloat width) {
|
|
ptr.set_line_width(width);
|
|
}
|
|
|
|
void p_gl_rend_state::set_primitive_restart_index(GLuint index) {
|
|
ptr.set_primitive_restart_index(index);
|
|
}
|
|
|
|
void p_gl_rend_state::set_scissor(const gl_rend_state_rect& rect) {
|
|
ptr.set_scissor(rect);
|
|
}
|
|
|
|
void p_gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
ptr.set_scissor(x, y, width, height);
|
|
}
|
|
|
|
void p_gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask) {
|
|
ptr.set_stencil_func(func, ref, mask);
|
|
}
|
|
|
|
void p_gl_rend_state::set_stencil_mask(GLuint mask) {
|
|
ptr.set_stencil_mask(mask);
|
|
}
|
|
|
|
void p_gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass) {
|
|
ptr.set_stencil_op(sfail, dpfail, dppass);
|
|
}
|
|
|
|
void p_gl_rend_state::set_viewport(const gl_rend_state_rect& rect) {
|
|
ptr.set_viewport(rect);
|
|
}
|
|
|
|
void p_gl_rend_state::tex_sub_image_2d(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
|
GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) {
|
|
ptr.tex_sub_image_2d(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
|
}
|
|
|
|
void p_gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
ptr.set_viewport(x, y, width, height);
|
|
}
|
|
|
|
void p_gl_rend_state::use_program(GLuint program) {
|
|
ptr.use_program(program);
|
|
}
|
|
|
|
inline void gl_rend_state::active_bind_texture_2d(int32_t index, GLuint texture) {
|
|
active_texture(index);
|
|
bind_texture_2d(texture);
|
|
}
|
|
|
|
inline void gl_rend_state::active_bind_texture_cube_map(int32_t index, GLuint texture) {
|
|
active_texture(index);
|
|
bind_texture_cube_map(texture);
|
|
}
|
|
|
|
inline void gl_rend_state::active_texture(int32_t index) {
|
|
active_texture_index = index;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_ACTIVE_TEXTURE);
|
|
}
|
|
|
|
inline void gl_rend_state::begin_event(const char* message, int32_t length) {
|
|
if (GLAD_GL_VERSION_4_3)
|
|
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)length, message);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_framebuffer(GLuint framebuffer) {
|
|
read_framebuffer_binding = framebuffer;
|
|
draw_framebuffer_binding = framebuffer;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER
|
|
| GL_REND_STATE_UPDATE_READ_FRAMEBUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_read_framebuffer(GLuint framebuffer) {
|
|
read_framebuffer_binding = framebuffer;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_READ_FRAMEBUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_draw_framebuffer(GLuint framebuffer) {
|
|
draw_framebuffer_binding = framebuffer;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_vertex_array(GLuint array) {
|
|
vertex_array_binding = array;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_VERTEX_ARRAY);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_array_buffer(GLuint buffer) {
|
|
if (array_buffer_binding != buffer) {
|
|
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
|
array_buffer_binding = buffer;
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::bind_element_array_buffer(GLuint buffer) {
|
|
if (element_array_buffer_binding != buffer) {
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
|
|
element_array_buffer_binding = buffer;
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::bind_uniform_buffer(GLuint buffer) {
|
|
if (uniform_buffer_binding != buffer) {
|
|
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
|
|
uniform_buffer_binding = buffer;
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::bind_uniform_buffer_base(GLuint index, GLuint buffer) {
|
|
uniform_buffer_bindings[index] = buffer;
|
|
uniform_buffer_offsets[index] = 0;
|
|
uniform_buffer_sizes[index] = -1;
|
|
uniform_buffer_start_index = min_def(uniform_buffer_start_index, (int32_t)index);
|
|
uniform_buffer_end_index = max_def(uniform_buffer_end_index, (int32_t)index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_UNIFORM_BUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_uniform_buffer_range(GLuint index,
|
|
GLuint buffer, GLintptr offset, GLsizeiptr size) {
|
|
uniform_buffer_bindings[index] = buffer;
|
|
uniform_buffer_offsets[index] = offset;
|
|
uniform_buffer_sizes[index] = size;
|
|
uniform_buffer_start_index = min_def(uniform_buffer_start_index, (int32_t)index);
|
|
uniform_buffer_end_index = max_def(uniform_buffer_end_index, (int32_t)index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_UNIFORM_BUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_shader_storage_buffer(GLuint buffer) {
|
|
if (shader_storage_buffer_binding != buffer) {
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
|
|
shader_storage_buffer_binding = buffer;
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::bind_shader_storage_buffer_base(GLuint index, GLuint buffer) {
|
|
shader_storage_buffer_bindings[index] = buffer;
|
|
shader_storage_buffer_offsets[index] = 0;
|
|
shader_storage_buffer_sizes[index] = -1;
|
|
shader_storage_buffer_start_index = min_def(shader_storage_buffer_start_index, (int32_t)index);
|
|
shader_storage_buffer_end_index = max_def(shader_storage_buffer_end_index, (int32_t)index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_shader_storage_buffer_range(GLuint index,
|
|
GLuint buffer, GLintptr offset, GLsizeiptr size) {
|
|
shader_storage_buffer_bindings[index] = buffer;
|
|
shader_storage_buffer_offsets[index] = offset;
|
|
shader_storage_buffer_sizes[index] = size;
|
|
shader_storage_buffer_start_index = min_def(shader_storage_buffer_start_index, (int32_t)index);
|
|
shader_storage_buffer_end_index = max_def(shader_storage_buffer_end_index, (int32_t)index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_texture_2d(GLuint texture) {
|
|
texture_binding_2d[active_texture_index] = texture;
|
|
texture_binding_start_index = min_def(texture_binding_start_index, (int32_t)active_texture_index);
|
|
texture_binding_end_index = max_def(texture_binding_end_index, (int32_t)active_texture_index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_TEXTURE);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_texture_cube_map(GLuint texture) {
|
|
texture_binding_cube_map[active_texture_index] = texture;
|
|
texture_binding_start_index = min_def(texture_binding_start_index, (int32_t)active_texture_index);
|
|
texture_binding_end_index = max_def(texture_binding_end_index, (int32_t)active_texture_index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_TEXTURE);
|
|
}
|
|
|
|
inline void gl_rend_state::bind_sampler(int32_t index, GLuint sampler) {
|
|
sampler_binding[index] = sampler;
|
|
sampler_binding_start_index = min_def(sampler_binding_start_index, (int32_t)index);
|
|
sampler_binding_end_index = max_def(sampler_binding_end_index, (int32_t)index);
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SAMPLER);
|
|
}
|
|
|
|
inline void gl_rend_state::blit_framebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
|
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
|
|
update_read_framebuffer();
|
|
update_draw_framebuffer();
|
|
|
|
if (mask & GL_COLOR_BUFFER_BIT)
|
|
update_color_mask();
|
|
|
|
if (mask & GL_DEPTH_BUFFER_BIT) {
|
|
update_depth_test();
|
|
update_depth_mask();
|
|
}
|
|
|
|
if (mask & GL_STENCIL_BUFFER_BIT) {
|
|
update_stencil_test();
|
|
update_stencil_mask();
|
|
}
|
|
|
|
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
|
|
}
|
|
|
|
inline GLenum gl_rend_state::check_framebuffer_status(GLenum target) {
|
|
switch (target) {
|
|
case GL_READ_FRAMEBUFFER:
|
|
update_read_framebuffer();
|
|
break;
|
|
case GL_DRAW_FRAMEBUFFER:
|
|
case GL_FRAMEBUFFER:
|
|
update_draw_framebuffer();
|
|
break;
|
|
}
|
|
|
|
return glCheckFramebufferStatus(target);
|
|
}
|
|
|
|
inline void gl_rend_state::clear(GLbitfield mask) {
|
|
update_draw_framebuffer();
|
|
|
|
if (mask & GL_COLOR_BUFFER_BIT)
|
|
update_color_mask();
|
|
|
|
if (mask & GL_DEPTH_BUFFER_BIT) {
|
|
update_depth_test();
|
|
update_depth_mask();
|
|
}
|
|
|
|
update_scissor_test();
|
|
update_scissor();
|
|
|
|
if (mask & GL_STENCIL_BUFFER_BIT) {
|
|
update_stencil_test();
|
|
update_stencil_mask();
|
|
}
|
|
|
|
if (mask & GL_COLOR_BUFFER_BIT)
|
|
update_clear_color();
|
|
|
|
if (mask & GL_DEPTH_BUFFER_BIT)
|
|
update_clear_depth();
|
|
|
|
if (mask & GL_STENCIL_BUFFER_BIT)
|
|
update_clear_stencil();
|
|
|
|
glClear(mask);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
inline void gl_rend_state::clear_buffer(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
|
|
update_draw_framebuffer();
|
|
|
|
if (buffer == GL_COLOR)
|
|
update_color_mask();
|
|
|
|
if (buffer == GL_DEPTH) {
|
|
update_depth_test();
|
|
update_depth_mask();
|
|
}
|
|
|
|
update_scissor_test();
|
|
update_scissor();
|
|
|
|
if (buffer == GL_STENCIL) {
|
|
update_stencil_test();
|
|
update_stencil_mask();
|
|
}
|
|
|
|
glClearBufferfv(buffer, drawbuffer, value);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
inline void gl_rend_state::clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
|
clear_color_value[0] = red;
|
|
clear_color_value[1] = green;
|
|
clear_color_value[2] = blue;
|
|
clear_color_value[3] = alpha;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_COLOR);
|
|
}
|
|
|
|
inline void gl_rend_state::clear_depth(GLfloat depth) {
|
|
clear_depth_value = depth;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_DEPTH);
|
|
}
|
|
|
|
inline void gl_rend_state::clear_stencil(GLint stencil) {
|
|
clear_stencil_value = stencil;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_CLEAR_STENCIL);
|
|
}
|
|
|
|
inline void gl_rend_state::copy_image_sub_data(GLuint srcName, GLenum srcTarget, GLint srcLevel,
|
|
GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel,
|
|
GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
|
|
glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
|
|
dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
inline void gl_rend_state::copy_tex_sub_image_2d(GLenum target, GLint level,
|
|
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
update_active_texture();
|
|
update_curr_active_texture();
|
|
update_read_framebuffer();
|
|
glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_blend() {
|
|
blend = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_cull_face() {
|
|
cull_face = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_depth_test() {
|
|
depth_test = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_TEST);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_multisample() {
|
|
multisample = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_MULTISAMPLE);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_primitive_restart() {
|
|
primitive_restart = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_scissor_test() {
|
|
scissor_test = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR_TEST);
|
|
}
|
|
|
|
inline void gl_rend_state::disable_stencil_test() {
|
|
stencil_test = GL_FALSE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_TEST);
|
|
}
|
|
|
|
inline void gl_rend_state::draw_arrays(GLenum mode, GLint first, GLsizei count) {
|
|
update();
|
|
glDrawArrays(mode, first, count);
|
|
}
|
|
|
|
inline void gl_rend_state::draw_arrays_instanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
|
|
update();
|
|
glDrawArraysInstanced(mode, first, count, instancecount);
|
|
}
|
|
|
|
inline void gl_rend_state::draw_elements(GLenum mode,
|
|
GLsizei count, GLenum type, const void* indices) {
|
|
switch (mode) {
|
|
case GL_TRIANGLE_STRIP:
|
|
uint32_t index;
|
|
switch (type) {
|
|
case GL_UNSIGNED_BYTE:
|
|
index = 0xFF;
|
|
break;
|
|
case GL_UNSIGNED_SHORT:
|
|
index = 0xFFFF;
|
|
break;
|
|
case GL_UNSIGNED_INT:
|
|
default:
|
|
index = 0xFFFFFFFF;
|
|
break;
|
|
}
|
|
|
|
enable_primitive_restart();
|
|
set_primitive_restart_index(index);
|
|
break;
|
|
}
|
|
|
|
update();
|
|
glDrawElements(mode, count, type, indices);
|
|
|
|
switch (mode) {
|
|
case GL_TRIANGLE_STRIP:
|
|
disable_primitive_restart();
|
|
break;
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::draw_range_elements(GLenum mode,
|
|
GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) {
|
|
switch (mode) {
|
|
case GL_TRIANGLE_STRIP:
|
|
uint32_t index;
|
|
switch (type) {
|
|
case GL_UNSIGNED_BYTE:
|
|
index = 0xFF;
|
|
break;
|
|
case GL_UNSIGNED_SHORT:
|
|
index = 0xFFFF;
|
|
break;
|
|
case GL_UNSIGNED_INT:
|
|
default:
|
|
index = 0xFFFFFFFF;
|
|
break;
|
|
}
|
|
|
|
enable_primitive_restart();
|
|
set_primitive_restart_index(index);
|
|
break;
|
|
}
|
|
|
|
update();
|
|
glDrawRangeElements(mode, start, end, count, type, indices);
|
|
|
|
switch (mode) {
|
|
case GL_TRIANGLE_STRIP:
|
|
disable_primitive_restart();
|
|
break;
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::enable_blend() {
|
|
blend = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND);
|
|
}
|
|
|
|
inline void gl_rend_state::enable_cull_face() {
|
|
cull_face = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE);
|
|
}
|
|
|
|
inline void gl_rend_state::enable_depth_test() {
|
|
depth_test = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_TEST);
|
|
}
|
|
|
|
inline void gl_rend_state::enable_multisample() {
|
|
multisample = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_MULTISAMPLE);
|
|
}
|
|
|
|
inline void gl_rend_state::enable_primitive_restart() {
|
|
primitive_restart = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART);
|
|
}
|
|
|
|
inline void gl_rend_state::enable_scissor_test() {
|
|
scissor_test = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR_TEST);
|
|
}
|
|
|
|
inline void gl_rend_state::enable_stencil_test() {
|
|
stencil_test = GL_TRUE;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_TEST);
|
|
}
|
|
|
|
inline void gl_rend_state::end_event() {
|
|
if (GLAD_GL_VERSION_4_3)
|
|
glPopDebugGroup();
|
|
}
|
|
|
|
inline void gl_rend_state::finish() {
|
|
bind_vertex_array(0);
|
|
update_vertex_array();
|
|
|
|
bind_array_buffer(0);
|
|
bind_element_array_buffer(0);
|
|
bind_uniform_buffer(0);
|
|
bind_shader_storage_buffer(0);
|
|
|
|
set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
set_depth_mask(GL_TRUE);
|
|
set_stencil_mask(GL_TRUE);
|
|
|
|
update_blend();
|
|
update_color_mask();
|
|
update_depth_test();
|
|
update_depth_mask();
|
|
update_primitive_restart();
|
|
update_scissor_test();
|
|
update_stencil_test();
|
|
update_stencil_mask();
|
|
}
|
|
|
|
inline void gl_rend_state::generate_mipmap(GLenum target) {
|
|
update_curr_active_texture();
|
|
glGenerateMipmap(target);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
inline void gl_rend_state::generate_texture_mipmap(GLuint texture) {
|
|
glGenerateTextureMipmap(texture);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
void gl_rend_state::get() {
|
|
glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&program);
|
|
|
|
GLenum active_texture = GL_TEXTURE0;
|
|
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&active_texture);
|
|
active_texture_index = active_texture - GL_TEXTURE0;
|
|
|
|
texture_binding_start_index = 32;
|
|
texture_binding_end_index = -1;
|
|
sampler_binding_start_index = 32;
|
|
sampler_binding_end_index = -1;
|
|
|
|
if (GLAD_GL_VERSION_4_5) {
|
|
for (GLuint i = 0; i < 32; i++) {
|
|
glGetIntegeri_v(GL_TEXTURE_BINDING_2D, i, (GLint*)&texture_binding_2d[i]);
|
|
glGetIntegeri_v(GL_TEXTURE_BINDING_CUBE_MAP, i, (GLint*)&texture_binding_cube_map[i]);
|
|
glGetIntegeri_v(GL_SAMPLER_BINDING, i, (GLint*)&sampler_binding[i]);
|
|
}
|
|
}
|
|
else {
|
|
for (GLuint i = 0; i < 32; i++) {
|
|
glActiveTexture((GLenum)(GL_TEXTURE0 + i));
|
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&texture_binding_2d[i]);
|
|
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, (GLint*)&texture_binding_cube_map[i]);
|
|
glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&sampler_binding[i]);
|
|
}
|
|
glActiveTexture(active_texture);
|
|
}
|
|
|
|
glGetBooleanv(GL_BLEND, &blend);
|
|
glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&blend_src_rgb);
|
|
glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&blend_src_alpha);
|
|
glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&blend_dst_rgb);
|
|
glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&blend_dst_alpha);
|
|
glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&blend_mode_rgb);
|
|
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&blend_mode_alpha);
|
|
|
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&read_framebuffer_binding);
|
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&draw_framebuffer_binding);
|
|
|
|
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&vertex_array_binding);
|
|
|
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&array_buffer_binding);
|
|
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&element_array_buffer_binding);
|
|
|
|
uniform_buffer_start_index = 14;
|
|
uniform_buffer_end_index = -1;
|
|
|
|
glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, (GLint*)&uniform_buffer_binding);
|
|
for (GLuint i = 0; i < 14; i++) {
|
|
glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, i, (GLint*)&uniform_buffer_bindings[i]);
|
|
glGetInteger64i_v(GL_UNIFORM_BUFFER_START, i, (GLint64*)&uniform_buffer_offsets[i]);
|
|
glGetInteger64i_v(GL_UNIFORM_BUFFER_SIZE, i, (GLint64*)&uniform_buffer_sizes[i]);
|
|
}
|
|
|
|
shader_storage_buffer_start_index = 14;
|
|
shader_storage_buffer_end_index = -1;
|
|
|
|
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, (GLint*)&shader_storage_buffer_binding);
|
|
for (GLuint i = 0; i < 14; i++) {
|
|
glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint*)&shader_storage_buffer_bindings[i]);
|
|
glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_START, i, (GLint64*)&shader_storage_buffer_offsets[i]);
|
|
glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_SIZE, i, (GLint64*)&shader_storage_buffer_sizes[i]);
|
|
}
|
|
|
|
glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
|
|
|
|
glGetBooleanv(GL_CULL_FACE, &cull_face);
|
|
glGetIntegerv(GL_CULL_FACE_MODE, (GLint*)&cull_face_mode);
|
|
|
|
glGetBooleanv(GL_DEPTH_TEST, &depth_test);
|
|
glGetIntegerv(GL_DEPTH_FUNC, (GLint*)&depth_func);
|
|
glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask);
|
|
|
|
glGetFloatv(GL_LINE_WIDTH, &line_width);
|
|
|
|
glGetBooleanv(GL_MULTISAMPLE, &multisample);
|
|
|
|
glGetBooleanv(GL_PRIMITIVE_RESTART, &primitive_restart);
|
|
glGetIntegerv(GL_PRIMITIVE_RESTART_INDEX, (GLint*)&primitive_restart_index);
|
|
|
|
glGetIntegerv(GL_SCISSOR_BOX, (GLint*)&scissor_box);
|
|
glGetBooleanv(GL_SCISSOR_TEST, &scissor_test);
|
|
|
|
glGetBooleanv(GL_STENCIL_TEST, &stencil_test);
|
|
glGetIntegerv(GL_STENCIL_FUNC, (GLint*)&stencil_func);
|
|
glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint*)&stencil_value_mask);
|
|
glGetIntegerv(GL_STENCIL_FAIL, (GLint*)&stencil_fail);
|
|
glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint*)&stencil_dpfail);
|
|
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint*)&stencil_dppass);
|
|
glGetIntegerv(GL_STENCIL_REF, &stencil_ref);
|
|
glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint*)&stencil_mask);
|
|
|
|
glGetIntegerv(GL_VIEWPORT, (GLint*)&viewport);
|
|
|
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color_value);
|
|
|
|
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clear_depth_value);
|
|
|
|
glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil_value);
|
|
|
|
curr_program = program;
|
|
|
|
curr_active_texture_index = active_texture_index;
|
|
|
|
for (GLuint i = 0; i < 32; i++) {
|
|
curr_texture_binding_2d[i] = texture_binding_2d[i];
|
|
curr_texture_binding_cube_map[i] = texture_binding_cube_map[i];
|
|
curr_sampler_binding[i] = sampler_binding[i];
|
|
}
|
|
|
|
curr_blend = blend;
|
|
curr_blend_src_rgb = blend_src_rgb;
|
|
curr_blend_src_alpha = blend_src_alpha;
|
|
curr_blend_dst_rgb = blend_dst_rgb;
|
|
curr_blend_dst_alpha = blend_dst_alpha;
|
|
curr_blend_mode_rgb = blend_mode_rgb;
|
|
curr_blend_mode_alpha = blend_mode_alpha;
|
|
|
|
curr_read_framebuffer_binding = read_framebuffer_binding;
|
|
curr_draw_framebuffer_binding = draw_framebuffer_binding;
|
|
|
|
curr_vertex_array_binding = vertex_array_binding;
|
|
|
|
for (GLuint i = 0; i < 14; i++) {
|
|
curr_uniform_buffer_bindings[i] = uniform_buffer_bindings[i];
|
|
curr_uniform_buffer_offsets[i] = uniform_buffer_offsets[i];
|
|
curr_uniform_buffer_sizes[i] = uniform_buffer_sizes[i];
|
|
}
|
|
|
|
for (GLuint i = 0; i < 14; i++) {
|
|
curr_shader_storage_buffer_bindings[i] = shader_storage_buffer_bindings[i];
|
|
curr_shader_storage_buffer_offsets[i] = shader_storage_buffer_offsets[i];
|
|
curr_shader_storage_buffer_sizes[i] = shader_storage_buffer_sizes[i];
|
|
}
|
|
|
|
memcpy(curr_color_mask, color_mask, sizeof(GLboolean) * 4);
|
|
|
|
curr_cull_face = cull_face;
|
|
curr_cull_face_mode = cull_face_mode;
|
|
|
|
curr_depth_test = depth_test;
|
|
curr_depth_func = depth_func;
|
|
curr_depth_mask = depth_mask;
|
|
|
|
curr_line_width = line_width;
|
|
curr_multisample = multisample;
|
|
|
|
curr_primitive_restart = primitive_restart;
|
|
curr_primitive_restart_index = primitive_restart_index;
|
|
|
|
curr_scissor_box = scissor_box;
|
|
curr_scissor_test = scissor_test;
|
|
|
|
curr_stencil_test = stencil_test;
|
|
curr_stencil_func = stencil_func;
|
|
curr_stencil_value_mask = stencil_value_mask;
|
|
curr_stencil_fail = stencil_fail;
|
|
curr_stencil_dpfail = stencil_dpfail;
|
|
curr_stencil_dppass = stencil_dppass;
|
|
curr_stencil_ref = stencil_ref;
|
|
curr_stencil_mask = stencil_mask;
|
|
|
|
curr_viewport = viewport;
|
|
|
|
memcpy(curr_clear_color_value, clear_color_value, sizeof(GLboolean) * 4);
|
|
curr_clear_depth_value = clear_depth_value;
|
|
curr_clear_stencil_value = clear_stencil_value;
|
|
|
|
flags = (gl_rend_state_flags)0;
|
|
update_flags = (gl_rend_state_update_flags)0;
|
|
}
|
|
|
|
inline void gl_rend_state::get_clear_color(GLfloat& red, GLfloat& green, GLfloat& blue, GLfloat& alpha) {
|
|
red = clear_color_value[0];
|
|
green = clear_color_value[1];
|
|
blue = clear_color_value[2];
|
|
alpha = clear_color_value[3];
|
|
}
|
|
|
|
inline GLuint gl_rend_state::get_program() {
|
|
return program;
|
|
}
|
|
|
|
inline gl_rend_state_rect gl_rend_state::get_scissor() {
|
|
return scissor_box;
|
|
}
|
|
|
|
inline void gl_rend_state::get_scissor(GLint& x, GLint& y, GLsizei& width, GLsizei& height) {
|
|
x = scissor_box.x;
|
|
y = scissor_box.y;
|
|
width = scissor_box.width;
|
|
height = scissor_box.height;
|
|
}
|
|
|
|
inline gl_rend_state_rect gl_rend_state::get_viewport() {
|
|
return viewport;
|
|
}
|
|
|
|
inline void gl_rend_state::get_viewport(GLint& x, GLint& y, GLsizei& width, GLsizei& height) {
|
|
x = viewport.x;
|
|
y = viewport.y;
|
|
width = viewport.width;
|
|
height = viewport.height;
|
|
}
|
|
|
|
inline void gl_rend_state::set_blend_func(GLenum src, GLenum dst) {
|
|
blend_src_rgb = src;
|
|
blend_dst_rgb = dst;
|
|
blend_src_alpha = GL_ONE;
|
|
blend_dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_FUNC);
|
|
}
|
|
|
|
inline void gl_rend_state::set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb,
|
|
GLenum src_alpha, GLenum dst_alpha) {
|
|
blend_src_rgb = src_rgb;
|
|
blend_dst_rgb = dst_rgb;
|
|
blend_src_alpha = src_alpha;
|
|
blend_dst_alpha = dst_alpha;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_FUNC);
|
|
}
|
|
|
|
inline void gl_rend_state::set_blend_equation(GLenum mode) {
|
|
blend_mode_rgb = mode;
|
|
blend_mode_alpha = mode;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_EQUATION);
|
|
}
|
|
|
|
inline void gl_rend_state::set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha) {
|
|
blend_mode_rgb = mode_rgb;
|
|
blend_mode_alpha = mode_alpha;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_BLEND_EQUATION);
|
|
}
|
|
|
|
inline void gl_rend_state::set_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
|
color_mask[0] = red;
|
|
color_mask[1] = green;
|
|
color_mask[2] = blue;
|
|
color_mask[3] = alpha;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_COLOR_MASK);
|
|
}
|
|
|
|
inline void gl_rend_state::set_cull_face_mode(GLenum mode) {
|
|
cull_face_mode = mode;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_CULL_FACE_MODE);
|
|
}
|
|
|
|
inline void gl_rend_state::set_depth_func(GLenum func) {
|
|
depth_func = func;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_FUNC);
|
|
}
|
|
|
|
inline void gl_rend_state::set_depth_mask(GLboolean flag) {
|
|
depth_mask = flag;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_DEPTH_MASK);
|
|
}
|
|
|
|
inline void gl_rend_state::set_line_width(GLfloat width) {
|
|
line_width = width;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_LINE_WIDTH);
|
|
}
|
|
|
|
inline void gl_rend_state::set_primitive_restart_index(GLuint index) {
|
|
primitive_restart_index = index;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX);
|
|
}
|
|
|
|
inline void gl_rend_state::set_scissor(const gl_rend_state_rect& rect) {
|
|
scissor_box = rect;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR);
|
|
}
|
|
|
|
inline void gl_rend_state::set_scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
scissor_box.x = x;
|
|
scissor_box.y = y;
|
|
scissor_box.width = width;
|
|
scissor_box.height = height;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_SCISSOR);
|
|
}
|
|
|
|
inline void gl_rend_state::set_stencil_func(GLenum func, GLint ref, GLuint mask) {
|
|
stencil_func = func;
|
|
stencil_ref = ref;
|
|
stencil_value_mask = mask;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_FUNC);
|
|
}
|
|
|
|
inline void gl_rend_state::set_stencil_mask(GLuint mask) {
|
|
stencil_mask = mask;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_MASK);
|
|
}
|
|
|
|
inline void gl_rend_state::set_stencil_op(GLenum sfail, GLenum dpfail, GLenum dppass) {
|
|
stencil_fail = sfail;
|
|
stencil_dpfail = dpfail;
|
|
stencil_dppass = dppass;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_STENCIL_OP);
|
|
}
|
|
|
|
inline void gl_rend_state::set_viewport(const gl_rend_state_rect& rect) {
|
|
viewport = rect;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_VIEWPORT);
|
|
}
|
|
|
|
inline void gl_rend_state::set_viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
viewport.x = x;
|
|
viewport.y = y;
|
|
viewport.width = width;
|
|
viewport.height = height;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_VIEWPORT);
|
|
}
|
|
|
|
inline void gl_rend_state::tex_sub_image_2d(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
|
GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) {
|
|
update_curr_active_texture();
|
|
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
void gl_rend_state::update() {
|
|
if (!update_flags)
|
|
return;
|
|
|
|
update_program();
|
|
update_texture();
|
|
update_sampler();
|
|
update_blend();
|
|
update_blend_func();
|
|
update_blend_equation();
|
|
update_read_framebuffer();
|
|
update_draw_framebuffer();
|
|
update_vertex_array();
|
|
update_uniform_buffer();
|
|
update_shader_storage_buffer();
|
|
update_color_mask();
|
|
update_cull_face();
|
|
update_cull_face_mode();
|
|
update_depth_test();
|
|
update_depth_mask();
|
|
update_depth_func();
|
|
update_line_width();
|
|
update_multisample();
|
|
update_primitive_restart();
|
|
update_primitive_restart_index();
|
|
update_scissor_test();
|
|
update_scissor();
|
|
update_stencil_test();
|
|
update_stencil_mask();
|
|
update_stencil_func();
|
|
update_stencil_op();
|
|
update_viewport();
|
|
update_clear_color();
|
|
update_clear_depth();
|
|
update_clear_stencil();
|
|
|
|
enum_or(flags, GL_REND_STATE_EXECUTE);
|
|
}
|
|
|
|
inline void gl_rend_state::update_program() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_PROGRAM) {
|
|
if (curr_program != program) {
|
|
glUseProgram(program);
|
|
curr_program = program;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_PROGRAM);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_active_texture() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_ACTIVE_TEXTURE) {
|
|
if (curr_active_texture_index != active_texture_index) {
|
|
glActiveTexture((GLenum)(GL_TEXTURE0 + active_texture_index));
|
|
curr_active_texture_index = active_texture_index;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_ACTIVE_TEXTURE);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_curr_active_texture() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_TEXTURE) {
|
|
GLuint index = curr_active_texture_index;
|
|
bool bind = false;
|
|
if (curr_texture_binding_2d[index] != texture_binding_2d[index]) {
|
|
glBindTexture(GL_TEXTURE_2D, texture_binding_2d[curr_active_texture_index]);
|
|
curr_texture_binding_2d[index] = texture_binding_2d[index];
|
|
bind = true;
|
|
}
|
|
else if (curr_texture_binding_cube_map[index] != texture_binding_cube_map[index]) {
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, texture_binding_cube_map[index]);
|
|
curr_texture_binding_cube_map[index] = texture_binding_cube_map[index];
|
|
bind = true;
|
|
}
|
|
|
|
if (bind) {
|
|
if (texture_binding_start_index == curr_active_texture_index)
|
|
texture_binding_start_index++;
|
|
else if (texture_binding_end_index == curr_active_texture_index)
|
|
texture_binding_end_index--;
|
|
|
|
if (texture_binding_start_index > texture_binding_end_index) {
|
|
texture_binding_start_index = 32;
|
|
texture_binding_end_index = -1;
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_TEXTURE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_texture() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_TEXTURE) {
|
|
for (int32_t index = texture_binding_start_index;
|
|
index <= texture_binding_end_index; index++)
|
|
if (curr_texture_binding_2d[index] != texture_binding_2d[index]) {
|
|
if (GLAD_GL_VERSION_4_5)
|
|
glBindTextureUnit(index, texture_binding_2d[index]);
|
|
else {
|
|
if (curr_active_texture_index != index)
|
|
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texture_binding_2d[index]);
|
|
curr_active_texture_index = index;
|
|
}
|
|
curr_texture_binding_2d[index] = texture_binding_2d[index];
|
|
}
|
|
else if (curr_texture_binding_cube_map[index] != texture_binding_cube_map[index]) {
|
|
if (GLAD_GL_VERSION_4_5)
|
|
glBindTextureUnit(index, texture_binding_cube_map[index]);
|
|
else {
|
|
if (curr_active_texture_index != index)
|
|
glActiveTexture((GLenum)(GL_TEXTURE0 + index));
|
|
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, texture_binding_cube_map[index]);
|
|
curr_active_texture_index = index;
|
|
}
|
|
curr_texture_binding_cube_map[index] = texture_binding_cube_map[index];
|
|
}
|
|
|
|
texture_binding_start_index = 32;
|
|
texture_binding_end_index = -1;
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_TEXTURE);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_sampler() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_SAMPLER) {
|
|
for (int32_t index = sampler_binding_start_index;
|
|
index <= sampler_binding_end_index; index++)
|
|
if (curr_sampler_binding[index] != sampler_binding[index]) {
|
|
glBindSampler(index, sampler_binding[index]);
|
|
curr_sampler_binding[index] = sampler_binding[index];
|
|
}
|
|
|
|
sampler_binding_start_index = 32;
|
|
sampler_binding_end_index = -1;
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_SAMPLER);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_blend() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_BLEND) {
|
|
if (curr_blend != blend) {
|
|
(blend ? glEnable : glDisable)(GL_BLEND);
|
|
curr_blend = blend;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_blend_func() {
|
|
if (curr_blend && (update_flags & GL_REND_STATE_UPDATE_BLEND_FUNC)) {
|
|
if (curr_blend_src_rgb != blend_src_rgb || curr_blend_dst_rgb != blend_dst_rgb
|
|
|| curr_blend_src_alpha != blend_src_alpha || curr_blend_dst_alpha != blend_dst_alpha) {
|
|
glBlendFuncSeparate(blend_src_rgb, blend_dst_rgb, blend_src_alpha, blend_dst_alpha);
|
|
curr_blend_src_rgb = blend_src_rgb;
|
|
curr_blend_dst_rgb = blend_dst_rgb;
|
|
curr_blend_src_alpha = blend_src_alpha;
|
|
curr_blend_dst_alpha = blend_dst_alpha;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND_FUNC);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_blend_equation() {
|
|
if (curr_blend && (update_flags & GL_REND_STATE_UPDATE_BLEND_EQUATION)) {
|
|
if (curr_blend_mode_rgb != blend_mode_rgb || curr_blend_mode_alpha != blend_mode_alpha) {
|
|
glBlendEquationSeparate(blend_mode_rgb, blend_mode_alpha);
|
|
curr_blend_mode_rgb = blend_mode_rgb;
|
|
curr_blend_mode_alpha = blend_mode_alpha;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_BLEND_EQUATION);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_read_framebuffer() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_READ_FRAMEBUFFER) {
|
|
if (curr_read_framebuffer_binding != read_framebuffer_binding) {
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer_binding);
|
|
if (read_framebuffer_binding) {
|
|
GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
|
|
if (status != GL_FRAMEBUFFER_COMPLETE)
|
|
printf_debug("GL Error: Bind Read Framebuffer Status - 0x%04X\n", status);
|
|
gl_get_error_print();
|
|
}
|
|
curr_read_framebuffer_binding = read_framebuffer_binding;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_READ_FRAMEBUFFER);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_draw_framebuffer() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER) {
|
|
if (curr_draw_framebuffer_binding != draw_framebuffer_binding) {
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw_framebuffer_binding);
|
|
if (draw_framebuffer_binding) {
|
|
GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
|
|
if (status != GL_FRAMEBUFFER_COMPLETE)
|
|
printf_debug("GL Error: Bind Draw Framebuffer Status - 0x%04X\n", status);
|
|
gl_get_error_print();
|
|
}
|
|
curr_draw_framebuffer_binding = draw_framebuffer_binding;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_DRAW_FRAMEBUFFER);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_vertex_array() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_VERTEX_ARRAY) {
|
|
if (curr_vertex_array_binding != vertex_array_binding) {
|
|
glBindVertexArray(vertex_array_binding);
|
|
curr_vertex_array_binding = vertex_array_binding;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_VERTEX_ARRAY);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_uniform_buffer() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_UNIFORM_BUFFER) {
|
|
for (int32_t index = uniform_buffer_start_index;
|
|
index <= uniform_buffer_end_index; index++) {
|
|
if (curr_uniform_buffer_bindings[index] == uniform_buffer_bindings[index]
|
|
&& curr_uniform_buffer_offsets[index] == uniform_buffer_offsets[index]
|
|
&& curr_uniform_buffer_sizes[index] == uniform_buffer_sizes[index])
|
|
continue;
|
|
|
|
if (uniform_buffer_offsets[index] == 0 && uniform_buffer_sizes[index] == -1)
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, index, uniform_buffer_bindings[index]);
|
|
else
|
|
glBindBufferRange(GL_UNIFORM_BUFFER, index, uniform_buffer_bindings[index],
|
|
uniform_buffer_offsets[index], uniform_buffer_sizes[index]);
|
|
uniform_buffer_binding = uniform_buffer_bindings[index];
|
|
curr_uniform_buffer_bindings[index] = uniform_buffer_bindings[index];
|
|
curr_uniform_buffer_offsets[index] = uniform_buffer_offsets[index];
|
|
curr_uniform_buffer_sizes[index] = uniform_buffer_sizes[index];
|
|
}
|
|
|
|
uniform_buffer_start_index = 14;
|
|
uniform_buffer_end_index = -1;
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_UNIFORM_BUFFER);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_shader_storage_buffer() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER) {
|
|
for (int32_t index = shader_storage_buffer_start_index;
|
|
index <= shader_storage_buffer_end_index; index++) {
|
|
if (curr_shader_storage_buffer_bindings[index] == shader_storage_buffer_bindings[index]
|
|
&& curr_shader_storage_buffer_offsets[index] == shader_storage_buffer_offsets[index]
|
|
&& curr_shader_storage_buffer_sizes[index] == shader_storage_buffer_sizes[index])
|
|
continue;
|
|
|
|
if (shader_storage_buffer_offsets[index] == 0 && shader_storage_buffer_sizes[index] == -1)
|
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, shader_storage_buffer_bindings[index]);
|
|
else
|
|
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, shader_storage_buffer_bindings[index],
|
|
shader_storage_buffer_offsets[index], shader_storage_buffer_sizes[index]);
|
|
shader_storage_buffer_binding = shader_storage_buffer_bindings[index];
|
|
curr_shader_storage_buffer_bindings[index] = shader_storage_buffer_bindings[index];
|
|
curr_shader_storage_buffer_offsets[index] = shader_storage_buffer_offsets[index];
|
|
curr_shader_storage_buffer_sizes[index] = shader_storage_buffer_sizes[index];
|
|
}
|
|
|
|
shader_storage_buffer_start_index = 14;
|
|
shader_storage_buffer_end_index = -1;
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_SHADER_STORAGE_BUFFER);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_color_mask() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_COLOR_MASK) {
|
|
if (memcmp(&curr_color_mask, &color_mask, sizeof(GLboolean) * 4)) {
|
|
glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
|
|
memcpy(&curr_color_mask, &color_mask, sizeof(GLboolean) * 4);
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_COLOR_MASK);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_cull_face() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_CULL_FACE) {
|
|
if (curr_cull_face != cull_face) {
|
|
(cull_face ? glEnable : glDisable)(GL_CULL_FACE);
|
|
curr_cull_face = cull_face;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_CULL_FACE);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_cull_face_mode() {
|
|
if (curr_cull_face && (update_flags & GL_REND_STATE_UPDATE_CULL_FACE_MODE)) {
|
|
if (curr_cull_face_mode != cull_face_mode) {
|
|
glCullFace(cull_face_mode);
|
|
curr_cull_face_mode = cull_face_mode;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_CULL_FACE_MODE);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_depth_test() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_DEPTH_TEST) {
|
|
if (curr_depth_test != depth_test) {
|
|
(depth_test ? glEnable : glDisable)(GL_DEPTH_TEST);
|
|
curr_depth_test = depth_test;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_TEST);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_depth_mask() {
|
|
if (curr_depth_test && (update_flags & GL_REND_STATE_UPDATE_DEPTH_MASK)) {
|
|
if (curr_depth_mask != depth_mask) {
|
|
glDepthMask(depth_mask);
|
|
curr_depth_mask = depth_mask;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_MASK);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_depth_func() {
|
|
if (curr_depth_test && (update_flags & GL_REND_STATE_UPDATE_DEPTH_FUNC)) {
|
|
if (curr_depth_func != depth_func) {
|
|
glDepthFunc(depth_func);
|
|
curr_depth_func = depth_func;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_DEPTH_FUNC);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_line_width() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_LINE_WIDTH) {
|
|
if (curr_line_width != line_width) {
|
|
glLineWidth(line_width);
|
|
curr_line_width = line_width;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_LINE_WIDTH);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_multisample() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_MULTISAMPLE) {
|
|
if (curr_multisample != multisample) {
|
|
(multisample ? glEnable : glDisable)(GL_MULTISAMPLE);
|
|
curr_multisample = multisample;
|
|
}
|
|
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_MULTISAMPLE);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_primitive_restart() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_PRIMITIVE_RESTART) {
|
|
if (curr_primitive_restart != primitive_restart) {
|
|
(primitive_restart ? glEnable : glDisable)(GL_PRIMITIVE_RESTART);
|
|
curr_primitive_restart = primitive_restart;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_PRIMITIVE_RESTART);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_primitive_restart_index() {
|
|
if (curr_primitive_restart && (update_flags & GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX)) {
|
|
if (curr_primitive_restart_index != primitive_restart_index) {
|
|
glPrimitiveRestartIndex(primitive_restart_index);
|
|
curr_primitive_restart_index = primitive_restart_index;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_PRIMITIVE_RESTART_INDEX);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_scissor_test() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_SCISSOR_TEST) {
|
|
if (curr_scissor_test != scissor_test) {
|
|
(scissor_test ? glEnable : glDisable)(GL_SCISSOR_TEST);
|
|
curr_scissor_test = scissor_test;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_SCISSOR_TEST);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_scissor() {
|
|
if (curr_scissor_test && (update_flags & GL_REND_STATE_UPDATE_SCISSOR)) {
|
|
if (memcmp(&curr_scissor_box, &scissor_box, sizeof(gl_rend_state_rect))) {
|
|
glScissor(scissor_box.x, scissor_box.y, scissor_box.width, scissor_box.height);
|
|
curr_scissor_box = scissor_box;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_SCISSOR);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_stencil_test() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_STENCIL_TEST) {
|
|
if (curr_stencil_test != stencil_test) {
|
|
(stencil_test ? glEnable : glDisable)(GL_STENCIL_TEST);
|
|
curr_stencil_test = stencil_test;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_TEST);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_stencil_mask() {
|
|
if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_MASK)) {
|
|
if (curr_stencil_mask != stencil_mask) {
|
|
glStencilMask(stencil_mask);
|
|
curr_stencil_mask = stencil_mask;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_MASK);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_stencil_func() {
|
|
if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_FUNC)) {
|
|
if (curr_stencil_func != stencil_func || curr_stencil_ref != stencil_ref
|
|
|| curr_stencil_value_mask != stencil_value_mask) {
|
|
glStencilFunc(stencil_func, stencil_ref, stencil_ref);
|
|
curr_stencil_func = stencil_func;
|
|
curr_stencil_ref = stencil_ref;
|
|
curr_stencil_value_mask = stencil_value_mask;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_FUNC);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_stencil_op() {
|
|
if (curr_stencil_test && (update_flags & GL_REND_STATE_UPDATE_STENCIL_OP)) {
|
|
if (curr_stencil_fail != stencil_fail || curr_stencil_dpfail != stencil_dpfail
|
|
|| curr_stencil_dppass != stencil_dppass) {
|
|
glStencilOp(stencil_fail, stencil_dpfail, stencil_dppass);
|
|
curr_stencil_fail = stencil_fail;
|
|
curr_stencil_dpfail = stencil_dpfail;
|
|
curr_stencil_dppass = stencil_dppass;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_STENCIL_OP);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_viewport() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_VIEWPORT) {
|
|
if (memcmp(&curr_viewport, &viewport, sizeof(gl_rend_state_rect))) {
|
|
glViewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
|
curr_viewport = viewport;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_VIEWPORT);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_clear_color() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_CLEAR_COLOR) {
|
|
if (curr_clear_color_value[0] != clear_color_value[0]
|
|
|| curr_clear_color_value[1] != clear_color_value[1]
|
|
|| curr_clear_color_value[2] != clear_color_value[2]
|
|
|| curr_clear_color_value[3] != clear_color_value[3]) {
|
|
glClearColor(clear_color_value[0], clear_color_value[1],
|
|
clear_color_value[2], clear_color_value[3]);
|
|
curr_clear_color_value[0] = clear_color_value[0];
|
|
curr_clear_color_value[1] = clear_color_value[1];
|
|
curr_clear_color_value[2] = clear_color_value[2];
|
|
curr_clear_color_value[3] = clear_color_value[3];
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_COLOR);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_clear_depth() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_CLEAR_DEPTH) {
|
|
if (curr_clear_depth_value != clear_depth_value) {
|
|
glClearDepthf(clear_depth_value);
|
|
curr_clear_depth_value = clear_depth_value;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_DEPTH);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::update_clear_stencil() {
|
|
if (update_flags & GL_REND_STATE_UPDATE_CLEAR_STENCIL) {
|
|
if (curr_clear_stencil_value != clear_stencil_value) {
|
|
glClearStencil(clear_stencil_value);
|
|
curr_clear_stencil_value = clear_stencil_value;
|
|
}
|
|
enum_and(update_flags, ~GL_REND_STATE_UPDATE_CLEAR_STENCIL);
|
|
}
|
|
}
|
|
|
|
inline void gl_rend_state::use_program(GLuint program) {
|
|
this->program = program;
|
|
enum_or(update_flags, GL_REND_STATE_UPDATE_PROGRAM);
|
|
}
|