Страницы

Поиск по вопросам

понедельник, 16 декабря 2019 г.

Баг текстуры в Opengl

#opengl


Когда я нахожусь по одну сторону от текстуры, она прозрачна и выглядит как нужно:



Но если я нахожусь с противоположной стороны от текстуры, с двумя ее сторонами что-то
не так:



Текстура на всех гранях одна и та же.

Код загрузки текстур:

GLuint Render::loadTexture(const sf::String & name)
{
    sf::Image image;

    if (!image.loadFromFile(name))
        return EXIT_FAILURE;

    image.flipVertically();

    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y,
GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    return texture;
}


Код отрисовки куба:

glTranslatef(x, y, z);


glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);   glVertex3f(-size, -size, -size);
glTexCoord2f(1, 0);   glVertex3f(size,  -size, -size);
glTexCoord2f(1, 1);   glVertex3f( size,  size, -size);
glTexCoord2f(0, 1);   glVertex3f( -size, size, -size);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(size, -size, size);
glTexCoord2f(1, 0); glVertex3f(-size,  -size, size);
glTexCoord2f(1, 1); glVertex3f( -size,  size, size);
glTexCoord2f(0, 1); glVertex3f( size, size, size);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-size, -size,  size);
glTexCoord2f(1, 0); glVertex3f(-size, -size, -size);
glTexCoord2f(1, 1); glVertex3f(-size,  size, -size);
glTexCoord2f(0, 1); glVertex3f(-size,  size,  size);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(size, -size, -size);
glTexCoord2f(1, 0); glVertex3f(size,  -size, size);
glTexCoord2f(1, 1); glVertex3f(size,  size,  size);
glTexCoord2f(0, 1); glVertex3f(size, size,  -size);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[4]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-size, -size,  size);
glTexCoord2f(1, 0); glVertex3f(size, -size, size);
glTexCoord2f(1, 1); glVertex3f( size, -size, -size);
glTexCoord2f(0, 1); glVertex3f( -size, -size,  -size);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[5]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(-size, size,  -size);
glTexCoord2f(1, 0); glVertex3f(size, size, -size);
glTexCoord2f(1, 1); glVertex3f( size, size, size);
glTexCoord2f(0, 1); glVertex3f( -size, size,  size);
glEnd();


glTranslatef(-x, -y, -z);

    


Ответы

Ответ 1



Проблемы в обоих случаях - скрытые грани куба рисуются некорректно. Проверьте, что у Вас выставлен GL_ALPHA_TEST. https://stackoverflow.com/questions/9353210/rendering-glitch-with-gl-depth-test-and-transparent-textures Кроме того, если альфа не дискретна 0/1, попробуйте такой подход: Порядок наложения текстур влияет на работу alpha-канала. Как это обойти?

Offset (смещение) для растра

#cpp #алгоритм #opencv


Для произвольной фигуры, представляющей из себя просто вектор с точками, имеется
возможность производить смещение. Уменьшать, либо увеличивать без строгого соответствия
начальной форме.

Для демонстрации привожу небольшой пример:



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

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

Да, при помощи методов, имеющихся в OpenCV (да и даже если просто свой цикл реализовать),
можно получить векторы пограничных пикселей маски, а затем использовать для смещения,
но хотелось бы избежать лишней конвертации. То есть выполнить смещение сразу на растре.

Навскидку приходят в голову операции дилатации и эрозии, но у них имеется недостаток,
заключающийся в том, что если брать большое ядро для выполнения морфологической операции,
то получим усиленную "квадратизацию" модифицированного полигона. Иными словами ровненькие
линии, такие как в примере не получатся. Если же брать маленький размер ядра, но взять
больше итераций, то это работает достаточно медленно, причём чем больше дельта (разница
между исходником и результатом), тем больше потребуется итераций и тем дольше будет
выполняться алгоритм. Часто такая скорость совершенно неприемлема.

Каким ещё способом, кроме обозначенных морфологических операций возможно решить данную
задачу?
    


Ответы

Ответ 1



