#HEX • IT – Telegram
#HEX • IT
372 subscribers
502 photos
104 videos
64 files
478 links
Channel by @alexeev_dev.

Авторский блог.

IT, статьи и другая информация.
Download Telegram
OpenGL — хоть и старая, но простая библиотека для работы с графикой. Если вы хотите начать путь в графику, то советую начинать с него, а после перейти к Vulkan (т.к. Vulkan требует больше знаний матчасти и low-level вещей). Сегодня я расскажу, как создать простое окно с OpenGL.

#include <GL/glew.h>
#include <GLFW/glfw3.h>

Сначала подключаем библиотеки. GLEW — это инструмент для управления расширениями OpenGL, а GLFW поможет нам работать с окнами и контекстом OpenGL.

int main() {
glfwInit();

В этой строке инициализируем GLFW, готовя его к работе.

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

Здесь задаем параметры окна. Указываем, что будем использовать OpenGL версии 3.3 с Core Profile — это позволит избежать использования устаревших функций.

    GLFWwindow* window = glfwCreateWindow(800, 600, "My OpenGL Window", nullptr, nullptr);

Создаём само окно, задавая ему размеры (800 на 600 пикселей) и название. Последние два параметра отвечают за контекст и монитор. Поскольку они нам не нужны, оставляем их nullptr.

    if (!window) {
glfwTerminate();
return -1;
}

Проверяем, удалось ли создать окно. Если нет — завершаем программу и возвращаем -1, чтобы сигнализировать об ошибке.

    glfwMakeContextCurrent(window);

Делаем созданное окно текущим контекстом, чтобы все вызовы OpenGL работали именно в этом окне.

    glewInit();

Выше инициализрован GLEW — теперь мы можем использовать функционал OpenGL.

Теперь переходим к главному циклу обработки событий и рендеринга:

    while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);

Запускаем бесконечный цикл, который будет работать до тех пор, пока окно открыто. Внутри цикла очищаем цветовой буфер, чтобы каждый кадр рисовался «с чистого листа».

        glfwSwapBuffers(window);
glfwPollEvents();
}

Здесь меняем буферы (рисуем на экран) и обрабатываем события (например, нажатия клавиш или закрытие окна). Это нужно, чтобы приложение взаимодействовало с пользователем.

    glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

По окончании работы цикла уничтожаем созданное окно и завершаем GLFW, освобождая все использованные ресурсы.
👍31
С 20 летием Half Life 2!

http://www.youtube.com/watch?v=YCjNT9qGjh4

Время? Доктор Фримен? Неужели опять пришло то самое время. Кажется что вы только прибили. Вы сделали очень много за короткое время. Собственно вы настолько хороши что я получил несколько интересных предложений на ваш счёт, в обычной ситуации я не стал бы их рассматривать, но ведь ситуация весьма необычная...
👍21
Знаете, друзья, а жизнь прекрасна.

Вы все сможете. Даже самая темная ночь сменяется рассветом. fall down seven times, stand up eights.

Можете в комментариях высказаться или попросить поддержку.

Вы уже превзошли большую часть населения, так что сможете превзойти и оставшуюся!
6👏1
Новогодний сбор

Хотите поздравить админа, или деньги некуда девать? Есть решение! Любому донату буду рад.

Взамен, буду делать интересные посты

2202206259210065 СБЕРБАНК
👍3
LearnVulkan Tutorial на русском

Очень интересная серия статей на Хабре, автор пишет:

Автор: связи с тем, что у меня не так много времени для ресерча каких-то новых штук и написания статей о них, я решил перевести серию уроков по Vulkan. Надеюсь, что мои переводы будут кому-то полезны и не очень плохого качества. Для начала обучения — прошу под кат.


Автор оригинала дал свое согласие на перевод. Также, когда я доперевожу все статьи и у меня будет время отформатировать их для github, он добавит русский перевод на свой сайт.



Структура гайдов:

Часть 1. Вступление

Общее вступление
Краткий обзор
Настройка окружения

Часть 2. Первый треугольник

