void C4FoWDrawWireframeStrategy::End(C4ShaderCall& call) { // If we have nothing to draw (e.g. directly after initialization), abort early. if (vertices.empty()) return; glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Upload vertices glBindBuffer(GL_ARRAY_BUFFER, vbo); if (vbo_size < vertices.size()) { glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STREAM_DRAW); vbo_size = vertices.size(); } else { glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vertex), &vertices[0]); } glEnableVertexAttribArray(call.GetAttribute(C4FoWRSA_Position)); glEnableVertexAttribArray(call.GetAttribute(C4FoWRSA_Color)); glVertexAttribPointer(call.GetAttribute(C4FoWRSA_Position), 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const uint8_t*>(offsetof(Vertex, x))); glVertexAttribPointer(call.GetAttribute(C4FoWRSA_Color), 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const uint8_t*>(offsetof(Vertex, r))); // Set Y offset for vertex const float y_offset[] = { 0.0f, 0.0f }; call.SetUniform2fv(C4FoWRSU_VertexOffset, 1, y_offset); glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, triangulator.GetIndices()); // Reset GL state glDisableVertexAttribArray(call.GetAttribute(C4FoWRSA_Position)); glDisableVertexAttribArray(call.GetAttribute(C4FoWRSA_Color)); glBindBuffer(GL_ARRAY_BUFFER, 0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Assume the capacity stays the same: vertices.resize(0); C4FoWDrawStrategy::End(call); }
void C4FoWDrawLightTextureStrategy::End(C4ShaderCall& call) { // If we have nothing to draw (e.g. directly after initialization), abort early. if (vertices.empty()) return; // Upload vertices glBindBuffer(GL_ARRAY_BUFFER, vbo); if (vbo_size < vertices.size()) { glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_DYNAMIC_DRAW); vbo_size = vertices.size(); } else { glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vertex), &vertices[0]); } // Region dimensions const float width = region->getSurfaceWidth(); const float height = region->getSurfaceHeight() / 2.0; // Set Y offset for vertex float y_offset[] = { 0.0f, 0.0f }; call.SetUniform2fv(C4FoWRSU_VertexOffset, 1, y_offset); // Enable scissor test to only draw in upper or lower half of texture glEnable(GL_SCISSOR_TEST); glScissor(0, height, width, height); // Setup state for 1st pass glEnableVertexAttribArray(call.GetAttribute(C4FoWRSA_Position)); glEnableVertexAttribArray(call.GetAttribute(C4FoWRSA_Color)); glVertexAttribPointer(call.GetAttribute(C4FoWRSA_Position), 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const uint8_t*>(offsetof(Vertex, x))); glVertexAttribPointer(call.GetAttribute(C4FoWRSA_Color), 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const uint8_t*>(offsetof(Vertex, r1))); // Set up blend equation, see C4FoWDrawLightTextureStrategy::DrawVertex // for details. glBlendFunc(GL_ONE, GL_ONE); glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); // Render 1st pass glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, triangulator.GetIndices()); // Prepare state for 2nd pass glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glVertexAttribPointer(call.GetAttribute(C4FoWRSA_Color), 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const uint8_t*>(offsetof(Vertex, r2))); // Render 2nd pass glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, triangulator.GetIndices()); // Prepare state for 3rd pass (color pass) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); glScissor(0, 0, width, height); glVertexAttribPointer(call.GetAttribute(C4FoWRSA_Color), 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const uint8_t*>(offsetof(Vertex, r3))); y_offset[1] = height; call.SetUniform2fv(C4FoWRSU_VertexOffset, 1, y_offset); // Render 3rd pass glDrawElements(GL_TRIANGLES, triangulator.GetNIndices(), GL_UNSIGNED_INT, triangulator.GetIndices()); // Reset GL state glDisableVertexAttribArray(call.GetAttribute(C4FoWRSA_Position)); glDisableVertexAttribArray(call.GetAttribute(C4FoWRSA_Color)); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisable(GL_SCISSOR_TEST); // Assume the capacity stays the same: vertices.resize(0); C4FoWDrawStrategy::End(call); }