Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.66/29: Рейтинг темы: голосов - 29, средняя оценка - 4.66
1 / 1 / 0
Регистрация: 10.03.2020
Сообщений: 56

Как сделать фото с встроенной веб-камеры?

11.03.2020, 12:38. Показов 6011. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Недавно появилась задача сделать программу (на ассемблере), которая бы подключалась к веб-камере, делала фото с неё, записывала 10-ти секундное видео и сохраняла бы на компьютер. Однако, она работает не совсем как надо. У меня ноутбук - Acer Predator со встроенной веб-камерой (и win 10 в качестве ОС). Когда я написал код и решил проверить его работу, то столкнулся с проблемой - программе удается подключиться к камере и даже записать и сохранить видео, но вот с фото возникает проблема - сохраняется пустой .bmp файл. В отладчике, при этом, после выполнения строки
Assembler
1
invoke SendMessage,ebx,WM_CAP_FILE_SAVEDIB,0,ADDR file1
возвращается результат False (0), с кодом ошибки 00000006 и ошибкой 'ERROR_INVALID_HANDLE'. Самое интересное, что когда я подключаю любую другую вебку, то с ней всё работает как надо - сохраняется нормально и фото и видео, не возникает никаких ошибок. Так вот сам вопрос: как сделать так, чтобы фото сохранялось со встроенной веб-камеры?
Ниже привожу код программы на ассемблере. Используются avicap32, user32, kernel32, vfw32 (я плохо разбираюсь в api, так что не исключаю, что что-то из этого может быть лишним).
Сам код:
Assembler
1
2
3
4
5
6
7
8
9
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
.386
.model flat,stdcall
 
include ..\INCLUDE\kernel32.inc 
include ..\INCLUDE\user32.inc 
includelib ..\LIB\kernel32.lib 
includelib ..\LIB\user32.lib
 
include ..\INCLUDE\masm32rt.inc
include ..\INCLUDE\avicap32.inc
includelib ..\LIB\avicap32.lib
 
;include ..\INCLUDE\vfw32.inc
includelib ..\LIB\vfw32.lib
 
CAPTUREPARMS STRUCT
            dwRequestMicroSecPerFrame  DWORD  ?      ; Requested capture rate
            fMakeUserHitOKToCapture    DWORD  ?      ; Show "Hit OK to cap" dlg?
            wPercentDropForError       DWORD  ?      ; Give error msg if > (10%)
            fYield                     DWORD  ?      ; Capture via background task?
            dwIndexSize                DWORD  ?      ; Max index size in frames (32K)
            wChunkGranularity          DWORD  ?      ; Junk chunk granularity (2K)
            fUsingDOSMemory            DWORD  ?      ; Use DOS buffers?
            wNumVideoRequested         DWORD  ?      ; # video buffers, If 0, autocalc
            fCaptureAudio              DWORD  ?      ; Capture audio?
            wNumAudioRequested         DWORD  ?      ; # audio buffers, If 0, autocalc
            vKeyAbort                  DWORD  ?      ; Virtual key causing abort
            fAbortLeftMouse            DWORD  ?      ; Abort on left mouse?
            fAbortRightMouse           DWORD  ?      ; Abort on right mouse?
            fLimitEnabled              DWORD  ?      ; Use wTimeLimit?
            wTimeLimit                 DWORD  ?      ; Seconds to capture
            fMCIControl                DWORD  ?      ; Use MCI video source?
            fStepMCIDevice             DWORD  ?      ; Step MCI device?
            dwMCIStartTime             DWORD  ?      ; Time to start in MS
            dwMCIStopTime              DWORD  ?      ; Time to stop in MS
            fStepCaptureAt2x           DWORD  ?      ; Perform spatial averaging 2x
            wStepCaptureAverageFrames  DWORD  ?      ; Temporal average n Frames
            dwAudioBufferSize          DWORD  ?      ; Size of audio bufs (0 = default)
            fDisableWriteCache         DWORD  ?      ; Attempt to disable write cache
            AVStreamMaster             DWORD  ?      ; Which stream controls length?
        CAPTUREPARMS ENDS
 
.const
 