Базовая структура
Hello window
Базовый графический пайплайн
Отрисовка
Создание своего Swap Chain

Часть 3. Vertex buffer


Введение
Создание Vertex Buffer
Staging Buffer (промежуточный буфер)
Index Buffer

Часть 4. Uniform Buffer


Layout и Buffer
Pool и Set

Часть 5. Текстуры


Загрузка изображений
Image View и Image Sampler
Комбинирование Image Sampler

Часть 6. Буфер глубины
Часть 7. 3D Модели
Часть 8. Mipmaps
Часть 9. Multisampling



💠 Статья
👍2
Чем отличается Vulkan от OpenGL?

Vulkan - это новый API для аппаратно-ускоренной графики (и общих вычислений) с использованием традиционных графических процессоров. OpenGL будет продолжать развиваться, поскольку это API более высокого уровня, чем предполагается для Vulkan. Первоначально упоминавшийся как "glNext", можно сделать вывод, что Vulkan, вероятно, в конечном итоге станет "OpenGL 5", но в конечном итоге орган по стандартизации решил, что новое название будет лучше соответствовать относительно чистому отличию API от существующих парадигм OpenGL.

Практические преимущества Vulkan для разработчиков игр заключаются в первую очередь в контроле (например, в том, что он позволяет использовать больше ИТ, потенциально позволяя улучшить оптимизацию за счет значительно большего объема предварительной работы со стороны разработчика). Конкретно:

API ориентирован на асинхронную генерацию командных буферов в нескольких потоках и последовательную обработку этих буферов в командном конвейере. Это отражает реалии современного оборудования. Большинство высококлассных и / или высокопроизводительных программ, созданных на OpenGL, сегодня реализуют подобное поведение самостоятельно; наличие поддержки API само по себе означает, что разработчикам не нужно внедрять и поддерживать этот фреймворк самостоятельно, или что они могут делать это с меньшими усилиями.
Задачи управления потоками и памятью возложены на приложение, а не на драйвер, что позволяет разработчикам игр лучше контролировать это поведение и, следовательно, потенциально более точно адаптировать это поведение к потребностям их индивидуальной игры.
Уровни проверки и диагностики могут быть включены независимо, что теоретически позволяет улучшить интеграцию инструментов с API (от чего страдает сам OpenGL) и отключить чрезмерную проверку, теоретически позволяя "графике третьего уровня" быть намного более производительной.
Нет жесткой разницы в API между мобильной и десктопной версиями, что теоретически облегчит перенос кроссплатформенных игр и, по крайней мере, уменьшит головную боль при проверке версий, которую все ненавидят.
Vulkan очень похож на C / OpenGL по внешней структуре (внешний вид вызовов API и так далее. Однако он лучше типизирован (в том смысле, что не все является голым int; есть соответствующие определения типов и так далее).

Он намного более низкого уровня, чем OpenGL. Можно ожидать скачка в операционных настройках и сложности между OpenGL и Vulkan, как это было замечено при переходе с D3D9 на D3D10, который предоставил клиенту API гораздо больше скрытых деталей работы устройства GPU. Переход на самом деле больше похож на D3D11 - 12, поскольку D3D12 сам по себе является API, очень похожим на Vulkan, с точки зрения возможностей.

💠 Источник

Если вы хотите изучать графическое программирование, советую начать с OpenGL, и после перейти на Vulkan. Vulkan требует больше знаний архитектуры компьютера и устройства графики.
👍3
ThinkPad — линейка ноутбуков, разработанная корпорацией IBM и выпускаемая ею с 1992 по 2005 год, с 2005 года права на производство этой серии переданы компании Lenovo.

Первые три модели ThinkPad — 700, 700C и 700T — были выпущены в октябре 1992 года. В модели 700C использовался процессор 486SLC (25 МГц), жёсткий диск объёмом 120 МБ, впервые в истории был выпущен 10,4-дюймовый цветной ЖК-дисплей.

Дизайн ноутбуков ThinkPad основан на концепции Bento Box, разработанной немецким дизайнером Ричардом Саппером. На одном из собраний с представителями IBM Саппер обратил внимание на традиционную японскую коробку для еды — Макуноути Бенто (Makunouchi Bento Box). Чёрная, квадратная, с красными отсеками внутри она оказалась идеальным прототипом ноутбука.

2 декабря 1993 года космический шаттл Endeavour доставил первый ноутбук ThinkPad в космос. Он использовался для ремонта космического телескопа «Хаббл»

если хотите, можете помочь мне собрать на Thinkpad
👍4🤔11
Работа с сокетами в C

Примерный набор библиотек, которые, скорее всего, придётся подключить выглядит так:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

Сокет в Си создаётся следующим образом:

int socket(int domain, int type, int protocol);

domain: Аргументом является семейство протоколов. Если Вы планируете использовать IPv4 укажите домен AF_INET.

Если нужен IPv6 то AF_INET6. Полный список смотрите в разделе MAN DESCRIPTION

type: Обычно выбирают SOCK_STREAM это надёжная упорядоченная передача байтов в режиме полный дуплекс.

Полный список типов: MAN DESCRIPTION types

protocol: Обычно выбирают 0. Если Вам нужен не 0, то Вы уже, видимо, знаете, что делаете лучше меня.

Пример:

int socket(AF_INET, SOCK_STREAM, 0);

Давайте напишем простой TCP сервер:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {

char server_message[256] = "You have reached the server!";

// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);

// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;

// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));

// second agrument is a backlog - how many connections
// can be waiting for this socket simultaneously
listen(server_socket, 5);

int client_socket;

client_socket = accept(server_socket, NULL, NULL);

// send the message
send(client_socket, server_message, sizeof(server_message), 0);

// close the socket
close(server_socket);

return 0;
}
👍7👎22
ORM, или объектно-реляционное отображение — это программная технология, которая позволяет взаимодействовать с базами данных с использованием объектно-ориентированной парадигмы. Вместо того чтобы писать SQL-запросы напрямую для работы с данными в базе данных, можно использовать ORM, чтобы взаимодействовать с данными, как если бы они были объектами в вашем коде.

ORM позволяет абстрагироваться от сырых SQL запросов путем абстракций.

В этой статье мы и рассмотрим создание своей ORM на Python с документацией и публикацией на PyPI. Данный проект очень интересен со стороны реализации: ведь требуется изучить большую часть ООП, принципов и паттернов.

Мы создадим сессии, модели баз данных, различные поля, миграции и другой вспомогательный функционал. Мы разберем изнутри, как работает такая концепция и как достигается удобство работы.

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

https://habr.com/ru/companies/timeweb/articles/851706/
👍6🔥32👎1
#HEX • IT pinned «ORM, или объектно-реляционное отображение — это программная технология, которая позволяет взаимодействовать с базами данных с использованием объектно-ориентированной парадигмы. Вместо того чтобы писать SQL-запросы напрямую для работы с данными в базе данных…»
Асинхронность, параллельность, многопроцессорность и многопоточность.

Асинхронность предполагает, что выполнение операций не блокирует поток, который их инициирует. Это означает, что программа может продолжать выполнение, не дожидаясь завершения определённой операции. Асинхронность активно используется в сетевых приложениях, веб-серверах и других системах, где важна отзывчивость. Например, в JavaScript асинхронные операции достигаются с помощью промисов и async/await. Асинхронный код позволяет избежать блокировок, но требует управления состоянием выполнения, что может привести к более сложному коду.

Например, следующий код в JavaScript демонстрирует, как асинхронная функция может выполнять запросы к API без блокировки основного потока:

async function fetchData() {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
}

fetchData();
console.log('Это сообщение появится раньше, чем данные от API.');

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

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

class MyRunnable implements Runnable {
public void run() {
System.out.println("Запуск потока: " + Thread.currentThread().getName());
}
}

public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable());
Thread thread2 = new Thread(new MyRunnable());

thread1.start();
thread2.start();
}
}