Думаю, вас может заинтересовать статья CPU vs GPU. Distance field на Хабрахабре. Там с помощью ядра получают Чем больше ядро, тем меньше угловатость и тем меньше скорость. Реализации на CPU и GPU прилагаются: Distance Field Samples.

Как задать шаблон для имен веток, вроде topic/myfeature или bugfixes/myfeature?

#git #git_branch #git_flow #source_tree


Добрый день, сейчас я работаю с git репозиторием, на котором ветки организованы в
папки: фичи в папке topic/myfeature, багфиксы в папке bugfixes/myfeature.

Собственно вопрос такой, могу ли я сконфигурировать дефолтное имя вообще всех новых
веток которые я создаю, используя сам git или инструментарий sourcetree? То есть я
хочу чтобы когда я нажимаю "создать новую ветку" мне предлагалось автоматически создать
ветку с названием topic/*.

То есть мне нужно предустановленное название ветки которую я создаю. Самой ветки,
имя репозитория к этому отношения не имеет.
    


Ответы

Ответ 1



То, что вы описываете - это расширение git-flow, вводящее высокоуровневые операции для управления потоком разработки. Судя по именованию - большинство разработчиков в вашей комманде использут/использовали именно его. SourceTree умеет работать с этим расширением. По нажатию на кнопку "Git Flow" на тулбаре открывается диалог инициализации Git Flow: В нем вы можете указать названия веток для разработки и продашена, для фич, релизов, хотфиксов, ну и префиксы для тегов версий. После инициализации, по нажатию на кнопку Git Flow будет показыватся диалог операций, позволяющий начинать и завершать работу над фичами, релизами, хотфиксами и т.д:

Ответ 2



git remote -v # View existing remotes # origin https://github.com/OWNER/REPOSITORY.git (fetch) # origin https://github.com/OWNER/REPOSITORY.git (push) git remote rename origin topic # Change remote name from 'origin' to 'topic' git remote -v # Verify remote's new name # topic https://github.com/FORKER/REPOSITORY.git (fetch) # topic https://github.com/FORKER/REPOSITORY.git (push) локальный конфиг хранится тут, если что vim .git/config

Собственная глобальная переменная потока

#c #unix #многопоточность


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

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


Ответы

Ответ 1



@margosh, немного почитал маны и вот что получилось (интересующую Вас переменную обозвал lib_errno, при создании (первое обращение к ней) в каждом потоке она обнуляется): avp@avp-ubu1:hashcode$ more ptlib.h ptlib.c c.c | cat :::::::::::::: ptlib.h :::::::::::::: #ifndef _PTLIB_H #define _PTLIB_H #ifdef __cplusplus extern "C" { #endif pid_t gettid(void); int *lib_errno_func(void); #ifdef __cplusplus } #endif #define lib_errno (*lib_errno_func()) #endif :::::::::::::: ptlib.c :::::::::::::: #include #include #include #include #include #include #include "ptlib.h" pid_t gettid() { return syscall(SYS_gettid); } static pthread_once_t key_is_initialized = PTHREAD_ONCE_INIT; static pthread_key_t key; static void destruct_thread_value (void *ptr) { printf("destruct: %ld %p value %d\n", (long)gettid(), ptr, ptr ? *((int *)ptr) : 0); free(ptr); } static void make_key () { printf("make_key: %ld\n", (long)gettid()); pthread_key_create(&key, destruct_thread_value); } int * lib_errno_func () { int *ptr; pthread_once(&key_is_initialized, make_key); if (!(ptr = (typeof(ptr))pthread_getspecific(key))) { ptr = (typeof(ptr))calloc(sizeof(int), 1); printf("construct: %ld %p\n", (long)gettid(), ptr); pthread_setspecific(key, ptr); } return ptr; } :::::::::::::: c.c :::::::::::::: #include #include #include #include #include "ptlib.h" void * tfunc (void *a) { usleep(rand() % 100000); printf("thread-run: tid=%ld a=%d lib_errno=%d\n", (long)gettid(), *((int *)a), lib_errno); lib_errno = *((int *)a) + 100; usleep(rand() % 100000); printf("thread-fin: tid=%ld a=%d lib_errno=%d\n", (long)gettid(), *((int *)a), lib_errno); return 0; } int main (int ac, char *av[]) { int n = atoi(av[1] ? av[1] : "3"); if (n < 1) n = 3; pthread_t tid[n]; printf("main-run: tid=%ld lib_errno=%d\n", (long)gettid(), lib_errno); int i; for (i = 0; i < n; i++) { int *pv = (int *)malloc(sizeof(int)); *pv = i; pthread_create(tid + i, 0, tfunc, pv); } for (i = 0; i < n; i++) pthread_join(tid[i], 0); printf("main-fin: tid=%ld lib_errno=%d\n", (long)gettid(), lib_errno); return puts("End") == EOF; } avp@avp-ubu1:hashcode$ gcc -pthread -O2 -c ptlib.c -Wall avp@avp-ubu1:hashcode$ g++ -pthread c.c ptlib.o avp@avp-ubu1:hashcode$ ./a.out make_key: 5556 construct: 5556 0x8ca010 main-run: tid=5556 lib_errno=0 construct: 5558 0x7f22c40008c0 thread-run: tid=5558 a=1 lib_errno=0 thread-fin: tid=5558 a=1 lib_errno=101 destruct: 5558 0x7f22c40008c0 value 101 construct: 5557 0x7f22c40008c0 thread-run: tid=5557 a=0 lib_errno=0 construct: 5559 0x7f22bc0008c0 thread-run: tid=5559 a=2 lib_errno=0 thread-fin: tid=5559 a=2 lib_errno=102 destruct: 5559 0x7f22bc0008c0 value 102 thread-fin: tid=5557 a=0 lib_errno=100 destruct: 5557 0x7f22c40008c0 value 100 main-fin: tid=5556 lib_errno=0 End avp@avp-ubu1:hashcode$ avp@avp-ubu1:hashcode$ На первый взгляд, вроде работает...

Ответ 2



Во-первых, уже давно практически все компиляторы предоставляют собственные средства для создания thread local переменных. В MSVC это declspec(thread), в GCC - __thread. Во-вторых, начиная с С11 в языке появился стандартный спецификатор _Thread_local, объявляющий thread local переменные. В любом случае, можно просто подсмотреть, что сделано на вашей платформе с errno и повторить то же самое.

Как просматривать исходники в Sublime Text?

#python #sublime_text #pycharm


В пайчарме есть отличная фича "go to declaration", название которой само говорит
за себя. В Sublime Text есть похожая штука "go to definition" но она, к сожалению,
только жалкая пародия пайчармовской, потому что в пайчарме можно перейти к объявлению
любой функции, класса..., что нельзя с делать в Sublime Text. Вопрос: как вы быстро
передвигаетесь по коду и не только своего кода? Может есть плагины в Sublime Text или
специальные программы?
    


Ответы

Ответ 1



Попробуйте дополнение для sublime anaconda - в нём есть собственная реализация goto defenition - гораздо лучше встроенной

Ввод знака ударения и других интересных символов в Ubuntu

#ubuntu #faq #xcompose


Как в Ubuntu наименее трудозатратным способом вводить символы, которых нет на клавиатуре?

Можно назначить клавишу Compose, онa же Multi_key.
Она дает всякие тире —,–, кавычки-елочки «», знак ударения ý и другие классные символы ☭,☺!
Например, Multi_key - - - печатает "—".
Но эти символы не всегда дружат с русской клавиатурой.   

Файл /usr/share/X11/locale/en_US.UTF-8/Compose содержит определения для клавиши Compose.
Гугл говорит, что можно добавить свои определения в ~/.XCompose. Команда xev | fgrep
"keysym" показывает названия клавиш в системе.

И вот я написала много интересных определений в ~/.XCompose, но они не заработали
даже после перезагрузки.
Тогда я скопировала их в /usr/share/X11/locale/en_US.UTF-8/Compose, но и это не помогло.  

И вот что получается: то, что было определено для русской раскладки в /usr/share/X11/locale/en_US.UTF-8/Compose,
например

    : "§"   section # SECTION SIGN  


работает, то есть Compose-п-а печатает "§",
а те определения, что я добавила, типа

   : "«" guillemotleft # левая кавычка-ёлочка    
     : "а́" # CYRILLIC SMALL LETTER a WITH COMBINING
ACUTE ACCENT


не работают!
(Почему-то в Firefoxе знак ударения сдвинулся вправо, но на моем компьютере он на
месте).  


В данный момент меня беспокоят следующие символы:


Кавычки-елочки.
Multi_key < < дает нам "«", а Multi_key > > — "»".
С русской клавиатуры ввести это невозможно, потому что нет знаков "<" и ">".
То есть чтобы ввести кавычки, которые используются в русском, нужно переключиться
на английскую раскладку, нажать на клавиши, а потом переключится обратно.
Ударение в русской раскладке получается совсем криво. С Compose не работает, но можно
использовать Unicode:  


переключиться на английский;
после буквы, на которую нужно поставить ударение, нажать одновременно Ctrl-Shift-u.
Появится подчеркнутая буква u.
ввести "301". Это Unicode знака dead_acute — ударения, которое не сдвигает каретку.
Ввод. Появляется ударение над буквой.
поменять язык обратно на русский.  



Что я делаю не так с Compose?
Есть ли еще способы добавить символы? Мне нужно, чтобы легко запоминалось и быстро
нажималось.
    


Ответы

Ответ 1



попробуйте добавить в конец файла ~/.profile строку: export GTK_IM_MODULE="xim" и перзапустите сеанс. после этого в программах, использующих gtk (например, firefox), должно заработать то, что написано в вашем ~/.XCompose. обновление хотя, вероятно, более «правильно-дистрибутивный» метод — это запустить программу im-config (если у неё есть возможность, она «нарисует» gui-окно, иначе — текстовое меню), где дойти до выбора вариантов конфигурации input methods и выбрать xim (этот пункт ближе к концу). после чего, опять-таки, надо перезапустить сеанс.

Ответ 2



Этот ответ содержит обновленную информацию для Ubuntu 18.04 и упорядоченные инструкции (на случай. что мне придется делать это еще раз, и я опять все забуду). Определяем клавишу Compose. Прежде всего, нам надо проверить, определена ли клавиша Compose, и если да. то где. Нажимаем на значок переключения языка, затем Показать раскладку клавиатуры. Если клавиши Compose нету, то его можно установить с помощью пакета gnome tweaks. (См.) (Раньше это делалось через Параметры → Клавиатура). Устанавливаем: sudo apt install gnome-tweaks или sudo apt install gnome-tweak-tool Либо в Менеджер приложений Ubuntu устанавливаем Доп. настройки gnome (можно написать в поисковой строке gnome tweaks и он найдет). Запускаем. Открываем Клавиатура и мышь Нажимаем на кнопку Композиционная клавиша и выбираем, на какую клавишу ее назначить. Ставим английскую раскладку и проверяем, что клавиша Compose работает. Например, Compose - - - должно напечатать длинное тире: —. Создаем свои комбинации клавиш. Свои комбинации определяются в файле ~/.XCompose. Как сообщает нам man XCompose, мы можем включать в него другие файлы определений командой include. В общем случае лучше всего включить системный файл своей локали: include "%L" Но в нашем случае /usr/share/X11/locale/ru_RU.UTF-8/Compose содержит только одну строчку include "/usr/share/X11/locale/en_US.UTF-8/Compose" Примечание. Все это сделано плохо. Английский файл содержит определения для кириллических гласных с ударением, вроде : "А́" но пользоваться ими в русской раскладке невозможно, потому что клавиша в русской раскладке превращается в , она же "э". (В Гугле сказали, что из более 50-ти кириллических языков апостроф существует только в украинском и белорусском.) Там также есть определение для печати символа "№" с помощью , но в русской раскладке он и так есть. Хорошо бы сделать минимальный /usr/share/X11/locale/ru_RU.UTF-8/Compose с ударениями над гласными и со всеми русскими кавычками и распространять его вместе с Ubuntu, но я не знаю, как. Теперь давайте добавим в ~/.XCompose свои определения. Для этого нам нужно узнать названия клавиш в раскладке. Запускаем команду xev | fgrep "keysym". Открывается окошечко. Печатаем туда символы, а в терминале нам показывают их названия. Например, мы хотим добавить в русскую раскладку квадратные скобки, чтоб было удобнее редактировать свои тексты на stackoverflow. Нажимаем на клавишу [ в окошке xev. В терминале, откуда был запущен xev, нам сообщают: keysym 0x5b, bracketleft. То есть эта клавиша называется bracketleft и заодно мы узнали ее юникод U005B. Выставляем русскую раскладку, печатаем то же самое. Теперь клавиша называется Cyrillic_ha. Добавляем в ~/.XCompose строчку : "[" U005B # левая квадратная скобка Таким же образом добавляем : "]" U005D # правая квадратная скобка : "`" U0027 # апостр́оф (на Multi_key+Ё+!) Мы можем также скопировать готовый .XCompose, например, отсюда или отсюда. Они содержат гигантское количество определений комбинаций клавиш. После изменения .XCompose перезапустите сеанс, чтобы увидеть результаты. Добавлять в ~/.profile строку export GTK_IM_MODULE="xim" больше не нужно. Еще полезность: В man Compose написано, что вместо файла ~/.XCompose можно использовать любой другой файл, и сообщить о нем системе с помощью переменной $XCOMPOSEFILE. Как это может пригодиться? Например, у одного пользователя есть классный ~/.XCompose. Другой пользователь может использовать его, если вставит в свой ~/.profile строку export XCOMPOSEFILE="$HOME/..//.XCompose" Так у вас есть только одна копия .XCompose, которую используют несколько пользователей. И про сдвиг ударения. Оказывается, в нем виноват шрифт Verdana, см. Хабр.

Действие перед тем как изменить размер окна

#c_sharp #wpf #события


Здравствуйте, как словить событие изменения размера окна? Я имею ввиду что бы в окне
происходили определённые действия перед тем, как WindowState станет Maximized, вне
зависимости от того, каким образом WindowState станет Maximized.
    


Ответы

Ответ 1



private const int WM_SYSCOMMAND = 0x0112; private const int SC_MINIMIZE = 0xF020; public MainWindow() { InitializeComponent(); } [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case WM_SYSCOMMAND: int command = wParam.ToInt32() & 0xfff0; if (command == SC_MINIMIZE) { //before min } else { //before max } break; } return IntPtr.Zero; } private void Window_SourceInitialized(object sender, EventArgs e) { IntPtr windowHandle = (new WindowInteropHelper(this)).Handle; HwndSource src = HwndSource.FromHwnd(windowHandle); src.AddHook(new HwndSourceHook(WndProc)); } код внутри SourceInitialized лучше исполнять именно внутри этого события или любого другого, когда окно уже про инициализировано ибо (new WindowInteropHelper(this)).Handle будет выдывать 0 пока оно не инициализируется

Ответ 2



private const int WM_SYSCOMMAND = 0x0112; private const int SC_MINIMIZE = 0xF020; private void music_SourceInitialized(object sender, EventArgs e) { IntPtr windowHandle = (new WindowInteropHelper(this)).Handle; HwndSource src = HwndSource.FromHwnd(windowHandle); src.AddHook(new HwndSourceHook(WndProc)); } [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case WM_SYSCOMMAND: int command = wParam.ToInt32() & 0xfff0; if (command == SC_MINIMIZE) { } else { border_main.CornerRadius = new CornerRadius(0); border_bottom.CornerRadius = new CornerRadius(0); ResizeMode = ResizeMode.NoResize; WindowState = WindowState.Maximized; } break; } return IntPtr.Zero; }