Реализации OpenGL не требуется для поддержки рендеринга широких линий.
Вы можете запросить диапазон поддерживаемых строк ширины с помощью:
GLfloat lineWidthRange[2] = {0.0f, 0.0f};
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
// Maximum supported line width is in lineWidthRange[1].
Необходимый минимум для обоих пределов 1.0, что означает, что поддержка ширины линий больше 1,0 не требуется. Кроме того, рисование широких линий является устаревшей функцией и больше не будет поддерживаться, если вы перейдете на новую версию (основной профиль) OpenGL.
Альтернативой рисованию широких линий является рендеринг тонких полигонов.
Этот парень написал аккуратный небольшой компактор пробелов, который просто запускает быструю блочную копию ваших байтов с помощью регулярного выражения, чтобы вырезать капли пространства. Он написал его как http-модуль, но вы могли взять из него 7 строк кода рабочей лошадки и вставить его в свою функцию.
Если вы возвращаете JSON из представления, он уже минифицирован и не должен содержать пробелов или CR / LF. Вы должны использовать разбиение на страницы, чтобы не отправлять столько данных в браузер одновременно.
Пробелы сжимаются очень хорошо, я не думаю, что их удаление сильно вас спасет.
Я бы посоветовал попытаться выгрузить часть HTML-кода клиенту, если это возможно, используйте JavaScript воссоздавать повторяющиеся вещи.
Я бы сказал, что если ваше представление генерирует более 20 МБ данных, вы можете исследовать различные способы отображения данных, возможно, пейджинг?
#region Stream filter
class StringFilterStream : Stream
{
private Stream _sink;
private Func<string, string> _filter;
public StringFilterStream(Stream sink, Func<string, string> filter) {
_sink = sink;
_filter = filter;
}
#region Mixin Properties/Methods
public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return true; } }
public override bool CanWrite { get { return true; } }
public override void Flush() { _sink.Flush(); }
public override long Length { get { return 0; } }
private long _position;
public override long Position {
get { return _position; }
set { _position = value; }
}
public override int Read(byte[] buffer, int offset, int count) {
return _sink.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin) {
return _sink.Seek(offset, origin);
}
public override void SetLength(long value) {
_sink.SetLength(value);
}
public override void Close() {
_sink.Close();
}
#endregion
public override void Write(byte[] buffer, int offset, int count) {
// intercept the data and convert to string
byte[] data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string s = Encoding.Default.GetString(buffer);
// apply the filter
s = _filter(s);
// write the data back to stream
byte[] outdata = Encoding.Default.GetBytes(s);
_sink.Write(outdata, 0, outdata.GetLength(0));
}
}
#endregion
public enum WebWhitespaceFilterContentType
{
Xml = 0, Css = 1, Javascript = 2
}
public class WebWhitespaceFilterAttribute : ActionFilterAttribute
{
private WebWhitespaceFilterContentType _contentType;
public WebWhitespaceFilterAttribute() {
_contentType = WebWhitespaceFilterContentType.Xml;
}
public WebWhitespaceFilterAttribute(WebWhitespaceFilterContentType contentType) {
_contentType = contentType;
}
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response;
switch (_contentType) {
case WebWhitespaceFilterContentType.Xml:
response.Filter = new StringFilterStream(response.Filter, s => {
s = Regex.Replace(s, @"\s+", " ");
s = Regex.Replace(s, @"\s*\n\s*", "\n");
s = Regex.Replace(s, @"\s*\>\s*\<\s*", "><");
// single-line doctype must be preserved
var firstEndBracketPosition = s.IndexOf(">");
if (firstEndBracketPosition >= 0) {
s = s.Remove(firstEndBracketPosition, 1);
s = s.Insert(firstEndBracketPosition, ">\n");
}
return s;
});
break;
case WebWhitespaceFilterContentType.Css:
case WebWhitespaceFilterContentType.Javascript:
response.Filter = new StringFilterStream(response.Filter, s => {
s = Regex.Replace(s, @"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/", "");
s = Regex.Replace(s, @"\s+", " ");
s = Regex.Replace(s, @"\s*{\s*", "{");
s = Regex.Replace(s, @"\s*}\s*", "}");
s = Regex.Replace(s, @"\s*;\s*", ";");
return s;
});
break;
}
}
}