;WM_CAP_DRIVER_CONNECT       equ WM_USER + 10
;WM_CAP_DRIVER_DISCONNECT    equ WM_USER + 11
;WM_CAP_FILE_SAVEDIB         equ WM_USER + 25
;WM_CAP_SET_PREVIEW         equ WM_CAP_START + 50
 
.data
 
file1  db "AAAA.bmp",0
title1 db 'webcam',0                ;название окна
device dd 0                 ;номер устройства камеры (0-9)
kek db "AAA.avi",0              ;название результирующего файла
CaptureParms   CAPTUREPARMS <>
 
.code
start:
 
;---------------------------------------------------------------------------------------------
 
invoke capCreateCaptureWindow,0,0,0,0,0,0,HWND_DESKTOP,0                ;изменил HWND на dHandle
mov ebx,eax
 
  
mov [device],0
@@:
invoke SendMessage,ebx,WM_CAP_DRIVER_CONNECT,device,0
cmp eax,TRUE
je @f
inc [device]
cmp [device],9
jbe @b
invoke DestroyWindow,ebx
jmp exit1
@@:
    
        
        invoke SendMessage,ebx,WM_CAP_SET_SCALE,TRUE,0
            invoke SendMessage,ebx,WM_CAP_SET_PREVIEW,TRUE,0
            invoke SendMessage,ebx,WM_CAP_SET_PREVIEWRATE,10,0
        ;invoke SendMessage,ebx,WM_CAP_GRAB_FRAME,0,0
invoke SendMessage,ebx,WM_CAP_FILE_SAVEDIB,0,ADDR file1
        invoke SendMessage,ebx,WM_CAP_FILE_SET_CAPTURE_FILE,0,ADDR kek
        invoke SendMessage,ebx,WM_CAP_GET_SEQUENCE_SETUP,sizeof CaptureParms,ADDR CaptureParms
        mov CaptureParms.fCaptureAudio,TRUE
        mov CaptureParms.fLimitEnabled,TRUE
                        mov CaptureParms.wTimeLimit,10
        invoke SendMessage,ebx,WM_CAP_SET_SEQUENCE_SETUP,sizeof CaptureParms,ADDR CaptureParms
 
        invoke SendMessage,ebx,WM_CAP_SEQUENCE,0,0
        
invoke SendMessage,ebx,WM_CAP_DRIVER_DISCONNECT,ADDR title1,0
 
invoke DestroyWindow,ebx
 
exit1:
invoke ExitProcess,0
 
end start
Спасибо большое всем, кто примет участие в обсуждении!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.03.2020, 12:38
Ответы с готовыми решениями:

Сделать фото с веб-камеры и сохранить на диск
Добрый день уважаемые форумчане. Пища для размышления: кто-нибудь видел или знает как можно реализовать на VBA, что бы при определенных...

Как получить фото с веб-камеры Logitech
Здравствуйте ! Можно ли как-нибудь в программе на C# (Visual Studio 2010, .Net 4) получить фото с веб-камеры Logitech ? Минимум:...

