vault backup: 2025-04-19 01:11:07
This commit is contained in:
6
.obsidian/workspace.json
vendored
6
.obsidian/workspace.json
vendored
@@ -41,12 +41,12 @@
|
|||||||
"state": {
|
"state": {
|
||||||
"type": "markdown",
|
"type": "markdown",
|
||||||
"state": {
|
"state": {
|
||||||
"file": "PERSONAL PROJECTS/PS1 DOCS/PS1 DMA.md",
|
"file": "PERSONAL PROJECTS/PS1 DOCS/PS1 Ordering table.md",
|
||||||
"mode": "source",
|
"mode": "source",
|
||||||
"source": false
|
"source": false
|
||||||
},
|
},
|
||||||
"icon": "lucide-file",
|
"icon": "lucide-file",
|
||||||
"title": "PS1 DMA"
|
"title": "PS1 Ordering table"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -207,10 +207,10 @@
|
|||||||
},
|
},
|
||||||
"active": "dd912cc876184c4f",
|
"active": "dd912cc876184c4f",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 MDEC.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 MDEC.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 IRQ.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA.md",
|
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PSX code IRQ handling.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PSX code IRQ handling.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 Geometry Transformation Engine.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 Geometry Transformation Engine.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/LZSS C++ Lib.md",
|
"PERSONAL PROJECTS/PS1 DOCS/LZSS C++ Lib.md",
|
||||||
|
|||||||
@@ -134,4 +134,108 @@ render_frame();
|
|||||||
- **Для сложных сцен** комбинируют OT, Bounding Box и приоритетные группы.
|
- **Для сложных сцен** комбинируют OT, Bounding Box и приоритетные группы.
|
||||||
- **Оптимизации** нужны для борьбы с артефактами.
|
- **Оптимизации** нужны для борьбы с артефактами.
|
||||||
|
|
||||||
Этот подход использовался в играх типа *Tekken 3* и *Resident Evil*. Для глубокого понимания изучите [документацию PsyQ](http://psx.arthus.net/sdk/PsyQ/DOCS/).
|
Этот подход использовался в играх типа *Tekken 3* и *Resident Evil*. Для глубокого понимания изучите [документацию PsyQ](http://psx.arthus.net/sdk/PsyQ/DOCS/).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Функция `DrawOTag` в библиотеке PsyQ для PlayStation 1
|
||||||
|
|
||||||
|
Функция `DrawOTag` (Draw Ordering Table Tag) является **ключевой функцией рендеринга** в графической подсистеме PlayStation 1. Она отвечает за отправку списка графических команд (Ordering Table) в графический процессор (GPU) для отрисовки.
|
||||||
|
|
||||||
|
## Основное назначение
|
||||||
|
|
||||||
|
`DrawOTag` выполняет:
|
||||||
|
1. Обработку списка команд OT (Ordering Table)
|
||||||
|
2. Отправку команд рендеринга в GPU
|
||||||
|
3. Управление приоритетом отрисовки объектов (Z-sorting через OT)
|
||||||
|
|
||||||
|
## Синтаксис
|
||||||
|
|
||||||
|
```c
|
||||||
|
void DrawOTag(unsigned long *ot);
|
||||||
|
```
|
||||||
|
где `ot` - указатель на Ordering Table (таблицу упорядочивания)
|
||||||
|
|
||||||
|
## Как работает Ordering Table (OT)
|
||||||
|
|
||||||
|
OT представляет собой массив указателей, где:
|
||||||
|
- Каждый элемент соответствует определенному уровню глубины (Z-буфер в упрощенной форме)
|
||||||
|
- Элементы содержат связанные списки графических примитивов (POLY_F3, SPRT и т.д.)
|
||||||
|
- Примитивы в одном слое OT рисуются в порядке добавления
|
||||||
|
|
||||||
|
## Пример использования
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <libgte.h>
|
||||||
|
#include <libgpu.h>
|
||||||
|
#include <libetc.h>
|
||||||
|
|
||||||
|
#define OT_LENGTH 10 // Количество Z-уровней
|
||||||
|
#define PACKETMAX 1000 // Максимальное количество примитивов
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DISPENV disp; // Display environment
|
||||||
|
DRAWENV draw; // Drawing environment
|
||||||
|
unsigned long ot[OT_LENGTH]; // Ordering Table
|
||||||
|
char p[PACKETMAX]; // Буфер для пакетов примитивов
|
||||||
|
} DB;
|
||||||
|
|
||||||
|
DB db[2]; // Double buffer
|
||||||
|
int active_buffer = 0; // Текущий буфер
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
// Инициализация графики
|
||||||
|
ResetGraph(0);
|
||||||
|
SetDefDispEnv(&db[0].disp, 0, 0, 320, 240);
|
||||||
|
SetDefDrawEnv(&db[0].draw, 0, 0, 320, 240);
|
||||||
|
SetDefDispEnv(&db[1].disp, 0, 0, 320, 240);
|
||||||
|
SetDefDrawEnv(&db[1].draw, 0, 0, 320, 240);
|
||||||
|
|
||||||
|
// Включение отображения
|
||||||
|
SetDispMask(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render() {
|
||||||
|
DB *cdb = &db[active_buffer];
|
||||||
|
|
||||||
|
// Очистка OT
|
||||||
|
ClearOTagR(cdb->ot, OT_LENGTH);
|
||||||
|
|
||||||
|
// Добавление примитивов в OT (пример)
|
||||||
|
add_primitive_to_ot(cdb);
|
||||||
|
|
||||||
|
// Рендеринг OT
|
||||||
|
DrawOTag(cdb->ot);
|
||||||
|
|
||||||
|
// Смена буферов
|
||||||
|
FntFlush(-1);
|
||||||
|
VSync(0);
|
||||||
|
PutDispEnv(&cdb->disp);
|
||||||
|
PutDrawEnv(&cdb->draw);
|
||||||
|
active_buffer ^= 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Особенности работы
|
||||||
|
|
||||||
|
1. **Двойная буферизация** - обычно используют два набора OT и буферов примитивов
|
||||||
|
2. **Сортировка по глубине** - OT автоматически сортирует примитивы по Z-координате
|
||||||
|
3. **Аппаратное ускорение** - функция использует возможности GPU PS1
|
||||||
|
4. **Минимизация перерисовки** - только измененные примитивы нужно добавлять каждый кадр
|
||||||
|
|
||||||
|
## Оптимизация производительности
|
||||||
|
|
||||||
|
1. **Размер OT** - должен соответствовать количеству уровней глубины в сцене
|
||||||
|
2. **Распределение примитивов** - равномерное по слоям OT улучшает сортировку
|
||||||
|
3. **Локальность данных** - последовательное расположение пакетов в памяти
|
||||||
|
4. **Очистка OT** - обязательна перед началом нового кадра (`ClearOTag` или `ClearOTagR`)
|
||||||
|
|
||||||
|
## Варианты функции
|
||||||
|
|
||||||
|
В PsyQ существуют несколько вариантов:
|
||||||
|
- `DrawOTag` - базовый вариант
|
||||||
|
- `DrawOTagEnv` - с применением DRAWENV
|
||||||
|
- `DrawOTagDMA` - использует DMA для передачи данных
|
||||||
|
|
||||||
|
Функция `DrawOTag` является фундаментальной для графического рендеринга на PS1 и понимание её работы необходимо для создания эффективных графических приложений на этой платформе.
|
||||||
Reference in New Issue
Block a user