OpenGL стандартный модуль

А, кстати, я тестировал без .pcu, то есть полной перекомпиляцией модуля при каждой компиляции программы. Иначе падает из за того бага PByte(nil)^.

Кстати, залейте, пожалуйста билд. А то исправили, но в релиз всё ещё не попало.


Крутящийся треугольник 1 (простейший пример).rar (461,8 КБ)

(Размер 4 а не 6 мегабайт потому что с момента написания я ещё убрал возможность напрямую взаимодействовать с адресами подпрограмм)

rar не открывается 7-zip-ом. Залейте архив в нормальном формате

В смысле? 7z открывает всё, даже NSIS и даже .Net-овские .exe (правда это не очень полезно).
И с rar-ом он прекрасно дружит, только что проверил. Может у вас версия какая то древняя?

Ну, в любом случае, вот, лучше, исходники: OpenGL.zip (348,9 КБ)

1 лайк

У меня запускается и тут же закрывается

И даже из IDE никакую ошибку не выдаёт?

OpenGL.pas(20784) : Ошибка времени выполнения: Object reference not set to an instance of an object.

Я exe запускал

У вас устаревшие графические драйверы. Последняя версия OpenGL - 4.6 . Ну а прямо над строчкой на которой вам выдало ошибку - можно найти это:

    // added in gl4.5
    private z_CreateBuffers_adr := GetFuncAdr('glCreateBuffers');

Пишет: Крутящийся треугольник 1 (простейший пример).pas(24) : Ошибка времени выполнения: Файл ‘D:\W8\Rot Triangle 1.vertex.glsl’ не найден.

Ой, да, извиняюсь, забыл исходники шейдера упаковать:

OpenGL.zip (349,3 КБ)

Или отдельно:

Rot Triangle 1.vertex.glsl (259 Байты)

Вот такая ерунда выдаётся:

0(12) : error C7011: implicit cast from "int" to "float"
0(13) : error C7011: implicit cast from "int" to "float"
0(16) : error C7011: implicit cast from "int" to "float"

Vertex info
-----------
0(12) : error C7011: implicit cast from "int" to "float"
0(13) : error C7011: implicit cast from "int" to "float"
0(16) : error C7011: implicit cast from "int" to "float"
(0) : error C2003: incompatible options for link

INVALID_OPERATION
INVALID_OPERATION
INVALID_OPERATION

и далее это в бесконечном цикле

1 лайк

Кхм, похоже у вас более суровый компилятор шейдеров.

Ну, допустим эти ошибки (которые должны быть предупреждениями, вообще то) исправил:

Rot Triangle 1.vertex.glsl (268 Байты)

Теперь это

0(12) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
0(13) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
0(16) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120

Vertex info
-----------
0(12) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
0(13) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
0(16) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
(0) : error C2003: incompatible options for link

INVALID_OPERATION
INVALID_OPERATION
INVALID_OPERATION

Вообще, давайте наверное уберем OPENGL из поставки - до выяснения причин так сказать. Кстати, в поставке не работает единственный пример.

Кстати,

uses OpenGL;

var gl: OpenGL.gl;

begin
end.

вот это компилируется в 1 Мб.

Так не должно быть. Это происходит за счет вот этих инициализаций

private z_GetActiveUniform_ovr_26 := GetFuncOrNil&<procedure(&program: UInt32; index: UInt32; bufSize: Int32; length: IntPtr; size: IntPtr; &type: IntPtr; name: IntPtr)>(z_GetActiveUniform_adr);

которых 100000 штук и которые вытаскивают в конструктор по умолчанию (который обязательно генерируется) все вот эти инициализации - и весь модуль по-существу в exe.

И - предлагаю написать не модуль, а dll всё - таки, а то случае прилинковывать к каждому приложению вот это огромное количество структур - это абсолютно непрофессионально. Что про нас подумают?

Если модуль заменить на dll, то сразу 40 кб exe

У меня работает. Разобраться, конечно надо, что не так. Но то что не работает у вас - не повод выкидывать из релиза.


Вы как то потеряли моё сообщение при переносе (или оно не отправилось…):

У вас, почему то, более строгий компилятор шейдеров. Вместо предупреждений даёт ошибки. Ну, исправляется это легко:

Rot Triangle 1.vertex.glsl (268 Байты)

Это я понимаю. От 1МБ никуда не уйти.

Инициализации нужны из за архитектуры библиотеки OpenGL. Дело в том, что при инициализации контекста (в нём хранятся данные о том - на чём и как рисовать) - OpenGL выбирает на каком устройстве он инициализируется.

Если в пк стоят 2 совершенно разные видеокарты и каждая из них подключена к отдельному монитору - получается ситуация, где в зависимости от выбора экрана контекст будет иметь разную версию OpenGL и разный набор расширений.

