Merge pull request #43498 from lawnjelly/ewok_poly_modulate

Poly colors fixes
This commit is contained in:
Rémi Verschelde 2020-11-16 09:58:36 +01:00 committed by GitHub
commit b38f7af4fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 164 additions and 125 deletions

View File

@ -135,60 +135,13 @@ void RasterizerCanvasGLES2::_batch_render_lines(const Batch &p_batch, Rasterizer
#endif
}
void RasterizerCanvasGLES2::_batch_render_polys(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material) {
_set_texture_rect_mode(false);
if (state.canvas_shader.bind()) {
_set_uniforms();
state.canvas_shader.use_material((void *)p_material);
}
// batch tex
const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
_bind_canvas_texture(tex.RID_texture, tex.RID_normal);
// state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, Transform());
int sizeof_vert = sizeof(BatchVertexColored);
// bind the index and vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer);
uint64_t pointer = 0;
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof_vert, (const void *)pointer);
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (2 * 4)));
glEnableVertexAttribArray(VS::ARRAY_COLOR);
glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (4 * 4)));
int64_t offset = p_batch.first_vert; // 6 inds per quad at 2 bytes each
int num_elements = p_batch.num_commands;
glDrawArrays(GL_TRIANGLES, offset, num_elements);
storage->info.render._2d_draw_call_count++;
// could these have ifs?
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
glDisableVertexAttribArray(VS::ARRAY_COLOR);
// may not be necessary .. state change optimization still TODO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void RasterizerCanvasGLES2::_batch_render_rects(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material) {
void RasterizerCanvasGLES2::_batch_render_generic(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material) {
ERR_FAIL_COND(p_batch.num_commands <= 0);
const bool &colored_verts = bdata.use_colored_vertices;
const bool &use_light_angles = bdata.use_light_angles;
const bool &use_modulate = bdata.use_modulate;
const bool &use_large_verts = bdata.use_large_verts;
const bool &colored_verts = bdata.use_colored_vertices | use_light_angles | use_modulate | use_large_verts;
int sizeof_vert;
@ -196,9 +149,10 @@ void RasterizerCanvasGLES2::_batch_render_rects(const Batch &p_batch, Rasterizer
default:
sizeof_vert = 0; // prevent compiler warning - this should never happen
break;
case RasterizerStorageCommon::FVF_UNBATCHED: // should not happen
case RasterizerStorageCommon::FVF_UNBATCHED: {
sizeof_vert = 0; // prevent compiler warning - this should never happen
return;
break;
} break;
case RasterizerStorageCommon::FVF_REGULAR: // no change
sizeof_vert = sizeof(BatchVertex);
break;
@ -216,13 +170,11 @@ void RasterizerCanvasGLES2::_batch_render_rects(const Batch &p_batch, Rasterizer
break;
}
// batch tex
const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
// make sure to set all conditionals BEFORE binding the shader
//state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
_set_texture_rect_mode(false, use_light_angles, use_modulate, use_large_verts);
// batch tex
const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
//VSG::rasterizer->gl_check_for_error();
// force repeat is set if non power of 2 texture, and repeat is needed if hardware doesn't support npot
@ -235,9 +187,6 @@ void RasterizerCanvasGLES2::_batch_render_rects(const Batch &p_batch, Rasterizer
state.canvas_shader.use_material((void *)p_material);
}
// batch tex
//const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
_bind_canvas_texture(tex.RID_texture, tex.RID_normal);
// bind the index and vertex buffer
@ -297,10 +246,23 @@ void RasterizerCanvasGLES2::_batch_render_rects(const Batch &p_batch, Rasterizer
tex.tex_pixel_size.to(tps);
state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, tps);
int64_t offset = p_batch.first_vert * 3;
switch (p_batch.type) {
default: {
// prevent compiler warning
} break;
case RasterizerStorageCommon::BT_RECT: {
int64_t offset = p_batch.first_vert * 3;
int num_elements = p_batch.num_commands * 6;
glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_SHORT, (void *)offset);
int num_elements = p_batch.num_commands * 6;
glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_SHORT, (void *)offset);
} break;
case RasterizerStorageCommon::BT_POLY: {
int64_t offset = p_batch.first_vert;
int num_elements = p_batch.num_commands;
glDrawArrays(GL_TRIANGLES, offset, num_elements);
} break;
}
storage->info.render._2d_draw_call_count++;
@ -341,10 +303,10 @@ void RasterizerCanvasGLES2::render_batches(Item::Command *const *p_commands, Ite
switch (batch.type) {
case RasterizerStorageCommon::BT_RECT: {
_batch_render_rects(batch, p_material);
_batch_render_generic(batch, p_material);
} break;
case RasterizerStorageCommon::BT_POLY: {
_batch_render_polys(batch, p_material);
_batch_render_generic(batch, p_material);
} break;
case RasterizerStorageCommon::BT_LINE: {
_batch_render_lines(batch, p_material, false);

View File

@ -59,8 +59,7 @@ private:
// low level batch funcs
void _batch_upload_buffers();
void _batch_render_rects(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material);
void _batch_render_polys(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material);
void _batch_render_generic(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material);
void _batch_render_lines(const Batch &p_batch, RasterizerStorageGLES2::Material *p_material, bool p_anti_alias);
// funcs used from rasterizer_canvas_batcher template

View File

@ -479,13 +479,13 @@ FRAGMENT_SHADER_CODE
normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
#endif
}
#ifdef USE_ATTRIB_MODULATE
color *= modulate_interp;
#else
#if !defined(MODULATE_USED)
color *= final_modulate;
#endif
#ifdef USE_ATTRIB_MODULATE
// todo .. this won't be used at the same time as MODULATE_USED
color *= modulate_interp;
#endif
#ifdef USE_LIGHTING

View File

@ -511,10 +511,10 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
switch (batch.type) {
case RasterizerStorageCommon::BT_RECT: {
_batch_render_rects(batch, p_material);
_batch_render_generic(batch, p_material);
} break;
case RasterizerStorageCommon::BT_POLY: {
_batch_render_polys(batch, p_material);
_batch_render_generic(batch, p_material);
} break;
case RasterizerStorageCommon::BT_LINE: {
_batch_render_lines(batch, p_material, false);
@ -2036,43 +2036,8 @@ void RasterizerCanvasGLES3::_batch_render_lines(const Batch &p_batch, Rasterizer
#endif
}
void RasterizerCanvasGLES3::_batch_render_polys(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material) {
ERR_FAIL_COND(p_batch.num_commands <= 0);
_set_texture_rect_mode(false);
state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false);
glBindVertexArray(batch_gl_data.batch_vertex_array[1]);
// batch tex
const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
_bind_canvas_texture(tex.RID_texture, tex.RID_normal);
// may not need this disable
// glDisableVertexAttribArray(VS::ARRAY_COLOR);
// glVertexAttrib4fv(VS::ARRAY_COLOR, p_batch.color.get_data());
// we need to convert explicitly from pod Vec2 to Vector2 ...
// could use a cast but this might be unsafe in future
Vector2 tps;
tex.tex_pixel_size.to(tps);
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, tps);
int64_t offset = p_batch.first_vert;
int num_elements = p_batch.num_commands;
glDrawArrays(GL_TRIANGLES, offset, num_elements);
storage->info.render._2d_draw_call_count++;
glBindVertexArray(0);
}
void RasterizerCanvasGLES3::_batch_render_rects(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material) {
ERR_FAIL_COND(p_batch.num_commands <= 0);
const bool &colored_verts = bdata.use_colored_vertices;
void RasterizerCanvasGLES3::_batch_render_prepare() {
//const bool &colored_verts = bdata.use_colored_vertices;
const bool &use_light_angles = bdata.use_light_angles;
const bool &use_modulate = bdata.use_modulate;
const bool &use_large_verts = bdata.use_large_verts;
@ -2102,11 +2067,41 @@ void RasterizerCanvasGLES3::_batch_render_rects(const Batch &p_batch, Rasterizer
glBindVertexArray(batch_gl_data.batch_vertex_array[4]);
break;
}
}
// if (state.canvas_shader.bind()) {
// _set_uniforms();
// state.canvas_shader.use_material((void *)p_material);
// }
void RasterizerCanvasGLES3::_batch_render_generic(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material) {
ERR_FAIL_COND(p_batch.num_commands <= 0);
const bool &use_light_angles = bdata.use_light_angles;
const bool &use_modulate = bdata.use_modulate;
const bool &use_large_verts = bdata.use_large_verts;
const bool &colored_verts = bdata.use_colored_vertices | use_light_angles | use_modulate | use_large_verts;
_set_texture_rect_mode(false, false, use_light_angles, use_modulate, use_large_verts);
// state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, p_rect->flags & CANVAS_RECT_CLIP_UV);
state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false);
switch (bdata.fvf) {
case RasterizerStorageCommon::FVF_UNBATCHED: // should not happen
return;
break;
case RasterizerStorageCommon::FVF_REGULAR: // no change
glBindVertexArray(batch_gl_data.batch_vertex_array[0]);
break;
case RasterizerStorageCommon::FVF_COLOR:
glBindVertexArray(batch_gl_data.batch_vertex_array[1]);
break;
case RasterizerStorageCommon::FVF_LIGHT_ANGLE:
glBindVertexArray(batch_gl_data.batch_vertex_array[2]);
break;
case RasterizerStorageCommon::FVF_MODULATED:
glBindVertexArray(batch_gl_data.batch_vertex_array[3]);
break;
case RasterizerStorageCommon::FVF_LARGE:
glBindVertexArray(batch_gl_data.batch_vertex_array[4]);
break;
}
// batch tex
const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
@ -2143,10 +2138,23 @@ void RasterizerCanvasGLES3::_batch_render_rects(const Batch &p_batch, Rasterizer
tex.tex_pixel_size.to(tps);
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, tps);
int64_t offset = p_batch.first_vert * 3; // 6 inds per quad at 2 bytes each
switch (p_batch.type) {
default: {
// prevent compiler warning
} break;
case RasterizerStorageCommon::BT_RECT: {
int64_t offset = p_batch.first_vert * 3; // 6 inds per quad at 2 bytes each
int num_elements = p_batch.num_commands * 6;
glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_SHORT, (void *)offset);
int num_elements = p_batch.num_commands * 6;
glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_SHORT, (void *)offset);
} break;
case RasterizerStorageCommon::BT_POLY: {
int64_t offset = p_batch.first_vert;
int num_elements = p_batch.num_commands;
glDrawArrays(GL_TRIANGLES, offset, num_elements);
} break;
}
storage->info.render._2d_draw_call_count++;

View File

@ -62,8 +62,8 @@ private:
// low level batch funcs
void _batch_upload_buffers();
void _batch_render_rects(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material);
void _batch_render_polys(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material);
void _batch_render_prepare();
void _batch_render_generic(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material);
void _batch_render_lines(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material, bool p_anti_alias);
// funcs used from rasterizer_canvas_batcher template

View File

@ -66,7 +66,7 @@ out mediump vec4 color_interp;
#ifdef USE_ATTRIB_MODULATE
// modulate doesn't need interpolating but we need to send it to the fragment shader
out mediump vec4 modulate_interp;
flat out mediump vec4 modulate_interp;
#endif
#ifdef MODULATE_USED
@ -332,7 +332,7 @@ in highp vec2 uv_interp;
in mediump vec4 color_interp;
#ifdef USE_ATTRIB_MODULATE
in mediump vec4 modulate_interp;
flat in mediump vec4 modulate_interp;
#endif
#if defined(SCREEN_TEXTURE_USED)
@ -582,13 +582,12 @@ FRAGMENT_SHADER_CODE
color = vec4(vec3(enc32), 1.0);
#endif
#ifdef USE_ATTRIB_MODULATE
color *= modulate_interp;
#else
#if !defined(MODULATE_USED)
color *= final_modulate;
#endif
#ifdef USE_ATTRIB_MODULATE
// todo .. this won't be used at the same time as MODULATE_USED
color *= modulate_interp;
#endif
#ifdef USE_LIGHTING

View File

@ -1492,9 +1492,42 @@ bool C_PREAMBLE::_prefill_polygon(RasterizerCanvas::Item::CommandPolygon *p_poly
CRASH_COND(!vertex_colors);
#endif
// are we using large FVF?
////////////////////////////////////
const bool use_large_verts = bdata.use_large_verts;
const bool use_modulate = bdata.use_modulate;
BatchColor *vertex_modulates = nullptr;
if (use_modulate) {
vertex_modulates = bdata.vertex_modulates.request(num_inds);
#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
CRASH_COND(!vertex_modulates);
#endif
// precalc the vertex modulate (will be shared by all verts)
// we store the modulate as an attribute in the fvf rather than a uniform
vertex_modulates[0].set(r_fill_state.final_modulate);
}
BatchTransform *pBT = nullptr;
if (use_large_verts) {
pBT = bdata.vertex_transforms.request(num_inds);
#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
CRASH_COND(!pBT);
#endif
// precalc the batch transform (will be shared by all verts)
// we store the transform as an attribute in the fvf rather than a uniform
const Transform2D &tr = r_fill_state.transform_combined;
pBT[0].translate.set(tr.elements[2]);
// could do swizzling in shader?
pBT[0].basis[0].set(tr.elements[0][0], tr.elements[1][0]);
pBT[0].basis[1].set(tr.elements[0][1], tr.elements[1][1]);
}
////////////////////////////////////
// the modulate is always baked
Color modulate;
if (multiply_final_modulate)
if (!use_large_verts && !use_modulate && multiply_final_modulate)
modulate = r_fill_state.final_modulate;
else
modulate = Color(1, 1, 1, 1);
@ -1508,6 +1541,11 @@ bool C_PREAMBLE::_prefill_polygon(RasterizerCanvas::Item::CommandPolygon *p_poly
}
// N.B. polygons don't have color thus don't need a batch change with color
// This code is left as reference in case of problems.
// if (!r_fill_state.curr_batch->color.equals(modulate)) {
// change_batch = true;
// bdata.total_color_changes++;
// }
if (change_batch) {
// put the tex pixel size in a local (less verbose and can be a register)
@ -1586,8 +1624,32 @@ bool C_PREAMBLE::_prefill_polygon(RasterizerCanvas::Item::CommandPolygon *p_poly
}
vertex_colors[n] = precalced_colors[ind];
if (use_modulate) {
vertex_modulates[n] = vertex_modulates[0];
}
if (use_large_verts) {
// reuse precalced transform (same for each vertex within polygon)
pBT[n] = pBT[0];
}
}
} // if not software skinning
else {
// software skinning extra passes
if (use_modulate) {
for (int n = 0; n < num_inds; n++) {
vertex_modulates[n] = vertex_modulates[0];
}
}
// not sure if this will produce garbage if software skinning is changing vertex pos
// in the shader, but is included for completeness
if (use_large_verts) {
for (int n = 0; n < num_inds; n++) {
pBT[n] = pBT[0];
}
}
}
// increment total vert count
bdata.total_verts += num_inds;
@ -2707,6 +2769,8 @@ T_PREAMBLE
template <class BATCH_VERTEX_TYPE, bool INCLUDE_LIGHT_ANGLES, bool INCLUDE_MODULATE, bool INCLUDE_LARGE>
void C_PREAMBLE::_translate_batches_to_larger_FVF() {
bool include_poly_color = INCLUDE_LIGHT_ANGLES | INCLUDE_MODULATE | INCLUDE_LARGE;
// zeros the size and sets up how big each unit is
bdata.unit_vertices.prepare(sizeof(BATCH_VERTEX_TYPE));
bdata.batches_temp.reset();
@ -2724,6 +2788,7 @@ void C_PREAMBLE::_translate_batches_to_larger_FVF() {
Batch *dest_batch = nullptr;
const BatchColor *source_vertex_colors = &bdata.vertex_colors[0];
const float *source_light_angles = &bdata.light_angles[0];
const BatchColor *source_vertex_modulates = &bdata.vertex_modulates[0];
const BatchTransform *source_vertex_transforms = &bdata.vertex_transforms[0];
@ -2820,7 +2885,13 @@ void C_PREAMBLE::_translate_batches_to_larger_FVF() {
#endif
cv->pos = bv.pos;
cv->uv = bv.uv;
cv->col = source_batch.color;
// polys are special, they can have per vertex colors
if (!include_poly_color) {
cv->col = source_batch.color;
} else {
cv->col = *source_vertex_colors++;
}
if (INCLUDE_LIGHT_ANGLES) {
// this is required to allow compilation with non light angle vertex.