Я пытаюсь сделать в игре проигрывание ролика в определённый момент но не получается вывести видео . Подскажите где ошибка.
Код:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <Jpeg.hpp>
#include <string.h>
#include <iostream.h>
#pragma hdrstop
unsigned int t1,t2;
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include "Unit1.h"
#include "avi.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HGLRC hGLRC;
HDC hDC;
int cw,ch;
GLuint texture[6];
AnsiString texture_path[6];
//---------------------------------------------------------------------------
void CreateTexture(unsigned int* Num, AnsiString File)
{
Graphics::TBitmap* Texture = new Graphics::TBitmap;
Texture->PixelFormat = pf24bit;
if (File.UpperCase().Pos(".JPG"))
{
TJPEGImage* jpg= new TJPEGImage;
jpg->LoadFromFile(File);
Texture->Assign(jpg);
}
if (File.UpperCase().Pos(".BMP"))
{
Texture->LoadFromFile(File);
}
int u1=Texture->Width,u2=Texture->Height;
__int8* TexPixels = (__int8*) malloc(u1 * u2 * 3);
ZeroMemory(TexPixels, u1 * u2 * 3);
for(int y = 0; y < u2; y++) {
for(int x = 0; x < u1; x++){
__int8* p = TexPixels + y * u1 * 3 + x * 3;
*p = GetRValue(Texture->Canvas->Pixels[x][y]);
*(p+1) = GetGValue(Texture->Canvas->Pixels[x][y]);
*(p+2) = GetBValue(Texture->Canvas->Pixels[x][y]);
// *(p+3) = 0;
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, Num);
glBindTexture(GL_TEXTURE_2D, (*Num));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3,u1, u2,0,GL_RGB,GL_UNSIGNED_BYTE,(void*)TexPixels);
free(TexPixels);
delete Texture;
}
void CreateTextureAvi(unsigned int* Num, AnsiString File)
{
OpenAVI(File.c_str()); // Откроем видео-файл
glGenTextures(1, &t2);
glBindTexture(GL_TEXTURE_2D, t2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE,data);
}
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
BorderStyle=bsNone;
WindowState=wsMaximized;
hDC = GetDC(Handle);
cw=Screen->Width;
ch=Screen->Height;
int PixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0,0, 0,0,0,0,0, 32, 0,
0, PFD_MAIN_PLANE, 0, 0,0,};
PixelFormat = ChoosePixelFormat (hDC, &pfd);
if (SetPixelFormat (hDC, PixelFormat, &pfd) == FALSE)
Application->Terminate ();
hGLRC = wglCreateContext(hDC);
if(hGLRC == NULL) Application->Terminate ();
if(wglMakeCurrent(hDC, hGLRC) == false) Application->Terminate ();
glEnable (GL_DEPTH_TEST);
glViewport (0, 0, Width, Height);
glShadeModel (GL_SMOOTH);
glClearColor (0.0, 0.0, 0.0, 1.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
// gluPerspective (90, GLdouble(Width/Height), 1.0, 100.0);
glOrtho( 1, Screen->Width, 1, Screen->Height, 0, 1 );
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
// gluLookAt (0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); // только текстуры без исходного цвета
glEnable(GL_TEXTURE_2D); // разрешаем использование текстур
Application->OnIdle = AppIdle;
Randomize();
CreateTexture(&t1, "texture\\fire.jpg");
CreateTextureAvi(&t2,"C:\\Users\\Acer\\Desktop\\GAME\\Interfeis\\OpenGL\\2D\\texture\\Face2.avi");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
glViewport (0, 0, Width, Height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//gluPerspective (90, GLdouble(Width/Height), 1.0, 100.0);
glOrtho( 1, Screen->Width, 1, Screen->Height, 0, 1 );
glMatrixMode (GL_MODELVIEW);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if (hGLRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hGLRC);
hGLRC = NULL;
}
if (hDC)
{
ReleaseDC(Handle, hDC);
hDC = NULL;
}
}
//---------------------------------------------------------------------------
int hh;
void DrawTargets()
{
glLoadName(1);
glBegin(GL_QUADS);
glVertex2f(400.0+hh, 400.0+hh);
glVertex2f(400.0+hh, 450.0-hh);
glVertex2f(650.0-hh, 450.0+hh);
glVertex2f(650.0-hh, 400.0-hh);
glEnd();
}
int Selection(void) // Здесь происходит выбор
{
int mouse_x=Mouse->CursorPos.x;
int mouse_y=Mouse->CursorPos.y;
GLuint buffer[512]; // Настройка буфера выбора
GLint hits; // Число объектов, которые мы выбрали
//PlaySound("data/shot.wav",NULL,SND_ASYNC); // Проигрывание звука выстрела
// Размер области просмотра. [0] - <x>, [1] - <y>, [2] - <length>, [3] - <width>
GLint viewport[4];
// Помещаем в массив <viewport> размеры и положение на экране относительно окна
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(512, buffer); // Скажем OpenGL использовать этот массив для выбора
// Переключить OpenGL в режим выбора. Ничего не будет нарисовано.
// Идентификатор объекта и его размеры будут сохранены в буфере.
(void) glRenderMode(GL_SELECT);
glInitNames(); // Инициализация стека имен
glPushName(0); // Поместить 0 в стек (наименьший первый элемент)
glMatrixMode(GL_PROJECTION); // Выбор матрицы проецирования
glPushMatrix(); // Поместить матрицу проецирования
glLoadIdentity(); // Сброс матрицы
// Создание матрицы, которая будет задавать маленькую часть экрана под мышью.
gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 1.0f, 1.0f, viewport);
// Применить перспективную матрицу
// gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]),
// 0.1f, 100.0f);
glOrtho( 1, Screen->Width, 1, Screen->Height, 0, 1 );
glMatrixMode(GL_MODELVIEW); // Выбор матрицы вида модели
DrawTargets(); // Визуализация целей в буфер выбора
glMatrixMode(GL_PROJECTION); // Выбор матрицы проецирования
glPopMatrix(); // Получить матрицу проецирования
glMatrixMode(GL_MODELVIEW); // Выбор матрицы вида модели
hits=glRenderMode(GL_RENDER); // Выбор режима визуализации, найти как много
if (hits > 0) // Если есть попадания
{
int choose = buffer[3]; // Сделать наш выбор первым объектом
int depth = buffer[1]; // Сохранить как далеко он
for (int loop = 1; loop < hits; loop++) // Цикл по всем обнаруженным попаданиям
{
// Если этот объект ближе, чем выбранный
if (buffer[loop*4+1] < GLuint(depth))
{
choose = buffer[loop*4+3]; // Выбрать ближний объект
depth = buffer[loop*4+1]; // Сохранить как далеко он
}
}
return choose;
}
else
{
return -1;
}
}
int gg;
void __fastcall TForm1::AppIdle(TObject *Sender, bool &Done)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
glBindTexture(GL_TEXTURE_2D, t1);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(400.0+hh, 400.0+hh);
glTexCoord2f(0.0f, 0.0f); glVertex2f(400.0+hh, 450.0-hh);
glTexCoord2f(1.0f, 0.0f); glVertex2f(650.0-hh, 450.0+hh);
glTexCoord2f(1.0f, 1.0f); glVertex2f(650.0-hh, 400.0-hh);
glEnd();
/* glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, ch);
glTexCoord2f(1.0f, 0.0f); glVertex2f(cw, ch);
glTexCoord2f(1.0f, 1.0f); glVertex2f(cw, 0.0);
glEnd(); */
gg++;
GrabAVIFrame(3); // Захват кадра анимации
glBindTexture(GL_TEXTURE_2D, t2);
glBegin(GL_QUADS); // Начало прорисовки фонового рисунка
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 256.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(256.0, 256.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(256.0, 0.0);
glEnd();
if (int x=Selection()!=-1)
{
hh=10;
Edit1->Text=IntToStr(x);
}
else
{
hh=0;
Edit1->Text=IntToStr(x);
}
glFlush ();
SwapBuffers(hDC);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (Key == VK_ESCAPE) Application->Terminate ();
}
//---------------------------------------------------------------------------
Код:
#include <windows.h> // Заголовочный файл Windows
#include <vfw.h> // Заголовочный файл для «Видео для Windows»
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#pragma comment(Psdk, "vfw32.lib" ) // Искать VFW32.lib при линковке
#ifndef CDS_FULLSCREEN // CDS_FULLSCREEN не определяется некоторыми
#define CDS_FULLSCREEN 4 // компиляторами. Определяем эту константу
#endif // Таким образом мы можем избежать ошибок
//GL_Window *g_window;
//Keys* g_keys;
float angle; // Для вращения
int next; // Для анимации
int frame=0; // Счётчик кадров
int effect; // Текущий эффект
bool sp; // Пробел нажат?
bool env=TRUE; // Показ среды(По умолчанию включен)
bool ep; // 'E' нажато?
bool bg=TRUE; // Фон(по умолчанию включен)
bool bp; // 'B' нажато?
AVISTREAMINFO psi; // Указатель на структуру содержащую информацию о потоке
PAVISTREAM pavi; // Дескриптор для открытия потока
PGETFRAME pgf; // Указатель на объект GetFrame
BITMAPINFOHEADER bmih; // Заголовочная информация для DrawDibDraw декодирования
long lastframe; // Последний кадр анимации
int width; // Ширина видео
int height; // Высота видео
char *pdata; // Указатель на данные текстуры
int mpf; // Сколько миллисекунд отображен кадр
GLUquadricObj *quadratic; // Хранилище для наших квадратичных объектов
HDRAWDIB hdd; // Дескриптор для нашего рисунка
HBITMAP hBitmap; // Дескриптор устройства растра
HDC hdc = CreateCompatibleDC(0); // Создание совместимого контекста устройства
unsigned int *data = 0; // Указатель на наше измененное в размерах изображение
void flipIt(void* buffer) // Функция меняющая красный и синий цвет
{
void* b = buffer; // Указатель на буфер
__asm // Начало asm кода
{
mov ecx, 256*256 // Установка счётчика (Размер блока памяти)
mov ebx, b // Указатель ebx на наши данные (b)
label: // Метка для цикла
mov al,[ebx+0] // Загружаем значение из ebx в регистр al
mov ah,[ebx+2] // Загружаем значение из ebx+2 в регистр ah
mov [ebx+2],al // Сохраняем данные в al из ebx+2
mov [ebx+0],ah // Сохраняем данные в ah из ebx
add ebx,3 // Перемещаем указатель на три байта
dec ecx // Уменьшаем наш счётчик
jnz label // Если не равно нулю перемещаемся назад
}
}
void OpenAVI(LPCSTR szFile) // Вскрытие AVI файла (szFile)
{
TCHAR title[100]; // Будет содержать заголовок
AVIFileInit(); // Открывает файл
// Открытие AVI потока
if (AVIStreamOpenFromFile(&pavi, szFile, streamtypeVIDEO, 0, OF_READ, NULL) !=0)
{
// Если ошибка
MessageBox (HWND_DESKTOP, "Failed To Open The AVI Stream",
"Error", MB_OK | MB_ICONEXCLAMATION);
}
AVIStreamInfo(pavi, &psi, sizeof(psi)); // Записываем информацию о потоке в psi
width=psi.rcFrame.right-psi.rcFrame.left; // Ширина = правая граница минус левая
height=psi.rcFrame.bottom-psi.rcFrame.top;// Высота равна верх минус низ
lastframe=AVIStreamLength(pavi); // Последний кадр потока
// Вычисление приблизительных миллисекунд на кадр
mpf=AVIStreamSampleToTime(pavi,lastframe)/lastframe;
bmih.biPlanes = 1; // Размер
bmih.biBitCount = 24; // Формат битов
bmih.biWidth = 256; // Ширина(256 пикселов)
bmih.biHeight = 256; // Высота(256 пикселов)
bmih.biCompression = BI_RGB; // Цветовой режим (RGB)
hBitmap = CreateDIBSection (hdc, (BITMAPINFO*)(&bmih),
DIB_RGB_COLORS, (void**)(&data), NULL, NULL);
SelectObject (hdc, hBitmap); // Выбор hBitmap в наш контекст устройства (hdc)
pgf=AVIStreamGetFrameOpen(pavi, NULL); // Создание PGETFRAME с нужными нам параметрами
if (pgf==NULL)
{
// Если ошибка
MessageBox (HWND_DESKTOP, "Failed To Open The AVI Frame",
"Error", MB_OK | MB_ICONEXCLAMATION);
}
}
void GrabAVIFrame(int frames2) // Захват кадра
{
LPBITMAPINFOHEADER lpbi; // Содержит BitmapInfoHeader
// Получение данных из потока
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frames2);
// Указатель на данные возвращенные AVIStreamGetFrame
// (Пропуск заголовка для получения указателя на данные)
pdata=(char *)lpbi+lpbi->biSize+lpbi->biClrUsed * sizeof(RGBQUAD);
// Преобразование информации в нужный нам формат
DrawDibDraw (hdd, hdc, 0, 0, 256, 256, lpbi, pdata, 0, 0, width, height, 0);
// flipIt(data); // Перестановка красных и синих байтов
// Обновление текстуры
glTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
void CloseAVI(void) // Функция закрытия
{
DeleteObject(hBitmap); // Уничтожение устройства растра
DrawDibClose(hdd); // Закрытие контекста DrawDib устройства
AVIStreamGetFrameClose(pgf); // Закрытие объекта GetFrame
AVIStreamRelease(pavi); // Завершение потока
AVIFileExit(); // Закрытие файла
}
void Deinitialize (void) //Вся деиницилизация здесь
{
CloseAVI(); // Закрываем AVI
}