- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
void load_functions(void** functions[], const char* names[], ushort count)
{
for(ushort i=0; i<count; i++)
*functions[i]=wglGetProcAddress(names[i]);
}
...
void* const glslFunctions[]={&glCreateShader, &glShaderSource, &glCompileShader,
&glGetShaderiv, &glGetShaderInfoLog, &glDeleteShader,
&glCreateProgram, &glAttachShader, &glLinkProgram, &glGetProgramiv,
&glGetProgramInfoLog, &glUseProgram, &glDeleteProgram,
&glGetUniformLocation, &glGetActiveUniform, &glBindAttribLocation,
&glGenProgramPipelines, &glBindProgramPipeline, &glDeleteProgramPipelines, &glUseProgramStages,
&glProgramParameteri, &glGetProgramPipelineiv, &glValidateProgramPipeline, &glGetProgramPipelineInfoLog,
&glProgramUniform1i, &glProgramUniform2iv, &glProgramUniform3iv, &glProgramUniform4iv,
&glProgramUniform1ui, &glProgramUniform2uiv, &glProgramUniform3uiv, &glProgramUniform4uiv,
&glProgramUniform1f, &glProgramUniform2fv, &glProgramUniform3fv, &glProgramUniform4fv,
&glProgramUniform1d, &glProgramUniform2dv, &glProgramUniform3dv, &glProgramUniform4dv,
&glProgramUniformMatrix2fv, &glProgramUniformMatrix3fv, &glProgramUniformMatrix4fv,
&glProgramUniformMatrix2x3fv, &glProgramUniformMatrix2x4fv,
&glProgramUniformMatrix3x2fv, &glProgramUniformMatrix3x4fv,
&glProgramUniformMatrix4x2fv, &glProgramUniformMatrix4x3fv,
&glProgramUniformMatrix2dv, &glProgramUniformMatrix3dv, &glProgramUniformMatrix4dv,
&glProgramUniformMatrix2x3dv, &glProgramUniformMatrix2x4dv,
&glProgramUniformMatrix3x2dv, &glProgramUniformMatrix3x4dv,
&glProgramUniformMatrix4x2dv, &glProgramUniformMatrix4x3dv};
const char* glslFuncNames[sizeof(glslFunctions)/sizeof(glslFunctions[0])]=
{"glCreateShader", "glShaderSource", "glCompileShader",
"glGetShaderiv", "glGetShaderInfoLog", "glDeleteShader",
"glCreateProgram", "glAttachShader", "glLinkProgram", "glGetProgramiv",
"glGetProgramInfoLog", "glUseProgram", "glDeleteProgram",
"glGetUniformLocation", "glGetActiveUniform", "glBindAttribLocation",
"glGenProgramPipelines", "glBindProgramPipeline", "glDeleteProgramPipelines", "glUseProgramStages",
"glProgramParameteri", "glGetProgramPipelineiv", "glValidateProgramPipeline", "glGetProgramPipelineInfoLog",
"glProgramUniform1i", "glProgramUniform2iv", "glProgramUniform3iv", "glProgramUniform4iv",
"glProgramUniform1ui", "glProgramUniform2uiv", "glProgramUniform3uiv", "glProgramUniform4uiv",
"glProgramUniform1f", "glProgramUniform2fv", "glProgramUniform3fv", "glProgramUniform4fv",
"glProgramUniform1d", "glProgramUniform2dv", "glProgramUniform3dv", "glProgramUniform4dv",
"glProgramUniformMatrix2fv", "glProgramUniformMatrix3fv", "glProgramUniformMatrix4fv",
"glProgramUniformMatrix2x3fv", "glProgramUniformMatrix2x4fv",
"glProgramUniformMatrix3x2fv", "glProgramUniformMatrix3x4fv",
"glProgramUniformMatrix4x2fv", "glProgramUniformMatrix4x3fv",
"glProgramUniformMatrix2dv", "glProgramUniformMatrix3dv", "glProgramUniformMatrix4dv",
"glProgramUniformMatrix2x3dv", "glProgramUniformMatrix2x4dv",
"glProgramUniformMatrix3x2dv", "glProgramUniformMatrix3x4dv",
"glProgramUniformMatrix4x2dv", "glProgramUniformMatrix4x3dv"};
load_functions((void***)glslFunctions, glslFuncNames, sizeof(glslFunctions)/sizeof(glslFunctions[0]));
...
> load_functions (...,sizeof(...));
?
P.S. Смотри, он будет рисовать картину...уже расширил ОпэнЖоЭль.
2) Это не даст никакой экономии памяти.
3) Может не хватить диапазона (в данном конкретном случае хватит, я согласен).
Поэтому short'ы вне массивов и структур не имеют особого смысла...
А я думал, что одинаково. 16-битные регистры же есть: ax, bx, cx, dx. Почему же они медленнее? А что насчёт 64-разрядных процессоров? Сейчас же уже все процессоры 64-разрядные, но многие программы 32-битные. 32-битные операции тоже медленные?
Во вторых 16битные mov и ему подобные вносят ненужную зависимость от старого содержимого старших бит, что мешает процу распараллеливать операции.
Ну а вообще да, в основном будут с такой же скоростью работать. Вот только быстрее чем 32хбитные - никак.
> void load_functions(void** functions[], const char* names[], ushort count)
Ну неужели двойная звёздочка, да ещё и с [] (хорошо хоть что не тройная) не смущает автора? Или он привычен? Я вот секунд 15 вдуплял, что там на что там на что там на что там указывает.
Ну я конечно хотел как-нибудь её убрать, но не придумал как. У меня такая функция единственная во всём движке. Но вроде всё понятно: массив указателей на указатели на функции.
>Я вот секунд 15 вдуплял, что там на что там на что там на что там указывает.
Вот и отлично. Чтобы понять мой механизм загрузки расширений нужно всего лишь каких-то 15 секунд.
Посмотри на код ниже. Он успешно передаёт размер контейнера сам и не требует передавать его отдельно.
fixed
Получилось бы более обобщённо. А Ада так может?
template<template<class > class Container>
void load_functions(const Container<FunctionInfo> &functions)
Это совершенно не будет работать.
Для тогоже std::vector придется написать
А для std::set:
Для какого-то своего контейнера с каким то другим числом параметров. А потом стандарт поменяют и старый код перестанет компилироваться. Бесполезно всё это... Убогие кресты не могут в обобщенное программирование.
template <template ...> нужен только тогда, когда код внутри шаблона собирается инстанциировать шаблонный класс несколько раз и по-разному
если ожидать Container<FunctionInfo> (т.е. тебе нужна только 1 версия), то и ожидай уже полностью инстанциированный тип:
Опасно это. По тихому преобразоваться тип может. Например, foo - указатель, а Container - контейнер boolов. К тому же некоторые питушки иногда создают свои операторы приведения типов. Вообщем не вариант с точки зрения обобщения. Нужна надежная проверка типа в месте использования функции.
Да и вообще показывать на ошибку вызова функции не в месте вызова функции, а в глубине библиотеки после цепочки вызова шаблонных функций - моветон.
ну а про ошибку в месте вызова функции - притянуто за уши
писать template <template ...> ради кода выше - говнокод, как раз именно потому, что лишняя работа, которая серьезно сужает применимость
____________________
Отредактировал пост:
ЗЫ: А вы про Аду... Ок
тут написано, что генерик использует параметр P1 как другой генерик с известным уже именем Q, и задает ему либо все параметры, либо использует все по умолчанию
т.е. это примерно как использовать std::vector<mytype, std::allocator<mytype> >, а не Container<mytype>
вот такой код на Аде можно написать?
Тарас молчит, а значит его тоже гложут сомнения.
я эту фичу не пользовал, что умеют пакеты в параметрах шаблона - не знаю.
Если что, можно тупо так:
dosmth<std::vector<int>, std::vector<double>>();
хотя бы в вот такой паттерн ада может?
(это один из обходов ситуации с template <template ...>)
http://ideone.com/Pxlpt
>St3setIiSt4lessIiESaIiEE
can not into деманглинг, братюнь?
в студии тот же код выводит сразу нормально
интернет подсказывает, что в гцц есть abi::__cxa_demangle - лишние телодвижения
Именно.
в студии, где инстанциирование шаблона не 2х этапное, как требует стандарт, как раз template внутри можно не писать
И ещё я вспомнил, почему я решил сам загружать расширения: я пытаюсь загружать сначала функционал ядра, но если он не поддерживается, то загружаю аналогичное расширение на место тех же функций для совместимости. А в библиотеках типа glew они загружаются отдельно.
Да и просто так, выложил, потому что нигде подобного не видел. Везде загружают функции по одной с кастами.
чтобы она в конструкторе сама дергала wglGetProcAddress() (если, конечно, его можно вызывать до вызова main())
FIX: макрос вместо функции, т.к. надо имя функции передавать в wglGetProcAddress.
А пример можете?
WARNING. Я не помню, можно ли вызывать wglGetProcAddress до main(), и какие инициализации надо провести перед его вызовом. Поэтому этот код лучше не юзать в продакшене.
P.S. Зато тут не нужны кодогенераторы, функция описывается 1 раз в одной точке...
Нельзя. Тем более, что ещё нужно сначала инициализировать контекст OpenGL. Без него будет всегда возвращаться нулевой указатель.
Вот такой вот говнокодик, поддерживающий отложенную загрузку. Вам скорее всего не подойдет из-за буста и требуемых особенностей загрузки... Но пусть лежит тут как proof-of-concept ;)
P.S. Торопился, поэтому смотрится как говно.
Эх, ладно, ни к чему все это...
Лол. std::function давно уже в стандарте. Его и используй.
А как вы обходитесь без лямбд с замыканиями, без каррирования и объектов первого класса? Это же так способствует надежности, декларативности и обобщенности.
Так что я выкладываю свои последние говнокоды в разделе C++...
Для Higher Order Functions это нужно.
Помешать отсутствие виртуального деструктора может разве что так: кастануть объект в boost::function<T*>*, а потом сделать ему delete, но зачем...
Для этого можно написать обертку над wglGetProcAddress, которая будет инициализировать GL при первом вызове, если она ещё не инициализирована.
Внешний скрипт коллектор-кодогенератор перед компиляцией?
Там почти весь исходник сгенерен из спецификаций расширений OpenGL.
Интересен уже общий случай с подобной инициализацией.
Пых или питон же
#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmap EXT)
Я не понимаю, зачем это сделали? Для ленивой инициализации что ли? А IDE даже подсказок не отображает.
А так сойдет?
Но, как говориться: хозяин - барин.
> C# будет импортировать эти функции.
И ты, после упоминания C#, пытаешься упоминать, что заботишься о размере файлов?
Пхпешник и экономия на спичках
про зажигалку?
Это я к чему - а к тому, что размер исполняемого файла важен только для игрушек уровня сапера, в которых ресурсов раз два и обчелся. И если эти ресурсы, которые кстати плохо жмутся, в отличие от экзешника, весят около 30 метров, то всем пофиг на дополнительный метр, на которые может вырасти исполняемый файл пожатый инсталлятором...
Да и не ставил я особенно цель уложиться в 96 КБ. Просто стремлюсь сделать игру как можно меньше, особенно не жертвуя удобством разработки.
Это только тебе так кажется.
>>А малый процент XP'шников и линуксоидов скачают его(или Mono), если у них нет.
>>ко-ко-ко
Скачают. Ага. Иди-ка ты нахуй.
Вот сраная джаба есть везде, это да.
Больше половины пользователей пересели на семёрку. У многих XP'шников, даже мало разбирающихся в компьютерах, я видел установленный .NET Framework 2.0. А когда я допишу, XP'шников ещё меньше останется.
>Скачают. Ага.
Зато кроссплатформенно. У меня шарповые экзешники даже на телефоне через Mono запускаются без перекомпиляции.
Еще как!
http://govnokod.ru/10050
А так как даже на андроидах уже многие игры занимают по 500 МБ, то Mono за 100 МБ не так уж сложно скачать.
Но в спойлере написал про убогую джабу.
http://govnokod.ru/11487#comment149085
Но даже на ней иногда бывают серъезные траблы с "кроссплатформенностью".
По крайней мере в сане старались.
Первая сцылка в гугли
http://en.wikipedia.org/wiki/Usage_share_of_operating_systems
И это еще самый благоприятный прогноз, обычно XP оценивают около 40%.
Так что нахуй.
А это тебе чем не понравилось то? Все же меньше вероятность ошибки.
Да это:
Почему бы это не применить?
Это конечно можно и использовать, но load_functions я вызываю достаточно редко, чтобы обойтись. А я предпочитаю не использовать шаблоны, когда они не очень нужны.