Указать путь сохранения фото с веб камеры
char filename; void SaveImage() { // сохраняем кадр в файл sprintf(filename, &quot;Image%d.bmp&quot;, counter); printf(&quot; Сделан...

2
Заблокирован
11.03.2020, 14:25
klaustrofob, думаю переделаешь с легкостью

C++
1
2
3
4
5
6
7
8
9
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <windows.h>
#include <vfw.h>
#pragma comment(lib,"vfw32.lib")
 
//
// nIndex - индекс драйвера может варьироваться от 0 до 9
// Filename - адрес строки с нулевым символом в конце, имя целевого файла DIB (bmp)
//
 
BOOL CaptureFrame(DWORD nIndex, char* Filename)
{
    HWND hwnd=CreateWindow("WSCLAS","",0,0,0,1,1,HWND_DESKTOP,NULL,GetModuleHandle(NULL),NULL); 
    if(!hwnd) {
        MessageBox(hwnd,"Не удалось создать родительское окно","Эрор",MB_OK);
        return FALSE;
    }
    
    HWND hwndCap=capCreateCaptureWindow("Window",WS_CHILD,0,0,160,120,hwnd,1);
    if(!hwndCap) {
        DestroyWindow(hwnd);
        MessageBox(hwnd,"Не удалось создать окно захвата","Эрор",MB_OK);
        return FALSE;
    }
 
    char buf[1024];
    if(!capDriverConnect(hwndCap, nIndex)) {
        DestroyWindow(hwnd);
        DestroyWindow(hwndCap);
        wsprintf(buf, "Невозможно подключиться к драйверу - %d\n", nIndex);
        MessageBox(hwnd,buf,"Info",MB_OK);
        return FALSE;
    }
    
    CAPDRIVERCAPS pcdc;
    capDriverGetCaps(hwndCap, &pcdc, sizeof(CAPDRIVERCAPS));
    if(!pcdc.fCaptureInitialized) {
        DestroyWindow(hwnd);
        DestroyWindow(hwndCap);
        wsprintf(buf, "Драйвер не был инициализирован для устройства - %d\n", nIndex);
        MessageBox(hwnd,buf,"Info",MB_OK);
        return FALSE;
    }
    
    DWORD dwSize=capGetVideoFormatSize(hwndCap);
    BITMAPINFO* pbiOrig=(BITMAPINFO *)malloc(dwSize);
    if(!pbiOrig) {
        DestroyWindow(hwndCap);
        DestroyWindow(hwnd);
        MessageBox(hwnd,"Ошибка выделения памяти","Эрор",MB_OK);
        return FALSE;
    }
 
    BITMAPINFO* pbiInfo=(BITMAPINFO *)malloc(dwSize);
    if(!pbiInfo) {
        DestroyWindow(hwndCap);
        DestroyWindow(hwnd);
        MessageBox(hwnd,"Ошибка выделения памяти","Эрор",MB_OK);
        return FALSE;
    }
 
    capGetVideoFormat(hwndCap, pbiOrig, dwSize); 
    memcpy(pbiInfo, pbiOrig, dwSize);
 
    pbiInfo->bmiHeader.biWidth = 640;
    pbiInfo->bmiHeader.biHeight = 480;
    pbiInfo->bmiHeader.biBitCount = 16;
 
    pbiInfo->bmiHeader.biSizeImage = 0;
    pbiInfo->bmiHeader.biCompression = BI_RGB;
    pbiInfo->bmiHeader.biClrUsed = 0;
    pbiInfo->bmiHeader.biClrImportant = 0;
    pbiInfo->bmiHeader.biPlanes = 1;
    
    pbiInfo->bmiColors->rgbBlue = 0;
    pbiInfo->bmiColors->rgbGreen = 0;
    pbiInfo->bmiColors->rgbRed = 0;
    pbiInfo->bmiColors->rgbReserved = 0;
    
    // Установить формат видео, захват кадра и сохранить на диск
    capSetVideoFormat(hwndCap, pbiInfo, dwSize);
    capGrabFrameNoStop(hwndCap);
    capFileSaveDIB(hwndCap, Filename);
 
    // Восстановить исходный режим захвата и очистить
    capSetVideoFormat(hwndCap, pbiOrig, dwSize);
 
    free(pbiOrig);  // это может вызывать БСОД
    free(pbiInfo);  // проверьте на месте...
 
    capDriverDisconnect(hwndCap);   
    DestroyWindow(hwndCap);
    DestroyWindow(hwnd);
    
    return TRUE;    // Удача - кадр записан в файл!
}
 
//
// Начало
//
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    CaptureFrame(0, "c:\\win368.swp");
 
    return 0;
}
0
Заблокирован
11.03.2020, 20:39
klaustrofob,

Специально от Меня - для Тебя!!!

C++
1
2
3
4
5
6
7
8
9
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
////////////////////////////////////////////////////////////////////////////////
// WinMain.cpp
 
#pragma comment(lib,"vfw32.lib")
#include <windows.h>
#include <vfw.h>
 
#define MAX_DIB 3
 
TCHAR GWndname[]=TEXT("qll_class");
TCHAR GAppname[]=TEXT("Capture Frame");
TCHAR GFolderDib[]=TEXT("CapDIB");
 
