wip: renderstate impl
parent
87c37ae3ad
commit
1c19c44400
34
bind/v4k.lua
34
bind/v4k.lua
|
@ -1032,6 +1032,38 @@ typedef struct reflect_t {
|
||||||
const char* symbol_naked(const char *s);
|
const char* symbol_naked(const char *s);
|
||||||
int ui_reflect(const char *mask);
|
int ui_reflect(const char *mask);
|
||||||
typedef unsigned handle;
|
typedef unsigned handle;
|
||||||
|
typedef struct renderstate_t {
|
||||||
|
int viewportX;
|
||||||
|
int viewportY;
|
||||||
|
int viewportWidth;
|
||||||
|
int viewportHeight;
|
||||||
|
float clearColor[4];
|
||||||
|
double clearDepth;
|
||||||
|
bool depthTestEnabled;
|
||||||
|
unsigned depthFunc;
|
||||||
|
bool blendEnabled;
|
||||||
|
unsigned blendFunc;
|
||||||
|
unsigned blendSrc;
|
||||||
|
unsigned blendDst;
|
||||||
|
bool cullFaceEnabled;
|
||||||
|
unsigned cullFaceMode;
|
||||||
|
bool stencilTestEnabled;
|
||||||
|
unsigned stencilFunc;
|
||||||
|
int stencilRef;
|
||||||
|
unsigned stencilMask;
|
||||||
|
unsigned frontFace;
|
||||||
|
bool smoothLineEnabled;
|
||||||
|
float lineWidth;
|
||||||
|
bool pointSizeEnabled;
|
||||||
|
float pointSize;
|
||||||
|
unsigned polygonModeFace;
|
||||||
|
unsigned polygonModeMode;
|
||||||
|
bool scissorTestEnabled;
|
||||||
|
int scissorBox[4];
|
||||||
|
} renderstate_t;
|
||||||
|
renderstate_t renderstate();
|
||||||
|
bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB);
|
||||||
|
void renderstate_apply(const renderstate_t *state);
|
||||||
unsigned rgba( uint8_t r, uint8_t g, uint8_t b, uint8_t a );
|
unsigned rgba( uint8_t r, uint8_t g, uint8_t b, uint8_t a );
|
||||||
unsigned bgra( uint8_t b, uint8_t g, uint8_t r, uint8_t a );
|
unsigned bgra( uint8_t b, uint8_t g, uint8_t r, uint8_t a );
|
||||||
unsigned rgbaf( float r, float g, float b, float a );
|
unsigned rgbaf( float r, float g, float b, float a );
|
||||||
|
@ -1148,6 +1180,7 @@ typedef struct shadowmap_t {
|
||||||
unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
unsigned shader_bind(unsigned program);
|
unsigned shader_bind(unsigned program);
|
||||||
|
int shader_uniform(const char *name);
|
||||||
void shader_bool(const char *uniform, bool i );
|
void shader_bool(const char *uniform, bool i );
|
||||||
void shader_int(const char *uniform, int i);
|
void shader_int(const char *uniform, int i);
|
||||||
void shader_uint(const char *uniform, unsigned i );
|
void shader_uint(const char *uniform, unsigned i );
|
||||||
|
@ -1362,6 +1395,7 @@ typedef struct model_t {
|
||||||
float *instanced_matrices;
|
float *instanced_matrices;
|
||||||
unsigned num_instances;
|
unsigned num_instances;
|
||||||
int stored_flags;
|
int stored_flags;
|
||||||
|
renderstate_t rs;
|
||||||
} model_t;
|
} model_t;
|
||||||
enum BILLBOARD_MODE {
|
enum BILLBOARD_MODE {
|
||||||
BILLBOARD_X = 0x1,
|
BILLBOARD_X = 0x1,
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include <v4k.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
window_create(40, WINDOW_SQUARE | WINDOW_MSAA8);
|
||||||
|
window_title(__FILE__);
|
||||||
|
|
||||||
|
// set up pipeline
|
||||||
|
renderstate_t state = renderstate();
|
||||||
|
state.clearColor[0] = 0.2f;
|
||||||
|
state.clearColor[1] = 0.2f;
|
||||||
|
state.clearColor[2] = 0.2f;
|
||||||
|
state.clearColor[3] = 1.0f;
|
||||||
|
state.depthTestEnabled = GL_TRUE;
|
||||||
|
state.depthFunc = GL_LEQUAL;
|
||||||
|
state.blendEnabled = GL_FALSE;
|
||||||
|
state.cullFaceEnabled = GL_TRUE;
|
||||||
|
|
||||||
|
// prepare triangle buffer
|
||||||
|
float vertices[] = {
|
||||||
|
-0.5f, -0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.0f,
|
||||||
|
0.0f, 0.5f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int VBO, VAO;
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
// basic shader
|
||||||
|
const char *vertex_shader_src = "#version 330 core\n"
|
||||||
|
"layout (location = 0) in vec3 aPos;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
|
||||||
|
"}\0";
|
||||||
|
|
||||||
|
const char *fragment_shader_src = "#version 330 core\n"
|
||||||
|
"out vec4 FragColor;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
|
||||||
|
"}\0";
|
||||||
|
|
||||||
|
handle program = shader(vertex_shader_src, fragment_shader_src, "aPos", "FragColor", "");
|
||||||
|
|
||||||
|
// app loop
|
||||||
|
while( window_swap() ) {
|
||||||
|
// input controls
|
||||||
|
if( input(KEY_ESC) ) break;
|
||||||
|
|
||||||
|
// bind pipeline
|
||||||
|
renderstate_apply(&state);
|
||||||
|
|
||||||
|
// clear screen
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
// draw triangle
|
||||||
|
glUseProgram(program);
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17030,6 +17030,65 @@ API int ui_reflect(const char *mask); // *, model* or NULL
|
||||||
|
|
||||||
typedef unsigned handle; // GLuint
|
typedef unsigned handle; // GLuint
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// renderstate
|
||||||
|
typedef struct renderstate_t {
|
||||||
|
// Viewport parameters
|
||||||
|
int viewportX;
|
||||||
|
int viewportY;
|
||||||
|
int viewportWidth;
|
||||||
|
int viewportHeight;
|
||||||
|
|
||||||
|
// Clear color
|
||||||
|
float clearColor[4];
|
||||||
|
|
||||||
|
// Clear depth
|
||||||
|
double clearDepth;
|
||||||
|
|
||||||
|
// Depth test
|
||||||
|
bool depthTestEnabled;
|
||||||
|
unsigned depthFunc;
|
||||||
|
|
||||||
|
// Blending
|
||||||
|
bool blendEnabled;
|
||||||
|
unsigned blendFunc;
|
||||||
|
unsigned blendSrc;
|
||||||
|
unsigned blendDst;
|
||||||
|
|
||||||
|
// Culling
|
||||||
|
bool cullFaceEnabled;
|
||||||
|
unsigned cullFaceMode;
|
||||||
|
|
||||||
|
// Stencil test
|
||||||
|
bool stencilTestEnabled;
|
||||||
|
unsigned stencilFunc;
|
||||||
|
int stencilRef;
|
||||||
|
unsigned stencilMask;
|
||||||
|
|
||||||
|
// Face culling direction
|
||||||
|
unsigned frontFace; // GL_CW or GL_CCW
|
||||||
|
|
||||||
|
// Line width
|
||||||
|
bool smoothLineEnabled;
|
||||||
|
float lineWidth;
|
||||||
|
|
||||||
|
// Point size
|
||||||
|
bool pointSizeEnabled;
|
||||||
|
float pointSize;
|
||||||
|
|
||||||
|
// Polygon mode
|
||||||
|
unsigned polygonModeFace;
|
||||||
|
unsigned polygonModeMode;
|
||||||
|
|
||||||
|
// Scissor test
|
||||||
|
bool scissorTestEnabled;
|
||||||
|
int scissorBox[4];
|
||||||
|
} renderstate_t;
|
||||||
|
|
||||||
|
API renderstate_t renderstate();
|
||||||
|
API bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB);
|
||||||
|
API void renderstate_apply(const renderstate_t *state);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// colors
|
// colors
|
||||||
|
|
||||||
|
@ -17250,6 +17309,7 @@ API void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float botto
|
||||||
API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
API unsigned shader_bind(unsigned program);
|
API unsigned shader_bind(unsigned program);
|
||||||
|
API int shader_uniform(const char *name);
|
||||||
API void shader_bool(const char *uniform, bool i );
|
API void shader_bool(const char *uniform, bool i );
|
||||||
API void shader_int(const char *uniform, int i);
|
API void shader_int(const char *uniform, int i);
|
||||||
API void shader_uint(const char *uniform, unsigned i );
|
API void shader_uint(const char *uniform, unsigned i );
|
||||||
|
@ -17599,6 +17659,7 @@ typedef struct model_t {
|
||||||
unsigned num_instances;
|
unsigned num_instances;
|
||||||
|
|
||||||
int stored_flags;
|
int stored_flags;
|
||||||
|
renderstate_t rs;
|
||||||
} model_t;
|
} model_t;
|
||||||
|
|
||||||
enum BILLBOARD_MODE {
|
enum BILLBOARD_MODE {
|
||||||
|
@ -363103,6 +363164,9 @@ typedef struct font_t {
|
||||||
// vbos
|
// vbos
|
||||||
GLuint vbo_quad; // vec2: simply just a regular [0,1]x[0,1] quad
|
GLuint vbo_quad; // vec2: simply just a regular [0,1]x[0,1] quad
|
||||||
GLuint vbo_instances; // vec4: (char_pos_x, char_pos_y, char_index, color_index)
|
GLuint vbo_instances; // vec4: (char_pos_x, char_pos_y, char_index, color_index)
|
||||||
|
|
||||||
|
// render state
|
||||||
|
renderstate_t rs;
|
||||||
} font_t;
|
} font_t;
|
||||||
|
|
||||||
enum { FONTS_MAX = 10 };
|
enum { FONTS_MAX = 10 };
|
||||||
|
@ -363441,6 +363505,16 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
||||||
glUniform2f(glGetUniformLocation(f->program, "res_meta"), f->num_glyphs, 2);
|
glUniform2f(glGetUniformLocation(f->program, "res_meta"), f->num_glyphs, 2);
|
||||||
glUniform1f(glGetUniformLocation(f->program, "num_colors"), FONT_MAX_COLORS);
|
glUniform1f(glGetUniformLocation(f->program, "num_colors"), FONT_MAX_COLORS);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
|
|
||||||
|
// set up pipeline
|
||||||
|
f->rs = renderstate();
|
||||||
|
f->rs.blendEnabled = 1;
|
||||||
|
f->rs.blendFunc = GL_FUNC_ADD;
|
||||||
|
f->rs.blendSrc = GL_SRC_ALPHA;
|
||||||
|
f->rs.blendDst = GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
f->rs.scissorTestEnabled = 1;
|
||||||
|
f->rs.depthTestEnabled = 0;
|
||||||
|
f->rs.cullFaceEnabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void font_face(const char *tag, const char *filename_ttf, float font_size, unsigned flags) {
|
void font_face(const char *tag, const char *filename_ttf, float font_size, unsigned flags) {
|
||||||
|
@ -363471,25 +363545,10 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_1D, &last_texture2);
|
glGetIntegerv(GL_TEXTURE_BINDING_1D, &last_texture2);
|
||||||
|
|
||||||
glGetIntegerv(GL_BLEND_SRC, &last_blend_src);
|
f->rs.scissorBox[0] = rect.x;
|
||||||
glGetIntegerv(GL_BLEND_DST, &last_blend_dst);
|
f->rs.scissorBox[1] = window_height() - (rect.y+rect.w);
|
||||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb);
|
f->rs.scissorBox[2] = rect.z;
|
||||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha);
|
f->rs.scissorBox[3] = rect.w;
|
||||||
|
|
||||||
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
|
||||||
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
|
||||||
GLboolean last_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
// Setup render state: alpha-blending enabled, no depth testing, enable clipping and bind textures
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
// @fixme: store existing scissor test setup
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glScissor(rect.x, window_height() - (rect.y+rect.w), rect.z, rect.w);
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, f->texture_fontdata);
|
glBindTexture(GL_TEXTURE_2D, f->texture_fontdata);
|
||||||
|
@ -363515,6 +363574,9 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, f->vbo_instances);
|
glBindBuffer(GL_ARRAY_BUFFER, f->vbo_instances);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*glyph_idx, glyph_data);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*glyph_idx, glyph_data);
|
||||||
|
|
||||||
|
// setup pipeline
|
||||||
|
renderstate_apply(&f->rs);
|
||||||
|
|
||||||
// actual drawing
|
// actual drawing
|
||||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx);
|
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx);
|
||||||
|
|
||||||
|
@ -363528,13 +363590,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
||||||
|
|
||||||
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
|
||||||
glBindVertexArray(last_vertex_array);
|
glBindVertexArray(last_vertex_array);
|
||||||
glBlendFunc(last_blend_src, last_blend_dst);
|
|
||||||
|
|
||||||
(last_enable_depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
|
|
||||||
(last_enable_blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND));
|
|
||||||
(last_scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. call font_face() if it's the first time it's called.
|
// 1. call font_face() if it's the first time it's called.
|
||||||
|
@ -370069,6 +370125,154 @@ void glCopyBackbufferToTexture( texture_t *tex ) { // unused
|
||||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, window_width(), window_height(), 0 );
|
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, window_width(), window_height(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// renderstate
|
||||||
|
|
||||||
|
renderstate_t renderstate() {
|
||||||
|
renderstate_t state = {0};
|
||||||
|
|
||||||
|
// Set default viewport parameters
|
||||||
|
state.viewportX = 0;
|
||||||
|
state.viewportY = 0;
|
||||||
|
state.viewportWidth = window_width();
|
||||||
|
state.viewportHeight = window_height();
|
||||||
|
|
||||||
|
// Set default clear color to black
|
||||||
|
state.clearColor[0] = 0.0f; // Red
|
||||||
|
state.clearColor[1] = 0.0f; // Green
|
||||||
|
state.clearColor[2] = 0.0f; // Blue
|
||||||
|
state.clearColor[3] = 1.0f; // Alpha
|
||||||
|
|
||||||
|
// Set default clear depth to maximum distance
|
||||||
|
state.clearDepth = 1.0;
|
||||||
|
|
||||||
|
// Enable depth test by default with less or equal function
|
||||||
|
state.depthTestEnabled = GL_TRUE;
|
||||||
|
state.depthFunc = GL_LEQUAL;
|
||||||
|
|
||||||
|
// Disable blending by default
|
||||||
|
state.blendEnabled = GL_FALSE;
|
||||||
|
state.blendFunc = GL_FUNC_ADD;
|
||||||
|
state.blendSrc = GL_ONE;
|
||||||
|
state.blendDst = GL_ZERO;
|
||||||
|
|
||||||
|
// Enable culling by default and cull back faces
|
||||||
|
state.cullFaceEnabled = GL_TRUE;
|
||||||
|
state.cullFaceMode = GL_BACK;
|
||||||
|
|
||||||
|
// Disable stencil test by default
|
||||||
|
state.stencilTestEnabled = GL_FALSE;
|
||||||
|
state.stencilFunc = GL_ALWAYS;
|
||||||
|
state.stencilRef = 0;
|
||||||
|
state.stencilMask = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// Set default front face to counter-clockwise
|
||||||
|
state.frontFace = GL_CCW;
|
||||||
|
|
||||||
|
// Set default line width
|
||||||
|
state.smoothLineEnabled = GL_FALSE;
|
||||||
|
state.lineWidth = 1.0f;
|
||||||
|
|
||||||
|
// Set default point size
|
||||||
|
state.pointSizeEnabled = GL_FALSE;
|
||||||
|
state.pointSize = 1.0f;
|
||||||
|
|
||||||
|
// Set default polygon mode to fill
|
||||||
|
state.polygonModeFace = GL_FRONT_AND_BACK;
|
||||||
|
state.polygonModeMode = GL_FILL;
|
||||||
|
|
||||||
|
// Disable scissor test by default
|
||||||
|
state.scissorTestEnabled = GL_FALSE;
|
||||||
|
state.scissorBox[0] = 0;
|
||||||
|
state.scissorBox[1] = 0;
|
||||||
|
state.scissorBox[2] = window_width();
|
||||||
|
state.scissorBox[3] = window_height();
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB) {
|
||||||
|
return memcmp(stateA, stateB, sizeof(renderstate_t)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderstate_apply(const renderstate_t *state) {
|
||||||
|
if (state != NULL) {
|
||||||
|
// Apply viewport parameters
|
||||||
|
glViewport(state->viewportX, state->viewportY, state->viewportWidth, state->viewportHeight);
|
||||||
|
|
||||||
|
// Apply clear color
|
||||||
|
glClearColor(state->clearColor[0], state->clearColor[1], state->clearColor[2], state->clearColor[3]);
|
||||||
|
|
||||||
|
// Apply clear depth
|
||||||
|
glClearDepth(state->clearDepth);
|
||||||
|
|
||||||
|
// Apply depth test
|
||||||
|
if (state->depthTestEnabled) {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(state->depthFunc);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply blending
|
||||||
|
if (state->blendEnabled) {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendEquation(state->blendFunc);
|
||||||
|
glBlendFunc(state->blendSrc, state->blendDst);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply culling @fixme
|
||||||
|
// if (state->cullFaceEnabled) {
|
||||||
|
// glEnable(GL_CULL_FACE);
|
||||||
|
// glCullFace(state->cullFaceMode);
|
||||||
|
// } else {
|
||||||
|
// glDisable(GL_CULL_FACE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Apply stencil test
|
||||||
|
if (state->stencilTestEnabled) {
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilFunc(state->stencilFunc, state->stencilRef, state->stencilMask);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply front face direction @fixme
|
||||||
|
// glFrontFace(state->frontFace);
|
||||||
|
|
||||||
|
// Apply line width
|
||||||
|
glLineWidth(state->lineWidth);
|
||||||
|
|
||||||
|
// apply smooth lines
|
||||||
|
if (state->smoothLineEnabled) {
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply point size
|
||||||
|
if (state->pointSizeEnabled) {
|
||||||
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
glPointSize(state->pointSize);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply polygon mode
|
||||||
|
glPolygonMode(state->polygonModeFace, state->polygonModeMode);
|
||||||
|
|
||||||
|
// Apply scissor test
|
||||||
|
if (state->scissorTestEnabled) {
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(state->scissorBox[0], state->scissorBox[1], state->scissorBox[2], state->scissorBox[3]);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// shaders
|
// shaders
|
||||||
|
|
||||||
|
@ -370543,7 +370747,7 @@ typedef map(unsigned,int) uniform_binding;
|
||||||
static __thread unsigned last_shader = -1;
|
static __thread unsigned last_shader = -1;
|
||||||
static __thread quarks_db uniform_names;
|
static __thread quarks_db uniform_names;
|
||||||
static __thread map(handle, uniform_binding) uniforms;
|
static __thread map(handle, uniform_binding) uniforms;
|
||||||
static
|
|
||||||
int shader_uniform(const char *name) {
|
int shader_uniform(const char *name) {
|
||||||
do_once map_init(uniforms, less_int, hash_int);
|
do_once map_init(uniforms, less_int, hash_int);
|
||||||
if (!map_find(uniforms, last_shader)) {
|
if (!map_find(uniforms, last_shader)) {
|
||||||
|
@ -371873,17 +372077,21 @@ void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength) {
|
||||||
|
|
||||||
API vec4 window_getcolor_(); // internal use, not public
|
API vec4 window_getcolor_(); // internal use, not public
|
||||||
|
|
||||||
|
static renderstate_t skybox_rs;
|
||||||
|
|
||||||
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
last_cubemap = &sky->cubemap;
|
last_cubemap = &sky->cubemap;
|
||||||
|
|
||||||
//glClear(GL_DEPTH_BUFFER_BIT);
|
do_once {
|
||||||
//glEnable(GL_DEPTH_TEST);
|
skybox_rs = renderstate();
|
||||||
glDepthFunc(GL_LEQUAL);
|
}
|
||||||
//glDisable(GL_CULL_FACE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// we have to reset clear color here, because of wrong alpha compositing issues on native transparent windows otherwise
|
// we have to reset clear color here, because of wrong alpha compositing issues on native transparent windows otherwise
|
||||||
vec4 bgcolor = window_getcolor_(); glClearColor(bgcolor.r, bgcolor.g, bgcolor.b, 1); // @transparent
|
vec4 bgcolor = window_getcolor_();
|
||||||
|
skybox_rs.clearColor[0] = bgcolor.r;
|
||||||
|
skybox_rs.clearColor[1] = bgcolor.g;
|
||||||
|
skybox_rs.clearColor[2] = bgcolor.b;
|
||||||
|
skybox_rs.clearColor[3] = 1; // @transparent
|
||||||
|
|
||||||
mat44 mvp; multiply44x2(mvp, proj, view);
|
mat44 mvp; multiply44x2(mvp, proj, view);
|
||||||
|
|
||||||
|
@ -371893,6 +372101,8 @@ int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
if( sky->flags ) {
|
if( sky->flags ) {
|
||||||
shader_cubemap("u_cubemap", sky->cubemap.id);
|
shader_cubemap("u_cubemap", sky->cubemap.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderstate_apply(&skybox_rs);
|
||||||
return 0; // @fixme: return sortable hash here?
|
return 0; // @fixme: return sortable hash here?
|
||||||
}
|
}
|
||||||
int skybox_pop_state() {
|
int skybox_pop_state() {
|
||||||
|
@ -371903,7 +372113,6 @@ int skybox_pop_state() {
|
||||||
}
|
}
|
||||||
int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
|
int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
skybox_push_state(sky, proj, view);
|
skybox_push_state(sky, proj, view);
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
mesh_render(&sky->geometry);
|
mesh_render(&sky->geometry);
|
||||||
skybox_pop_state();
|
skybox_pop_state();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -373562,6 +373771,11 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
|
||||||
model_t model_from_mem(const void *mem, int len, int flags) {
|
model_t model_from_mem(const void *mem, int len, int flags) {
|
||||||
model_t m = {0};
|
model_t m = {0};
|
||||||
|
|
||||||
|
{
|
||||||
|
m.rs = renderstate();
|
||||||
|
m.rs.blendEnabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
m.stored_flags = flags;
|
m.stored_flags = flags;
|
||||||
m.shading = SHADING_PHONG;
|
m.shading = SHADING_PHONG;
|
||||||
|
|
||||||
|
@ -373845,6 +374059,8 @@ void model_draw_call(model_t m, int shader) {
|
||||||
handle old_shader = last_shader;
|
handle old_shader = last_shader;
|
||||||
shader_bind(shader);
|
shader_bind(shader);
|
||||||
|
|
||||||
|
renderstate_apply(&m.rs);
|
||||||
|
|
||||||
glBindVertexArray( q->vao );
|
glBindVertexArray( q->vao );
|
||||||
|
|
||||||
struct iqmtriangle *tris = NULL;
|
struct iqmtriangle *tris = NULL;
|
||||||
|
@ -374143,6 +374359,7 @@ typedef struct text2d_cmd {
|
||||||
float sca;
|
float sca;
|
||||||
} text2d_cmd;
|
} text2d_cmd;
|
||||||
|
|
||||||
|
static renderstate_t dd_rs;
|
||||||
static uint32_t dd_color = ~0u;
|
static uint32_t dd_color = ~0u;
|
||||||
static GLuint dd_program = -1;
|
static GLuint dd_program = -1;
|
||||||
static int dd_u_color = -1;
|
static int dd_u_color = -1;
|
||||||
|
@ -374176,7 +374393,9 @@ void ddraw_flush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddraw_flush_projview(mat44 proj, mat44 view) {
|
void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
do_once dd_rs = renderstate();
|
||||||
|
|
||||||
|
dd_rs.depthTestEnabled = 1;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
mat44 mvp;
|
mat44 mvp;
|
||||||
|
@ -374191,16 +374410,16 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
dd_rs.pointSizeEnabled = 1;
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE); // for GL_POINTS
|
dd_rs.smoothLineEnabled = 1;
|
||||||
glEnable(GL_LINE_SMOOTH); // for GL_LINES (thin)
|
|
||||||
|
|
||||||
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
||||||
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
||||||
glLineWidth(i == 1 ? 1 : 0.3); // 0.625);
|
dd_rs.lineWidth = (i == 1 ? 1 : 0.3); // 0.625);
|
||||||
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
||||||
int count = array_count(list);
|
int count = array_count(list);
|
||||||
if(!count) continue;
|
if(!count) continue;
|
||||||
|
renderstate_apply(&dd_rs);
|
||||||
// color
|
// color
|
||||||
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
||||||
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
||||||
|
@ -374229,10 +374448,11 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
|
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
|
||||||
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
||||||
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
||||||
glLineWidth(i == 1 ? 1 : 0.3); // 0.625);
|
dd_rs.lineWidth = (i == 1 ? 1 : 0.3); // 0.625);
|
||||||
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
||||||
int count = array_count(list);
|
int count = array_count(list);
|
||||||
if(!count) continue;
|
if(!count) continue;
|
||||||
|
renderstate_apply(&dd_rs);
|
||||||
// color
|
// color
|
||||||
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
||||||
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
||||||
|
@ -374251,9 +374471,6 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
array_resize(dd_text2d, 0);
|
array_resize(dd_text2d, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_LINE_SMOOTH);
|
|
||||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
ddraw_color(WHITE); // reset color for next drawcall
|
ddraw_color(WHITE); // reset color for next drawcall
|
||||||
|
@ -379529,7 +379746,20 @@ struct nk_glfw *window_handle_nkglfw() {
|
||||||
return g->nk_glfw;
|
return g->nk_glfw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static renderstate_t window_rs;
|
||||||
|
|
||||||
void glNewFrame() {
|
void glNewFrame() {
|
||||||
|
do_once {
|
||||||
|
window_rs = renderstate();
|
||||||
|
window_rs.blendEnabled = 1;
|
||||||
|
window_rs.depthTestEnabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
window_rs.clearColor[0] = winbgcolor.r;
|
||||||
|
window_rs.clearColor[1] = winbgcolor.g;
|
||||||
|
window_rs.clearColor[2] = winbgcolor.b;
|
||||||
|
window_rs.clearColor[3] = window_has_transparent() ? 0 : winbgcolor.a;
|
||||||
|
|
||||||
// @transparent debug
|
// @transparent debug
|
||||||
// if( input_down(KEY_F1) ) window_transparent(window_has_transparent()^1);
|
// if( input_down(KEY_F1) ) window_transparent(window_has_transparent()^1);
|
||||||
// if( input_down(KEY_F2) ) window_maximize(window_has_maximize()^1);
|
// if( input_down(KEY_F2) ) window_maximize(window_has_maximize()^1);
|
||||||
|
@ -379550,30 +379780,8 @@ void glNewFrame() {
|
||||||
g->width = w;
|
g->width = w;
|
||||||
g->height = h;
|
g->height = h;
|
||||||
|
|
||||||
// blending defaults
|
renderstate_apply(&window_rs);
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
// culling defaults
|
|
||||||
// glEnable(GL_CULL_FACE);
|
|
||||||
// glCullFace(GL_BACK);
|
|
||||||
// glFrontFace(GL_CCW);
|
|
||||||
|
|
||||||
// depth-testing defaults
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
// glDepthFunc(GL_LESS);
|
|
||||||
|
|
||||||
// depth-writing defaults
|
|
||||||
// glDepthMask(GL_TRUE);
|
|
||||||
|
|
||||||
// seamless cubemaps
|
|
||||||
// glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
|
||||||
|
|
||||||
glViewport(0, 0, window_width(), window_height());
|
|
||||||
|
|
||||||
// GLfloat bgColor[4]; glGetFloatv(GL_COLOR_CLEAR_VALUE, bgColor);
|
|
||||||
glClearColor(winbgcolor.r, winbgcolor.g, winbgcolor.b, window_has_transparent() ? 0 : winbgcolor.a); // @transparent
|
|
||||||
//glClearColor(0.15,0.15,0.15,1);
|
|
||||||
//glClearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
|
|
||||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1554,6 +1554,9 @@ typedef struct font_t {
|
||||||
// vbos
|
// vbos
|
||||||
GLuint vbo_quad; // vec2: simply just a regular [0,1]x[0,1] quad
|
GLuint vbo_quad; // vec2: simply just a regular [0,1]x[0,1] quad
|
||||||
GLuint vbo_instances; // vec4: (char_pos_x, char_pos_y, char_index, color_index)
|
GLuint vbo_instances; // vec4: (char_pos_x, char_pos_y, char_index, color_index)
|
||||||
|
|
||||||
|
// render state
|
||||||
|
renderstate_t rs;
|
||||||
} font_t;
|
} font_t;
|
||||||
|
|
||||||
enum { FONTS_MAX = 10 };
|
enum { FONTS_MAX = 10 };
|
||||||
|
@ -1892,6 +1895,16 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
||||||
glUniform2f(glGetUniformLocation(f->program, "res_meta"), f->num_glyphs, 2);
|
glUniform2f(glGetUniformLocation(f->program, "res_meta"), f->num_glyphs, 2);
|
||||||
glUniform1f(glGetUniformLocation(f->program, "num_colors"), FONT_MAX_COLORS);
|
glUniform1f(glGetUniformLocation(f->program, "num_colors"), FONT_MAX_COLORS);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
|
|
||||||
|
// set up pipeline
|
||||||
|
f->rs = renderstate();
|
||||||
|
f->rs.blendEnabled = 1;
|
||||||
|
f->rs.blendFunc = GL_FUNC_ADD;
|
||||||
|
f->rs.blendSrc = GL_SRC_ALPHA;
|
||||||
|
f->rs.blendDst = GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
f->rs.scissorTestEnabled = 1;
|
||||||
|
f->rs.depthTestEnabled = 0;
|
||||||
|
f->rs.cullFaceEnabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void font_face(const char *tag, const char *filename_ttf, float font_size, unsigned flags) {
|
void font_face(const char *tag, const char *filename_ttf, float font_size, unsigned flags) {
|
||||||
|
@ -1922,25 +1935,10 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_1D, &last_texture2);
|
glGetIntegerv(GL_TEXTURE_BINDING_1D, &last_texture2);
|
||||||
|
|
||||||
glGetIntegerv(GL_BLEND_SRC, &last_blend_src);
|
f->rs.scissorBox[0] = rect.x;
|
||||||
glGetIntegerv(GL_BLEND_DST, &last_blend_dst);
|
f->rs.scissorBox[1] = window_height() - (rect.y+rect.w);
|
||||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb);
|
f->rs.scissorBox[2] = rect.z;
|
||||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha);
|
f->rs.scissorBox[3] = rect.w;
|
||||||
|
|
||||||
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
|
||||||
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
|
||||||
GLboolean last_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
// Setup render state: alpha-blending enabled, no depth testing, enable clipping and bind textures
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
// @fixme: store existing scissor test setup
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glScissor(rect.x, window_height() - (rect.y+rect.w), rect.z, rect.w);
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, f->texture_fontdata);
|
glBindTexture(GL_TEXTURE_2D, f->texture_fontdata);
|
||||||
|
@ -1966,6 +1964,9 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, f->vbo_instances);
|
glBindBuffer(GL_ARRAY_BUFFER, f->vbo_instances);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*glyph_idx, glyph_data);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*glyph_idx, glyph_data);
|
||||||
|
|
||||||
|
// setup pipeline
|
||||||
|
renderstate_apply(&f->rs);
|
||||||
|
|
||||||
// actual drawing
|
// actual drawing
|
||||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx);
|
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx);
|
||||||
|
|
||||||
|
@ -1979,13 +1980,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
||||||
|
|
||||||
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
|
||||||
glBindVertexArray(last_vertex_array);
|
glBindVertexArray(last_vertex_array);
|
||||||
glBlendFunc(last_blend_src, last_blend_dst);
|
|
||||||
|
|
||||||
(last_enable_depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
|
|
||||||
(last_enable_blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND));
|
|
||||||
(last_scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. call font_face() if it's the first time it's called.
|
// 1. call font_face() if it's the first time it's called.
|
||||||
|
|
|
@ -50,6 +50,154 @@ void glCopyBackbufferToTexture( texture_t *tex ) { // unused
|
||||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, window_width(), window_height(), 0 );
|
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, window_width(), window_height(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// renderstate
|
||||||
|
|
||||||
|
renderstate_t renderstate() {
|
||||||
|
renderstate_t state = {0};
|
||||||
|
|
||||||
|
// Set default viewport parameters
|
||||||
|
state.viewportX = 0;
|
||||||
|
state.viewportY = 0;
|
||||||
|
state.viewportWidth = window_width();
|
||||||
|
state.viewportHeight = window_height();
|
||||||
|
|
||||||
|
// Set default clear color to black
|
||||||
|
state.clearColor[0] = 0.0f; // Red
|
||||||
|
state.clearColor[1] = 0.0f; // Green
|
||||||
|
state.clearColor[2] = 0.0f; // Blue
|
||||||
|
state.clearColor[3] = 1.0f; // Alpha
|
||||||
|
|
||||||
|
// Set default clear depth to maximum distance
|
||||||
|
state.clearDepth = 1.0;
|
||||||
|
|
||||||
|
// Enable depth test by default with less or equal function
|
||||||
|
state.depthTestEnabled = GL_TRUE;
|
||||||
|
state.depthFunc = GL_LEQUAL;
|
||||||
|
|
||||||
|
// Disable blending by default
|
||||||
|
state.blendEnabled = GL_FALSE;
|
||||||
|
state.blendFunc = GL_FUNC_ADD;
|
||||||
|
state.blendSrc = GL_ONE;
|
||||||
|
state.blendDst = GL_ZERO;
|
||||||
|
|
||||||
|
// Enable culling by default and cull back faces
|
||||||
|
state.cullFaceEnabled = GL_TRUE;
|
||||||
|
state.cullFaceMode = GL_BACK;
|
||||||
|
|
||||||
|
// Disable stencil test by default
|
||||||
|
state.stencilTestEnabled = GL_FALSE;
|
||||||
|
state.stencilFunc = GL_ALWAYS;
|
||||||
|
state.stencilRef = 0;
|
||||||
|
state.stencilMask = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// Set default front face to counter-clockwise
|
||||||
|
state.frontFace = GL_CCW;
|
||||||
|
|
||||||
|
// Set default line width
|
||||||
|
state.smoothLineEnabled = GL_FALSE;
|
||||||
|
state.lineWidth = 1.0f;
|
||||||
|
|
||||||
|
// Set default point size
|
||||||
|
state.pointSizeEnabled = GL_FALSE;
|
||||||
|
state.pointSize = 1.0f;
|
||||||
|
|
||||||
|
// Set default polygon mode to fill
|
||||||
|
state.polygonModeFace = GL_FRONT_AND_BACK;
|
||||||
|
state.polygonModeMode = GL_FILL;
|
||||||
|
|
||||||
|
// Disable scissor test by default
|
||||||
|
state.scissorTestEnabled = GL_FALSE;
|
||||||
|
state.scissorBox[0] = 0;
|
||||||
|
state.scissorBox[1] = 0;
|
||||||
|
state.scissorBox[2] = window_width();
|
||||||
|
state.scissorBox[3] = window_height();
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB) {
|
||||||
|
return memcmp(stateA, stateB, sizeof(renderstate_t)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderstate_apply(const renderstate_t *state) {
|
||||||
|
if (state != NULL) {
|
||||||
|
// Apply viewport parameters
|
||||||
|
glViewport(state->viewportX, state->viewportY, state->viewportWidth, state->viewportHeight);
|
||||||
|
|
||||||
|
// Apply clear color
|
||||||
|
glClearColor(state->clearColor[0], state->clearColor[1], state->clearColor[2], state->clearColor[3]);
|
||||||
|
|
||||||
|
// Apply clear depth
|
||||||
|
glClearDepth(state->clearDepth);
|
||||||
|
|
||||||
|
// Apply depth test
|
||||||
|
if (state->depthTestEnabled) {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(state->depthFunc);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply blending
|
||||||
|
if (state->blendEnabled) {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendEquation(state->blendFunc);
|
||||||
|
glBlendFunc(state->blendSrc, state->blendDst);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply culling @fixme
|
||||||
|
// if (state->cullFaceEnabled) {
|
||||||
|
// glEnable(GL_CULL_FACE);
|
||||||
|
// glCullFace(state->cullFaceMode);
|
||||||
|
// } else {
|
||||||
|
// glDisable(GL_CULL_FACE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Apply stencil test
|
||||||
|
if (state->stencilTestEnabled) {
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilFunc(state->stencilFunc, state->stencilRef, state->stencilMask);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply front face direction @fixme
|
||||||
|
// glFrontFace(state->frontFace);
|
||||||
|
|
||||||
|
// Apply line width
|
||||||
|
glLineWidth(state->lineWidth);
|
||||||
|
|
||||||
|
// apply smooth lines
|
||||||
|
if (state->smoothLineEnabled) {
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply point size
|
||||||
|
if (state->pointSizeEnabled) {
|
||||||
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
glPointSize(state->pointSize);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply polygon mode
|
||||||
|
glPolygonMode(state->polygonModeFace, state->polygonModeMode);
|
||||||
|
|
||||||
|
// Apply scissor test
|
||||||
|
if (state->scissorTestEnabled) {
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(state->scissorBox[0], state->scissorBox[1], state->scissorBox[2], state->scissorBox[3]);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// shaders
|
// shaders
|
||||||
|
|
||||||
|
@ -524,7 +672,7 @@ typedef map(unsigned,int) uniform_binding;
|
||||||
static __thread unsigned last_shader = -1;
|
static __thread unsigned last_shader = -1;
|
||||||
static __thread quarks_db uniform_names;
|
static __thread quarks_db uniform_names;
|
||||||
static __thread map(handle, uniform_binding) uniforms;
|
static __thread map(handle, uniform_binding) uniforms;
|
||||||
static
|
|
||||||
int shader_uniform(const char *name) {
|
int shader_uniform(const char *name) {
|
||||||
do_once map_init(uniforms, less_int, hash_int);
|
do_once map_init(uniforms, less_int, hash_int);
|
||||||
if (!map_find(uniforms, last_shader)) {
|
if (!map_find(uniforms, last_shader)) {
|
||||||
|
@ -1854,17 +2002,21 @@ void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength) {
|
||||||
|
|
||||||
API vec4 window_getcolor_(); // internal use, not public
|
API vec4 window_getcolor_(); // internal use, not public
|
||||||
|
|
||||||
|
static renderstate_t skybox_rs;
|
||||||
|
|
||||||
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
last_cubemap = &sky->cubemap;
|
last_cubemap = &sky->cubemap;
|
||||||
|
|
||||||
//glClear(GL_DEPTH_BUFFER_BIT);
|
do_once {
|
||||||
//glEnable(GL_DEPTH_TEST);
|
skybox_rs = renderstate();
|
||||||
glDepthFunc(GL_LEQUAL);
|
}
|
||||||
//glDisable(GL_CULL_FACE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// we have to reset clear color here, because of wrong alpha compositing issues on native transparent windows otherwise
|
// we have to reset clear color here, because of wrong alpha compositing issues on native transparent windows otherwise
|
||||||
vec4 bgcolor = window_getcolor_(); glClearColor(bgcolor.r, bgcolor.g, bgcolor.b, 1); // @transparent
|
vec4 bgcolor = window_getcolor_();
|
||||||
|
skybox_rs.clearColor[0] = bgcolor.r;
|
||||||
|
skybox_rs.clearColor[1] = bgcolor.g;
|
||||||
|
skybox_rs.clearColor[2] = bgcolor.b;
|
||||||
|
skybox_rs.clearColor[3] = 1; // @transparent
|
||||||
|
|
||||||
mat44 mvp; multiply44x2(mvp, proj, view);
|
mat44 mvp; multiply44x2(mvp, proj, view);
|
||||||
|
|
||||||
|
@ -1874,6 +2026,8 @@ int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
if( sky->flags ) {
|
if( sky->flags ) {
|
||||||
shader_cubemap("u_cubemap", sky->cubemap.id);
|
shader_cubemap("u_cubemap", sky->cubemap.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderstate_apply(&skybox_rs);
|
||||||
return 0; // @fixme: return sortable hash here?
|
return 0; // @fixme: return sortable hash here?
|
||||||
}
|
}
|
||||||
int skybox_pop_state() {
|
int skybox_pop_state() {
|
||||||
|
@ -1884,7 +2038,6 @@ int skybox_pop_state() {
|
||||||
}
|
}
|
||||||
int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
|
int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
skybox_push_state(sky, proj, view);
|
skybox_push_state(sky, proj, view);
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
mesh_render(&sky->geometry);
|
mesh_render(&sky->geometry);
|
||||||
skybox_pop_state();
|
skybox_pop_state();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3543,6 +3696,11 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
|
||||||
model_t model_from_mem(const void *mem, int len, int flags) {
|
model_t model_from_mem(const void *mem, int len, int flags) {
|
||||||
model_t m = {0};
|
model_t m = {0};
|
||||||
|
|
||||||
|
{
|
||||||
|
m.rs = renderstate();
|
||||||
|
m.rs.blendEnabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
m.stored_flags = flags;
|
m.stored_flags = flags;
|
||||||
m.shading = SHADING_PHONG;
|
m.shading = SHADING_PHONG;
|
||||||
|
|
||||||
|
@ -3826,6 +3984,8 @@ void model_draw_call(model_t m, int shader) {
|
||||||
handle old_shader = last_shader;
|
handle old_shader = last_shader;
|
||||||
shader_bind(shader);
|
shader_bind(shader);
|
||||||
|
|
||||||
|
renderstate_apply(&m.rs);
|
||||||
|
|
||||||
glBindVertexArray( q->vao );
|
glBindVertexArray( q->vao );
|
||||||
|
|
||||||
struct iqmtriangle *tris = NULL;
|
struct iqmtriangle *tris = NULL;
|
||||||
|
|
|
@ -8,6 +8,65 @@
|
||||||
|
|
||||||
typedef unsigned handle; // GLuint
|
typedef unsigned handle; // GLuint
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// renderstate
|
||||||
|
typedef struct renderstate_t {
|
||||||
|
// Viewport parameters
|
||||||
|
int viewportX;
|
||||||
|
int viewportY;
|
||||||
|
int viewportWidth;
|
||||||
|
int viewportHeight;
|
||||||
|
|
||||||
|
// Clear color
|
||||||
|
float clearColor[4];
|
||||||
|
|
||||||
|
// Clear depth
|
||||||
|
double clearDepth;
|
||||||
|
|
||||||
|
// Depth test
|
||||||
|
bool depthTestEnabled;
|
||||||
|
unsigned depthFunc;
|
||||||
|
|
||||||
|
// Blending
|
||||||
|
bool blendEnabled;
|
||||||
|
unsigned blendFunc;
|
||||||
|
unsigned blendSrc;
|
||||||
|
unsigned blendDst;
|
||||||
|
|
||||||
|
// Culling
|
||||||
|
bool cullFaceEnabled;
|
||||||
|
unsigned cullFaceMode;
|
||||||
|
|
||||||
|
// Stencil test
|
||||||
|
bool stencilTestEnabled;
|
||||||
|
unsigned stencilFunc;
|
||||||
|
int stencilRef;
|
||||||
|
unsigned stencilMask;
|
||||||
|
|
||||||
|
// Face culling direction
|
||||||
|
unsigned frontFace; // GL_CW or GL_CCW
|
||||||
|
|
||||||
|
// Line width
|
||||||
|
bool smoothLineEnabled;
|
||||||
|
float lineWidth;
|
||||||
|
|
||||||
|
// Point size
|
||||||
|
bool pointSizeEnabled;
|
||||||
|
float pointSize;
|
||||||
|
|
||||||
|
// Polygon mode
|
||||||
|
unsigned polygonModeFace;
|
||||||
|
unsigned polygonModeMode;
|
||||||
|
|
||||||
|
// Scissor test
|
||||||
|
bool scissorTestEnabled;
|
||||||
|
int scissorBox[4];
|
||||||
|
} renderstate_t;
|
||||||
|
|
||||||
|
API renderstate_t renderstate();
|
||||||
|
API bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB);
|
||||||
|
API void renderstate_apply(const renderstate_t *state);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// colors
|
// colors
|
||||||
|
|
||||||
|
@ -228,6 +287,7 @@ API void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float botto
|
||||||
API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
API unsigned shader_bind(unsigned program);
|
API unsigned shader_bind(unsigned program);
|
||||||
|
API int shader_uniform(const char *name);
|
||||||
API void shader_bool(const char *uniform, bool i );
|
API void shader_bool(const char *uniform, bool i );
|
||||||
API void shader_int(const char *uniform, int i);
|
API void shader_int(const char *uniform, int i);
|
||||||
API void shader_uint(const char *uniform, unsigned i );
|
API void shader_uint(const char *uniform, unsigned i );
|
||||||
|
@ -577,6 +637,7 @@ typedef struct model_t {
|
||||||
unsigned num_instances;
|
unsigned num_instances;
|
||||||
|
|
||||||
int stored_flags;
|
int stored_flags;
|
||||||
|
renderstate_t rs;
|
||||||
} model_t;
|
} model_t;
|
||||||
|
|
||||||
enum BILLBOARD_MODE {
|
enum BILLBOARD_MODE {
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef struct text2d_cmd {
|
||||||
float sca;
|
float sca;
|
||||||
} text2d_cmd;
|
} text2d_cmd;
|
||||||
|
|
||||||
|
static renderstate_t dd_rs;
|
||||||
static uint32_t dd_color = ~0u;
|
static uint32_t dd_color = ~0u;
|
||||||
static GLuint dd_program = -1;
|
static GLuint dd_program = -1;
|
||||||
static int dd_u_color = -1;
|
static int dd_u_color = -1;
|
||||||
|
@ -66,7 +67,9 @@ void ddraw_flush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddraw_flush_projview(mat44 proj, mat44 view) {
|
void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
do_once dd_rs = renderstate();
|
||||||
|
|
||||||
|
dd_rs.depthTestEnabled = 1;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
mat44 mvp;
|
mat44 mvp;
|
||||||
|
@ -81,16 +84,16 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
dd_rs.pointSizeEnabled = 1;
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE); // for GL_POINTS
|
dd_rs.smoothLineEnabled = 1;
|
||||||
glEnable(GL_LINE_SMOOTH); // for GL_LINES (thin)
|
|
||||||
|
|
||||||
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
||||||
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
||||||
glLineWidth(i == 1 ? 1 : 0.3); // 0.625);
|
dd_rs.lineWidth = (i == 1 ? 1 : 0.3); // 0.625);
|
||||||
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
||||||
int count = array_count(list);
|
int count = array_count(list);
|
||||||
if(!count) continue;
|
if(!count) continue;
|
||||||
|
renderstate_apply(&dd_rs);
|
||||||
// color
|
// color
|
||||||
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
||||||
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
||||||
|
@ -119,10 +122,11 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
|
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
|
||||||
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
||||||
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
||||||
glLineWidth(i == 1 ? 1 : 0.3); // 0.625);
|
dd_rs.lineWidth = (i == 1 ? 1 : 0.3); // 0.625);
|
||||||
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
||||||
int count = array_count(list);
|
int count = array_count(list);
|
||||||
if(!count) continue;
|
if(!count) continue;
|
||||||
|
renderstate_apply(&dd_rs);
|
||||||
// color
|
// color
|
||||||
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
||||||
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
||||||
|
@ -141,9 +145,6 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
array_resize(dd_text2d, 0);
|
array_resize(dd_text2d, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_LINE_SMOOTH);
|
|
||||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
ddraw_color(WHITE); // reset color for next drawcall
|
ddraw_color(WHITE); // reset color for next drawcall
|
||||||
|
|
|
@ -221,7 +221,20 @@ struct nk_glfw *window_handle_nkglfw() {
|
||||||
return g->nk_glfw;
|
return g->nk_glfw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static renderstate_t window_rs;
|
||||||
|
|
||||||
void glNewFrame() {
|
void glNewFrame() {
|
||||||
|
do_once {
|
||||||
|
window_rs = renderstate();
|
||||||
|
window_rs.blendEnabled = 1;
|
||||||
|
window_rs.depthTestEnabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
window_rs.clearColor[0] = winbgcolor.r;
|
||||||
|
window_rs.clearColor[1] = winbgcolor.g;
|
||||||
|
window_rs.clearColor[2] = winbgcolor.b;
|
||||||
|
window_rs.clearColor[3] = window_has_transparent() ? 0 : winbgcolor.a;
|
||||||
|
|
||||||
// @transparent debug
|
// @transparent debug
|
||||||
// if( input_down(KEY_F1) ) window_transparent(window_has_transparent()^1);
|
// if( input_down(KEY_F1) ) window_transparent(window_has_transparent()^1);
|
||||||
// if( input_down(KEY_F2) ) window_maximize(window_has_maximize()^1);
|
// if( input_down(KEY_F2) ) window_maximize(window_has_maximize()^1);
|
||||||
|
@ -242,30 +255,8 @@ void glNewFrame() {
|
||||||
g->width = w;
|
g->width = w;
|
||||||
g->height = h;
|
g->height = h;
|
||||||
|
|
||||||
// blending defaults
|
renderstate_apply(&window_rs);
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
// culling defaults
|
|
||||||
// glEnable(GL_CULL_FACE);
|
|
||||||
// glCullFace(GL_BACK);
|
|
||||||
// glFrontFace(GL_CCW);
|
|
||||||
|
|
||||||
// depth-testing defaults
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
// glDepthFunc(GL_LESS);
|
|
||||||
|
|
||||||
// depth-writing defaults
|
|
||||||
// glDepthMask(GL_TRUE);
|
|
||||||
|
|
||||||
// seamless cubemaps
|
|
||||||
// glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
|
||||||
|
|
||||||
glViewport(0, 0, window_width(), window_height());
|
|
||||||
|
|
||||||
// GLfloat bgColor[4]; glGetFloatv(GL_COLOR_CLEAR_VALUE, bgColor);
|
|
||||||
glClearColor(winbgcolor.r, winbgcolor.g, winbgcolor.b, window_has_transparent() ? 0 : winbgcolor.a); // @transparent
|
|
||||||
//glClearColor(0.15,0.15,0.15,1);
|
|
||||||
//glClearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
|
|
||||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
277
engine/v4k.c
277
engine/v4k.c
|
@ -10256,6 +10256,9 @@ typedef struct font_t {
|
||||||
// vbos
|
// vbos
|
||||||
GLuint vbo_quad; // vec2: simply just a regular [0,1]x[0,1] quad
|
GLuint vbo_quad; // vec2: simply just a regular [0,1]x[0,1] quad
|
||||||
GLuint vbo_instances; // vec4: (char_pos_x, char_pos_y, char_index, color_index)
|
GLuint vbo_instances; // vec4: (char_pos_x, char_pos_y, char_index, color_index)
|
||||||
|
|
||||||
|
// render state
|
||||||
|
renderstate_t rs;
|
||||||
} font_t;
|
} font_t;
|
||||||
|
|
||||||
enum { FONTS_MAX = 10 };
|
enum { FONTS_MAX = 10 };
|
||||||
|
@ -10594,6 +10597,16 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
||||||
glUniform2f(glGetUniformLocation(f->program, "res_meta"), f->num_glyphs, 2);
|
glUniform2f(glGetUniformLocation(f->program, "res_meta"), f->num_glyphs, 2);
|
||||||
glUniform1f(glGetUniformLocation(f->program, "num_colors"), FONT_MAX_COLORS);
|
glUniform1f(glGetUniformLocation(f->program, "num_colors"), FONT_MAX_COLORS);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
|
|
||||||
|
// set up pipeline
|
||||||
|
f->rs = renderstate();
|
||||||
|
f->rs.blendEnabled = 1;
|
||||||
|
f->rs.blendFunc = GL_FUNC_ADD;
|
||||||
|
f->rs.blendSrc = GL_SRC_ALPHA;
|
||||||
|
f->rs.blendDst = GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
f->rs.scissorTestEnabled = 1;
|
||||||
|
f->rs.depthTestEnabled = 0;
|
||||||
|
f->rs.cullFaceEnabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void font_face(const char *tag, const char *filename_ttf, float font_size, unsigned flags) {
|
void font_face(const char *tag, const char *filename_ttf, float font_size, unsigned flags) {
|
||||||
|
@ -10624,25 +10637,10 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_1D, &last_texture2);
|
glGetIntegerv(GL_TEXTURE_BINDING_1D, &last_texture2);
|
||||||
|
|
||||||
glGetIntegerv(GL_BLEND_SRC, &last_blend_src);
|
f->rs.scissorBox[0] = rect.x;
|
||||||
glGetIntegerv(GL_BLEND_DST, &last_blend_dst);
|
f->rs.scissorBox[1] = window_height() - (rect.y+rect.w);
|
||||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb);
|
f->rs.scissorBox[2] = rect.z;
|
||||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha);
|
f->rs.scissorBox[3] = rect.w;
|
||||||
|
|
||||||
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
|
||||||
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
|
||||||
GLboolean last_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
// Setup render state: alpha-blending enabled, no depth testing, enable clipping and bind textures
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
// @fixme: store existing scissor test setup
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glScissor(rect.x, window_height() - (rect.y+rect.w), rect.z, rect.w);
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, f->texture_fontdata);
|
glBindTexture(GL_TEXTURE_2D, f->texture_fontdata);
|
||||||
|
@ -10668,6 +10666,9 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, f->vbo_instances);
|
glBindBuffer(GL_ARRAY_BUFFER, f->vbo_instances);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*glyph_idx, glyph_data);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*glyph_idx, glyph_data);
|
||||||
|
|
||||||
|
// setup pipeline
|
||||||
|
renderstate_apply(&f->rs);
|
||||||
|
|
||||||
// actual drawing
|
// actual drawing
|
||||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx);
|
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx);
|
||||||
|
|
||||||
|
@ -10681,13 +10682,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
||||||
|
|
||||||
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
|
||||||
glBindVertexArray(last_vertex_array);
|
glBindVertexArray(last_vertex_array);
|
||||||
glBlendFunc(last_blend_src, last_blend_dst);
|
|
||||||
|
|
||||||
(last_enable_depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
|
|
||||||
(last_enable_blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND));
|
|
||||||
(last_scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. call font_face() if it's the first time it's called.
|
// 1. call font_face() if it's the first time it's called.
|
||||||
|
@ -17222,6 +17217,154 @@ void glCopyBackbufferToTexture( texture_t *tex ) { // unused
|
||||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, window_width(), window_height(), 0 );
|
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, window_width(), window_height(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// renderstate
|
||||||
|
|
||||||
|
renderstate_t renderstate() {
|
||||||
|
renderstate_t state = {0};
|
||||||
|
|
||||||
|
// Set default viewport parameters
|
||||||
|
state.viewportX = 0;
|
||||||
|
state.viewportY = 0;
|
||||||
|
state.viewportWidth = window_width();
|
||||||
|
state.viewportHeight = window_height();
|
||||||
|
|
||||||
|
// Set default clear color to black
|
||||||
|
state.clearColor[0] = 0.0f; // Red
|
||||||
|
state.clearColor[1] = 0.0f; // Green
|
||||||
|
state.clearColor[2] = 0.0f; // Blue
|
||||||
|
state.clearColor[3] = 1.0f; // Alpha
|
||||||
|
|
||||||
|
// Set default clear depth to maximum distance
|
||||||
|
state.clearDepth = 1.0;
|
||||||
|
|
||||||
|
// Enable depth test by default with less or equal function
|
||||||
|
state.depthTestEnabled = GL_TRUE;
|
||||||
|
state.depthFunc = GL_LEQUAL;
|
||||||
|
|
||||||
|
// Disable blending by default
|
||||||
|
state.blendEnabled = GL_FALSE;
|
||||||
|
state.blendFunc = GL_FUNC_ADD;
|
||||||
|
state.blendSrc = GL_ONE;
|
||||||
|
state.blendDst = GL_ZERO;
|
||||||
|
|
||||||
|
// Enable culling by default and cull back faces
|
||||||
|
state.cullFaceEnabled = GL_TRUE;
|
||||||
|
state.cullFaceMode = GL_BACK;
|
||||||
|
|
||||||
|
// Disable stencil test by default
|
||||||
|
state.stencilTestEnabled = GL_FALSE;
|
||||||
|
state.stencilFunc = GL_ALWAYS;
|
||||||
|
state.stencilRef = 0;
|
||||||
|
state.stencilMask = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// Set default front face to counter-clockwise
|
||||||
|
state.frontFace = GL_CCW;
|
||||||
|
|
||||||
|
// Set default line width
|
||||||
|
state.smoothLineEnabled = GL_FALSE;
|
||||||
|
state.lineWidth = 1.0f;
|
||||||
|
|
||||||
|
// Set default point size
|
||||||
|
state.pointSizeEnabled = GL_FALSE;
|
||||||
|
state.pointSize = 1.0f;
|
||||||
|
|
||||||
|
// Set default polygon mode to fill
|
||||||
|
state.polygonModeFace = GL_FRONT_AND_BACK;
|
||||||
|
state.polygonModeMode = GL_FILL;
|
||||||
|
|
||||||
|
// Disable scissor test by default
|
||||||
|
state.scissorTestEnabled = GL_FALSE;
|
||||||
|
state.scissorBox[0] = 0;
|
||||||
|
state.scissorBox[1] = 0;
|
||||||
|
state.scissorBox[2] = window_width();
|
||||||
|
state.scissorBox[3] = window_height();
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB) {
|
||||||
|
return memcmp(stateA, stateB, sizeof(renderstate_t)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderstate_apply(const renderstate_t *state) {
|
||||||
|
if (state != NULL) {
|
||||||
|
// Apply viewport parameters
|
||||||
|
glViewport(state->viewportX, state->viewportY, state->viewportWidth, state->viewportHeight);
|
||||||
|
|
||||||
|
// Apply clear color
|
||||||
|
glClearColor(state->clearColor[0], state->clearColor[1], state->clearColor[2], state->clearColor[3]);
|
||||||
|
|
||||||
|
// Apply clear depth
|
||||||
|
glClearDepth(state->clearDepth);
|
||||||
|
|
||||||
|
// Apply depth test
|
||||||
|
if (state->depthTestEnabled) {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(state->depthFunc);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply blending
|
||||||
|
if (state->blendEnabled) {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendEquation(state->blendFunc);
|
||||||
|
glBlendFunc(state->blendSrc, state->blendDst);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply culling @fixme
|
||||||
|
// if (state->cullFaceEnabled) {
|
||||||
|
// glEnable(GL_CULL_FACE);
|
||||||
|
// glCullFace(state->cullFaceMode);
|
||||||
|
// } else {
|
||||||
|
// glDisable(GL_CULL_FACE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Apply stencil test
|
||||||
|
if (state->stencilTestEnabled) {
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilFunc(state->stencilFunc, state->stencilRef, state->stencilMask);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply front face direction @fixme
|
||||||
|
// glFrontFace(state->frontFace);
|
||||||
|
|
||||||
|
// Apply line width
|
||||||
|
glLineWidth(state->lineWidth);
|
||||||
|
|
||||||
|
// apply smooth lines
|
||||||
|
if (state->smoothLineEnabled) {
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply point size
|
||||||
|
if (state->pointSizeEnabled) {
|
||||||
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
glPointSize(state->pointSize);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply polygon mode
|
||||||
|
glPolygonMode(state->polygonModeFace, state->polygonModeMode);
|
||||||
|
|
||||||
|
// Apply scissor test
|
||||||
|
if (state->scissorTestEnabled) {
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(state->scissorBox[0], state->scissorBox[1], state->scissorBox[2], state->scissorBox[3]);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// shaders
|
// shaders
|
||||||
|
|
||||||
|
@ -17696,7 +17839,7 @@ typedef map(unsigned,int) uniform_binding;
|
||||||
static __thread unsigned last_shader = -1;
|
static __thread unsigned last_shader = -1;
|
||||||
static __thread quarks_db uniform_names;
|
static __thread quarks_db uniform_names;
|
||||||
static __thread map(handle, uniform_binding) uniforms;
|
static __thread map(handle, uniform_binding) uniforms;
|
||||||
static
|
|
||||||
int shader_uniform(const char *name) {
|
int shader_uniform(const char *name) {
|
||||||
do_once map_init(uniforms, less_int, hash_int);
|
do_once map_init(uniforms, less_int, hash_int);
|
||||||
if (!map_find(uniforms, last_shader)) {
|
if (!map_find(uniforms, last_shader)) {
|
||||||
|
@ -19026,17 +19169,21 @@ void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength) {
|
||||||
|
|
||||||
API vec4 window_getcolor_(); // internal use, not public
|
API vec4 window_getcolor_(); // internal use, not public
|
||||||
|
|
||||||
|
static renderstate_t skybox_rs;
|
||||||
|
|
||||||
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
last_cubemap = &sky->cubemap;
|
last_cubemap = &sky->cubemap;
|
||||||
|
|
||||||
//glClear(GL_DEPTH_BUFFER_BIT);
|
do_once {
|
||||||
//glEnable(GL_DEPTH_TEST);
|
skybox_rs = renderstate();
|
||||||
glDepthFunc(GL_LEQUAL);
|
}
|
||||||
//glDisable(GL_CULL_FACE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// we have to reset clear color here, because of wrong alpha compositing issues on native transparent windows otherwise
|
// we have to reset clear color here, because of wrong alpha compositing issues on native transparent windows otherwise
|
||||||
vec4 bgcolor = window_getcolor_(); glClearColor(bgcolor.r, bgcolor.g, bgcolor.b, 1); // @transparent
|
vec4 bgcolor = window_getcolor_();
|
||||||
|
skybox_rs.clearColor[0] = bgcolor.r;
|
||||||
|
skybox_rs.clearColor[1] = bgcolor.g;
|
||||||
|
skybox_rs.clearColor[2] = bgcolor.b;
|
||||||
|
skybox_rs.clearColor[3] = 1; // @transparent
|
||||||
|
|
||||||
mat44 mvp; multiply44x2(mvp, proj, view);
|
mat44 mvp; multiply44x2(mvp, proj, view);
|
||||||
|
|
||||||
|
@ -19046,6 +19193,8 @@ int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
if( sky->flags ) {
|
if( sky->flags ) {
|
||||||
shader_cubemap("u_cubemap", sky->cubemap.id);
|
shader_cubemap("u_cubemap", sky->cubemap.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderstate_apply(&skybox_rs);
|
||||||
return 0; // @fixme: return sortable hash here?
|
return 0; // @fixme: return sortable hash here?
|
||||||
}
|
}
|
||||||
int skybox_pop_state() {
|
int skybox_pop_state() {
|
||||||
|
@ -19056,7 +19205,6 @@ int skybox_pop_state() {
|
||||||
}
|
}
|
||||||
int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
|
int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
|
||||||
skybox_push_state(sky, proj, view);
|
skybox_push_state(sky, proj, view);
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
mesh_render(&sky->geometry);
|
mesh_render(&sky->geometry);
|
||||||
skybox_pop_state();
|
skybox_pop_state();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -20715,6 +20863,11 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model,
|
||||||
model_t model_from_mem(const void *mem, int len, int flags) {
|
model_t model_from_mem(const void *mem, int len, int flags) {
|
||||||
model_t m = {0};
|
model_t m = {0};
|
||||||
|
|
||||||
|
{
|
||||||
|
m.rs = renderstate();
|
||||||
|
m.rs.blendEnabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
m.stored_flags = flags;
|
m.stored_flags = flags;
|
||||||
m.shading = SHADING_PHONG;
|
m.shading = SHADING_PHONG;
|
||||||
|
|
||||||
|
@ -20998,6 +21151,8 @@ void model_draw_call(model_t m, int shader) {
|
||||||
handle old_shader = last_shader;
|
handle old_shader = last_shader;
|
||||||
shader_bind(shader);
|
shader_bind(shader);
|
||||||
|
|
||||||
|
renderstate_apply(&m.rs);
|
||||||
|
|
||||||
glBindVertexArray( q->vao );
|
glBindVertexArray( q->vao );
|
||||||
|
|
||||||
struct iqmtriangle *tris = NULL;
|
struct iqmtriangle *tris = NULL;
|
||||||
|
@ -21296,6 +21451,7 @@ typedef struct text2d_cmd {
|
||||||
float sca;
|
float sca;
|
||||||
} text2d_cmd;
|
} text2d_cmd;
|
||||||
|
|
||||||
|
static renderstate_t dd_rs;
|
||||||
static uint32_t dd_color = ~0u;
|
static uint32_t dd_color = ~0u;
|
||||||
static GLuint dd_program = -1;
|
static GLuint dd_program = -1;
|
||||||
static int dd_u_color = -1;
|
static int dd_u_color = -1;
|
||||||
|
@ -21329,7 +21485,9 @@ void ddraw_flush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddraw_flush_projview(mat44 proj, mat44 view) {
|
void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
do_once dd_rs = renderstate();
|
||||||
|
|
||||||
|
dd_rs.depthTestEnabled = 1;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
mat44 mvp;
|
mat44 mvp;
|
||||||
|
@ -21344,16 +21502,16 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
dd_rs.pointSizeEnabled = 1;
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE); // for GL_POINTS
|
dd_rs.smoothLineEnabled = 1;
|
||||||
glEnable(GL_LINE_SMOOTH); // for GL_LINES (thin)
|
|
||||||
|
|
||||||
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
||||||
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
||||||
glLineWidth(i == 1 ? 1 : 0.3); // 0.625);
|
dd_rs.lineWidth = (i == 1 ? 1 : 0.3); // 0.625);
|
||||||
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
||||||
int count = array_count(list);
|
int count = array_count(list);
|
||||||
if(!count) continue;
|
if(!count) continue;
|
||||||
|
renderstate_apply(&dd_rs);
|
||||||
// color
|
// color
|
||||||
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
||||||
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
||||||
|
@ -21382,10 +21540,11 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
|
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
|
||||||
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
for( int i = 0; i < 3; ++i ) { // [0] thin, [1] thick, [2] points
|
||||||
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
GLenum mode = i < 2 ? GL_LINES : GL_POINTS;
|
||||||
glLineWidth(i == 1 ? 1 : 0.3); // 0.625);
|
dd_rs.lineWidth = (i == 1 ? 1 : 0.3); // 0.625);
|
||||||
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
for each_map(dd_lists[dd_ontop][i], unsigned, rgb, array(vec3), list) {
|
||||||
int count = array_count(list);
|
int count = array_count(list);
|
||||||
if(!count) continue;
|
if(!count) continue;
|
||||||
|
renderstate_apply(&dd_rs);
|
||||||
// color
|
// color
|
||||||
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
vec3 rgbf = {((rgb>>0)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>16)&255)/255.f};
|
||||||
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x);
|
||||||
|
@ -21404,9 +21563,6 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
|
||||||
array_resize(dd_text2d, 0);
|
array_resize(dd_text2d, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_LINE_SMOOTH);
|
|
||||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
ddraw_color(WHITE); // reset color for next drawcall
|
ddraw_color(WHITE); // reset color for next drawcall
|
||||||
|
@ -26682,7 +26838,20 @@ struct nk_glfw *window_handle_nkglfw() {
|
||||||
return g->nk_glfw;
|
return g->nk_glfw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static renderstate_t window_rs;
|
||||||
|
|
||||||
void glNewFrame() {
|
void glNewFrame() {
|
||||||
|
do_once {
|
||||||
|
window_rs = renderstate();
|
||||||
|
window_rs.blendEnabled = 1;
|
||||||
|
window_rs.depthTestEnabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
window_rs.clearColor[0] = winbgcolor.r;
|
||||||
|
window_rs.clearColor[1] = winbgcolor.g;
|
||||||
|
window_rs.clearColor[2] = winbgcolor.b;
|
||||||
|
window_rs.clearColor[3] = window_has_transparent() ? 0 : winbgcolor.a;
|
||||||
|
|
||||||
// @transparent debug
|
// @transparent debug
|
||||||
// if( input_down(KEY_F1) ) window_transparent(window_has_transparent()^1);
|
// if( input_down(KEY_F1) ) window_transparent(window_has_transparent()^1);
|
||||||
// if( input_down(KEY_F2) ) window_maximize(window_has_maximize()^1);
|
// if( input_down(KEY_F2) ) window_maximize(window_has_maximize()^1);
|
||||||
|
@ -26703,30 +26872,8 @@ void glNewFrame() {
|
||||||
g->width = w;
|
g->width = w;
|
||||||
g->height = h;
|
g->height = h;
|
||||||
|
|
||||||
// blending defaults
|
renderstate_apply(&window_rs);
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
// culling defaults
|
|
||||||
// glEnable(GL_CULL_FACE);
|
|
||||||
// glCullFace(GL_BACK);
|
|
||||||
// glFrontFace(GL_CCW);
|
|
||||||
|
|
||||||
// depth-testing defaults
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
// glDepthFunc(GL_LESS);
|
|
||||||
|
|
||||||
// depth-writing defaults
|
|
||||||
// glDepthMask(GL_TRUE);
|
|
||||||
|
|
||||||
// seamless cubemaps
|
|
||||||
// glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
|
||||||
|
|
||||||
glViewport(0, 0, window_width(), window_height());
|
|
||||||
|
|
||||||
// GLfloat bgColor[4]; glGetFloatv(GL_COLOR_CLEAR_VALUE, bgColor);
|
|
||||||
glClearColor(winbgcolor.r, winbgcolor.g, winbgcolor.b, window_has_transparent() ? 0 : winbgcolor.a); // @transparent
|
|
||||||
//glClearColor(0.15,0.15,0.15,1);
|
|
||||||
//glClearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
|
|
||||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
61
engine/v4k.h
61
engine/v4k.h
|
@ -3097,6 +3097,65 @@ API int ui_reflect(const char *mask); // *, model* or NULL
|
||||||
|
|
||||||
typedef unsigned handle; // GLuint
|
typedef unsigned handle; // GLuint
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// renderstate
|
||||||
|
typedef struct renderstate_t {
|
||||||
|
// Viewport parameters
|
||||||
|
int viewportX;
|
||||||
|
int viewportY;
|
||||||
|
int viewportWidth;
|
||||||
|
int viewportHeight;
|
||||||
|
|
||||||
|
// Clear color
|
||||||
|
float clearColor[4];
|
||||||
|
|
||||||
|
// Clear depth
|
||||||
|
double clearDepth;
|
||||||
|
|
||||||
|
// Depth test
|
||||||
|
bool depthTestEnabled;
|
||||||
|
unsigned depthFunc;
|
||||||
|
|
||||||
|
// Blending
|
||||||
|
bool blendEnabled;
|
||||||
|
unsigned blendFunc;
|
||||||
|
unsigned blendSrc;
|
||||||
|
unsigned blendDst;
|
||||||
|
|
||||||
|
// Culling
|
||||||
|
bool cullFaceEnabled;
|
||||||
|
unsigned cullFaceMode;
|
||||||
|
|
||||||
|
// Stencil test
|
||||||
|
bool stencilTestEnabled;
|
||||||
|
unsigned stencilFunc;
|
||||||
|
int stencilRef;
|
||||||
|
unsigned stencilMask;
|
||||||
|
|
||||||
|
// Face culling direction
|
||||||
|
unsigned frontFace; // GL_CW or GL_CCW
|
||||||
|
|
||||||
|
// Line width
|
||||||
|
bool smoothLineEnabled;
|
||||||
|
float lineWidth;
|
||||||
|
|
||||||
|
// Point size
|
||||||
|
bool pointSizeEnabled;
|
||||||
|
float pointSize;
|
||||||
|
|
||||||
|
// Polygon mode
|
||||||
|
unsigned polygonModeFace;
|
||||||
|
unsigned polygonModeMode;
|
||||||
|
|
||||||
|
// Scissor test
|
||||||
|
bool scissorTestEnabled;
|
||||||
|
int scissorBox[4];
|
||||||
|
} renderstate_t;
|
||||||
|
|
||||||
|
API renderstate_t renderstate();
|
||||||
|
API bool renderstate_compare(const renderstate_t *stateA, const renderstate_t *stateB);
|
||||||
|
API void renderstate_apply(const renderstate_t *state);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// colors
|
// colors
|
||||||
|
|
||||||
|
@ -3317,6 +3376,7 @@ API void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float botto
|
||||||
API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
API unsigned shader(const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
API unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char *attribs, const char *fragcolor, const char *defines);
|
||||||
API unsigned shader_bind(unsigned program);
|
API unsigned shader_bind(unsigned program);
|
||||||
|
API int shader_uniform(const char *name);
|
||||||
API void shader_bool(const char *uniform, bool i );
|
API void shader_bool(const char *uniform, bool i );
|
||||||
API void shader_int(const char *uniform, int i);
|
API void shader_int(const char *uniform, int i);
|
||||||
API void shader_uint(const char *uniform, unsigned i );
|
API void shader_uint(const char *uniform, unsigned i );
|
||||||
|
@ -3666,6 +3726,7 @@ typedef struct model_t {
|
||||||
unsigned num_instances;
|
unsigned num_instances;
|
||||||
|
|
||||||
int stored_flags;
|
int stored_flags;
|
||||||
|
renderstate_t rs;
|
||||||
} model_t;
|
} model_t;
|
||||||
|
|
||||||
enum BILLBOARD_MODE {
|
enum BILLBOARD_MODE {
|
||||||
|
|
Loading…
Reference in New Issue