Более того, OpenGL это только спецификация. Каждый производитель видеокарт по своему её реализует. А значит реализация подпрограмм 2 разных контекстов - будет находится в 2 разных участках памяти.

Поэтому, адреса подпрограмм нужно получать уже после инициализации контекста. Именно это и происходит на строчке gl := new OpenGL.gl;.


P.S. Вообще у меня есть 1 идея:

Можно добавить в PABCSystem атрибут, который можно будет применить к полям. Если этот атрибут применён - поле не добавляется в готовый .exe, пока оно не будет использовано кодом, использующим .pcu . Так же как сейчас с типами и методами. По названию - предлагаю UnnecessaryFieldAttribute.

Обычно поля нельзя выкидывать, потому что это сломает представление типа в памяти. Но если разрешать это атрибутом - можно будет избежать того мегабайта.

Моё предложение тогда - сделать dll. 2-3 Мб на каждую программу - это очень плохая цена. Кроме того, наш инсталлятор собирается секунд на 20 дольше из-за этого модуля.

Еще раз - dll вместо модуля нормально решает проблему. В NET только так всё и делается.

И собственно - это вы говорили, что размер .exe большой. Он большой по существу, потому что все ваши структуры используются.

Может, частичным решением было бы рассредоточить всё это по разным классам чтобы в приложении использовались бы только некоторые. Например, двухуровневая иерархия, при которой классы верхнего уровня в зависимости от решаемой задачи подключают только те или другие части.

Второй приём - вместо делегатов сделать свойства, которые инициализируются при первом обращении к ним. Тогда если не обращался в программе, то и класс этот не подшивается.

Вообщем, проблема с архитектурой есть, и ее надо решать.

3 Мб ради треугольника - это много.

Нет, мы не будем конечно же подобным заниматься

Это не вариант, потому что тогда готовые .exe не будут работать без установки паскаля.

“конечно”? Вы говорите так, будто интуитивно понятно что это ужасная идея. Можете объяснить?

Я знаю эту мотивировку. В мире NET так не делается. А Вы находитесь именно в мире .NET в данном случае. Здесь создаётся много сборок, и приложение распространяется вместе с этими сборками.

Обратите также внимание на полезность - вашим модулем будет пользоваться 0 человек. Мотивировка проста - код рисования треугольника - огромный по моим меркам, который у меня кстати так и не заработал - компилируется в 2 Мб.

Опросите, у кого ваш код работает, и сделайте выводы. Странно помещать неработающий код в инсталлят.

Еще раз - если вы будете настаивать на своей идее, - попробуйте реализовать двухуровневую архитектуру, о которой я говорил в своём посте. И запихните например все делегаты в свойства, которые будут инициализироваться при первом использовании.

Я постараюсь объяснить так чтобы не обидеть. Идея мягко сказать странная. Как и многие странные идеи, она возникла из ситуации "это мне надо для моего проекта, поэтому давайте поменяем компилятор). Такие идеи не принимаются “с порога”. Кроме того, эта идея нигде не реализована чтобы как-то можно было на нее ссылаться и как-то мотивировать.

1 лайк

Дело не в этом. Если таскать .dll вместе с .exe - размер бинарников становится ещё больше. 1МБ это только функции ядра, а в OpenGL большинство подпрограмм в расширениях. Поэтому создание .dll вообще никак не исправляет вопрос размера.

Это новый стиль OpenGL, а не моя идея. В OpenGL всё ещё можно рисовать в стиле OpenGL1.1, тогда код будет строчек на 10. Зато производительность…

Но я не собираюсь на всегда так оставлять. Весь смысле делать Open* и Open*ABC модули - как раз чтоб была возможность писать или особо короткие, или особо производительные программы.

Посмотрите примеры чистого OpenCL - они тоже огромные (хоть там всё и не так плохо). Соответствующие примеры на OpenCLABC значительно проще. А с OpenGL это будет ещё более заметно.

Ну так надо дальше разбираться. Я же говорю, у меня работает - значит, как минимум, говорить что код вообще не работает - неправильно.

Это никаким образом не поможет. Готовые адреса всё равно надо хранить. А проблема кол-ва инициализаций не в скорости (они все моментально инициализируются), а только в размере .exe, который только увеличится от доп проверок.

А откуда должны возникать не странные идеи? Идеи которые возникли из того, что никому никогда не понадобилось - вот этого надо опасаться.

Потому что эта идея касается лично вашей архитектуры.


Атрибуты идеально подходят в данном случае. Это никак не увеличит размер PABCSystem, потому что это всего 1 тип, и в .exe его без необходимости сувать не будет.

И использование такого атрибута не ограничено моими модулями. Это в целом атрибут для оптимизации любого кода.

1 лайк