void warn(LPCTSTR x){MessageBox(GetActiveWindow(),x,GAppname,MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);}
void err(LPCTSTR x){MessageBox(GetActiveWindow(),x,GAppname,MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SYSTEMMODAL);ExitProcess(0);}
 
//
// nIndex - индекс драйвера может варьироваться от 0 до 9
// Filename - адрес строки с нулевым символом в конце, имя целевого файла DIB (bmp)
//
 
BOOL CaptureFrame(HWND hWnd, DWORD nIndex, LPCTSTR Filename)
{
    HWND hwndCap=capCreateCaptureWindow(TEXT("Window"),WS_CHILD,0,0,160,120,hWnd,1);
    if(!hwndCap) {
        warn(TEXT("Не удалось создать окно захвата"));
        return FALSE;
    }
 
    TCHAR buf[1024];
    if(!capDriverConnect(hwndCap, nIndex)) {
        DestroyWindow(hwndCap);
        wsprintf(buf,TEXT("Невозможно подключиться к драйверу - %d"), nIndex);
        warn(buf);
        return FALSE;
    }
 
    CAPDRIVERCAPS pcdc;
    capDriverGetCaps(hwndCap, &pcdc, sizeof(CAPDRIVERCAPS));
    if(!pcdc.fCaptureInitialized) {
        DestroyWindow(hwndCap);
        wsprintf(buf,TEXT("Драйвер не был инициализирован для устройства - %d"),nIndex);
        warn(buf);
        return FALSE;
    }
    
    DWORD dwSize=capGetVideoFormatSize(hwndCap);
    BITMAPINFO* pbiOrig=(BITMAPINFO*)malloc(dwSize);
    if(!pbiOrig) {
        DestroyWindow(hwndCap);
        warn(TEXT("Ошибка выделения памяти"));
        return FALSE;
    }
 
    BITMAPINFO* pbiInfo=(BITMAPINFO*)malloc(dwSize);
    if(!pbiInfo) {
        DestroyWindow(hwndCap);
        warn(TEXT("Ошибка выделения памяти"));
        return FALSE;
    }
 
    capGetVideoFormat(hwndCap, pbiOrig, dwSize); 
    memcpy(pbiInfo, pbiOrig, dwSize);
 
    pbiInfo->bmiHeader.biWidth = 640;
    pbiInfo->bmiHeader.biHeight = 480;
    pbiInfo->bmiHeader.biBitCount = 16;
 
    pbiInfo->bmiHeader.biSizeImage = 0;
    pbiInfo->bmiHeader.biCompression = BI_RGB;
    pbiInfo->bmiHeader.biClrUsed = 0;
    pbiInfo->bmiHeader.biClrImportant = 0;
    pbiInfo->bmiHeader.biPlanes = 1;
    
    pbiInfo->bmiColors->rgbBlue = 0;
    pbiInfo->bmiColors->rgbGreen = 0;
    pbiInfo->bmiColors->rgbRed = 0;
    pbiInfo->bmiColors->rgbReserved = 0;
 
    // Установить формат видео, захват кадра и сохранить на диск
    capSetVideoFormat(hwndCap, pbiInfo, dwSize);
    capGrabFrameNoStop(hwndCap);
    capFileSaveDIB(hwndCap, Filename);
 
    // Восстановить исходный режим захвата и очистить
    capSetVideoFormat(hwndCap, pbiOrig, dwSize);
 
    free(pbiOrig);  // это может вызывать БСОД
    //free(pbiInfo);    // проверьте на месте...
 
    capDriverDisconnect(hwndCap);
    DestroyWindow(hwndCap);
    
    return TRUE;    // Удача - кадр записан в файл!
}
 
//
// appBaseDir
//
LPCTSTR appBaseDir()
{
    int i;
    static TCHAR Result[512];
    if(!lstrlen(Result)) {
        GetModuleFileName(GetModuleHandle(NULL),Result,511);
        for(i=lstrlen(Result)-1;i>0;--i)
            if('\\'==Result[i-1] || '/'==Result[i-1])
                break;
        Result[i]=0;
    }return Result;
}
 