Параллельность как концепция предполагает одновременное выполнение нескольких процессов или потоков с целью повышения производительности и рационального использования ресурсов. Параллельные вычисления возможны только в многопроцессорных или многоядерных системах, где различные проверки выполняются одновременно. Ключевым моментом является то, что параллелизм — это "аппаратное" явление, в то время как многопоточность — "программное".

В языках, таких как Python, библиотека multiprocessing может быть использована для выполнения параллельных задач на разных ядрах:

import multiprocessing

def worker(num):
print(f'Работник {num}')

if __name__ == '__main__':
processes = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
processes.append(p)
p.start()

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

Теперь давайте подведем итог:

- Асинхронность — это не блокирующее выполнение операций, позволяющее оставаться отзывчивым.
- Многопоточность — это возможность выполнения нескольких потоков в рамках одной программы, управляемой одной операционной системой.
- Параллельность — это одновременное выполнение задач, требующее от оборудования поддержки многопоточности.
- Многопроцессорность — это механика, позволяющая запускать несколько процессов и пулов процессов.
522👍1
Недавно вышла новая песня от научно-технического рэпа - "Язык для славян"

Я.Музыка: https://music.yandex.ru/album/33934790/track/132728259?utm_medium=copy_link
MTS MUSIC: https://music.mts.ru/album/33934790/track/132728259

1С - язык без изъян!
1С - язык для славян!
Для тех, кто решился работать в IT,
Язык 1С - вершина пути!
2🤬1👨‍💻1
Грокаем глубокое обучение.pdf
19.6 MB
Грокаем глубокое обучение.

Автор: Траск Эндрю
Грокаем стриминг.pdf
14.9 MB
Грокаем стриминг

Авторы: Джош Фишер, Нин Ван
Грокаем алгоритмы ИИ.pdf
8.8 MB
Грокаем алгоритмы искусcтвенного интеллекта

Автор: Ришал Харбанс
Грокаем_глубокое_обучение_с_подкреплением.zip
10.1 MB
Грокаем глубокое обучение с подкреплением

Автор: Моралес Мигель
👍222
Компилятор Go генерирует абстрактный, портируемый ассемблер, который не привязан к конкретному оборудованию. Следовательно, сборщик Go использует этот псевдоассемблер для создания инструкций, специфичных для целевого оборудования.

Go позволяет использовать ассемблерные вставки в коде. Написание функций на ассемблере прямо в Go не так уж сложно, как кажется. В качестве примера, рассмотрим функцию sum, которая складывает два int64:

func sum(a int64, b int64) int64

Хотя это стандартная функция, в ней отсутствует тело. Поэтому компилятор выдаст ошибку при попытке сборки программы.

Для реализации функции на ассемблере добавим файл с расширением .s:

text sum(sb),$0-24
movq a+0(fp), ax
addq b+8(fp), ax
movq ax, ret+16(fp)
ret

Теперь мы можем собрать, протестировать и использовать функцию sum как обычную. Этот подход широко применяется в различных пакетах, таких как runtime, math, bytealg, syscall, reflect, crypto, позволяя использовать аппаратные оптимизации процессора и команды, отсутствующие в самом языке. Во многом благодаря этому можно создать полноценное ядро операционной системы.

Однако следует учитывать, что функции на ассемблере не могут быть оптимизированы и встроены компилятором. Для обхода этого ограничения разработчики создали встраиваемые функции.

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

Встраиваемые функции представляют собой элегантное решение, предоставляющее доступ к низкоуровневым операциям без необходимости расширения спецификации языка. В случае отсутствия специфических примитивов sync/atomic (например, в некоторых вариантах arm), или операций из math/bits, компилятор будет вставлять полифил на обычном Go.

Источник: [встраиваемые функции в Go](https://dave.cheney.net/2019/08/20/go-compiler-intrinsics)
👍3🔥1
https://github.com/alexeev-prog/carbon-colorscheme

Моя цветовая схема - Carbon.

Пока есть конфиг для терминала alacritty и sublime text.
👍53