//
// CheckFileExists
//
BOOL CheckFileExists(LPCTSTR Filename)
{
    WIN32_FIND_DATA FindFile;
    HANDLE handle=FindFirstFile(Filename,&FindFile);
    if(INVALID_HANDLE_VALUE!=handle) {
        FindClose(handle);
        return TRUE;
    }return FALSE;
}
 
//
// GenerateFilename
//
LPCTSTR GenerateFilename(LPCTSTR Name)
{
    static nCount;
    static TCHAR Filename[512];
    if(Filename[0]) *Filename=0;
 
    static TCHAR Foldername[512];
    if(!Foldername[0])
    {
        wsprintf(Foldername,TEXT("%s%s"),appBaseDir(),GFolderDib);
        if(!CheckFileExists(Foldername))
        {
            if(!CreateDirectory(Foldername,NULL))
            {
                TCHAR Buffer[512];
                wsprintf(Buffer,TEXT("Could not create directory:\n\"%s\""),Foldername);
                err(Buffer);
            }
        }
    }
    if(MAX_DIB!=nCount)
    {
        wsprintf(Filename, TEXT("%s\\%s%03d.bmp"),Foldername,Name,nCount);
        ++nCount;
    }
    return Filename;
}
 
//
// GetListCaps
//
int GetListCaps()
{
    TCHAR Buffer[1024];
    TCHAR Name[256];
    TCHAR Comment[512]; 
    int nCount=-1;
    for(int i=0; i<5; ++i)
    {
        if(capGetDriverDescription(i,Name,255, Comment,512))
        {
            wsprintf(Buffer, TEXT("%d: %s %s"),i,Name,Comment);
            ++nCount;
        }
    }   
    wsprintf(Buffer,TEXT("%d devices listed"),nCount);  
    return nCount;
}
 
//
// Начало
//
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    if(0>GetListCaps())
        err(TEXT("No device"));
 
    HINSTANCE hInstance=GetModuleHandle(NULL);
    WNDCLASSEX wcex={sizeof(WNDCLASSEX),0,DefWindowProc,0,0,hInstance,NULL,NULL,NULL,NULL,GWndname,NULL,};
    ATOM Atom=RegisterClassEx(&wcex);
    if(!Atom) {
        Atom=RegisterClass((LPWNDCLASS)&wcex.style);
        if(!Atom) err(TEXT("Cannot register class"));
    }
 
    HWND hWnd=CreateWindowEx(0,MAKEINTATOM(Atom),GAppname,0,0,0,0,0,HWND_DESKTOP,NULL,hInstance,NULL);
    if(!hWnd) err(TEXT("Cannot create window"));
 
    TCHAR Name[64];
    GetDateFormat(LOCALE_SYSTEM_DEFAULT,0,NULL,TEXT("dd_MM_yyyy_"),Name,63);
 
    TCHAR Filename[1024];
    lstrcpy(Filename,GenerateFilename(Name));
 
    while(Filename[0])
    {
        if(!CaptureFrame(hWnd,0,Filename))
            break;
        lstrcpy(Filename,GenerateFilename(Name));
    }
    return 0;
}
 
////////////////////////////////////////////////////////////////////////////////
// <<eof>> WinMain.cpp
////////////////////////////////////////////////////////////////////////////////
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.03.2020, 20:39
Помогаю со студенческими работами здесь

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

Получение фото с веб камеры, занесение его в Bitmap и преобразование Bitmap в массив
В общем необходимо подключиться к веб камере сделать снимок и отправить его в сеть. Задачу я разделил на несколько этапов. 1. Сам...

Невозможно сделать запись видео с веб-камеры в You Tube
В ноутбуке (прогр.обесп. - Vista) - встроенная веб-камера, в ПК (Windows XP) - подключаемая веб-камера. И там, и там не могу записать в You...

Сделать снимок с веб-камеры, сохранить на диск с сохранением пути в БД
Здравствуйте, требуется написать программу учета рабочего времени сотрудников. Если в целом, то задача сводится к тому, что есть таблица, в...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru