DirectX тормоза при масштабировании картинки
В общем возникла проблема.
Есть программа которая гонит видеопоток с нескольких камер в RGB32.
И отрисовывает каждый кадр. Т.е используется самописный рендерер. Работает хорошо НО.
Если область отображения близка по размерам к исходному фрейму, если же кадр 640 на 480 отрисовать на весь экран FPS падает с 25 до 2-3!
при этом загрузка процессора не растет
, такое впечатление что серьёзно задумывается видео карта. Особенно видно проблему если программа выводит изображение на 4 отдельных монитора. Загрузка процессора 30%, 4фпс, снижение разрешение уменьшает проблему но не снимает.
Скажите что я могу потенциально делать неправильно?
Или Какими функциями директХ лучше пользоваться для рендеринга маленьких картинок на всю площадь монитора (т.е чтоб их сразу и масштабировало), либо может какие то особенности видеокарты использовать карты GeForce последних моделей в основном.
Заранее спасибо.
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re: DirectX тормоза при масштабировании картинки
т.е я рисую полученные из семпл граббера кадры сам, без использования VMR9.
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re: DirectX тормоза при масштабировании картинки
На сколько использование Оверлеев может упростить жизнь? Или это не то?
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re: DirectX тормоза при масштабировании картинки
От:
8bit
Дата: 15.02.09 11:21
Оценка:
Здравствуйте, Aleksey Skurihin, Вы писали:
Вы через DirectX рисуете? Каким способом?
Re[2]: DirectX тормоза при масштабировании картинки
Здравствуйте, Aleksey Skurihin, Вы писали:
>> т.е я рисую полученные из семпл граббера кадры сам, без использования VMR9
не одного меня твой способ рисования озадачил. можно было бы и кусочек кода показать
AS>На сколько использование Оверлеев может упростить жизнь? Или это не то?
жизнь оно не упростит, но производительность поднимет. только это уже не direct show, а direct draw.
расскажу вкратце, как это было сделано у нас.
у нас картинка приходит с различной частотой из разных источников. приходит и остаётся в буфере. при этом выставляется соответствующий флажок на обновление. рисование на внеэкранной поверхности осуществляет отдельный поток, обладающий знанием о z-порядке буферов — ведь в случае обновления "нижней" картинки приходится вспомнить и про верхнюю. в итоге имеем источники с 2fps и 80fps, а отображение происходит со стабильной частотой 20-25fps, что положительно влияет на загрузку cpu (точней, частота отображения определяется наиболее активным источником, но не превосходит заданную границу).
Re[3]: DirectX тормоза при масштабировании картинки
CTH>не одного меня твой способ рисования озадачил. можно было бы и кусочек кода показать
Сейчас каждый кадр отрисовывается через DirectX поверхность, с ресайзом. После, накладывается текстура, содержащая элементы управления.
CTH>жизнь оно не упростит, но производительность поднимет. только это уже не direct show, а direct draw.
а директХ это ж, по идее более продвинутый вариант, почему он менее производительный?
CTH>расскажу вкратце, как это было сделано у нас.
CTH>у нас картинка приходит с различной частотой из разных источников. приходит и остаётся в буфере. при этом выставляется соответствующий флажок на обновление. рисование на внеэкранной поверхности осуществляет отдельный поток, обладающий знанием о z-порядке буферов — ведь в случае обновления "нижней" картинки приходится вспомнить и про верхнюю. в итоге имеем источники с 2fps и 80fps, а отображение происходит со стабильной частотой 20-25fps, что положительно влияет на загрузку cpu (точней, частота отображения определяется наиболее активным источником, но не превосходит заданную границу).
о спасибо, тут подумаю. Но сначала надо с первым вопросом разобраться.
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re: DirectX тормоза при масштабировании картинки
d3d_dev_->Clear( 0, NULL, D3DCLEAR_TARGET, aRenderer->bg_color_, 1.0f, 0 );
d3d_dev_->BeginScene();
d3d_dev_->EndScene();
HRESULT hr = d3d_dev_->Present( NULL, NULL, NULL, NULL );
пообрезал код, обнаружил что загрузка процессора растет при росте площади, хотя не должна, ведь сайзит то видяха. Т.е что то не так с этим директХ сайзом. Жаэе если я ничего реально не рисую вот этот блок грузит проц
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[2]: DirectX тормоза при масштабировании картинки
От:
8bit
Дата: 16.02.09 15:34
Оценка:
Здравствуйте, Aleksey Skurihin, Вы писали:
AS>Жаэе если я ничего реально не рисую вот этот блок грузит проц
Любой код грузит проц.
Адексей, покажите код которым вы рисуете и как загоняете данные.
через DirectX поверхность
Это что Вы под этим имеете ввиду? Через текстуру?
Re[3]: DirectX тормоза при масштабировании картинки
AS>>Жаэе если я ничего реально не рисую вот этот блок грузит проц
8>Любой код грузит проц.
Это да, но почему при большей области рендерера РАСТЕТ загрузка если реально ничего не рисуется.
8>Адексей, покажите код которым вы рисуете и как загоняете данные.
8>8> через DirectX поверхность
8>Это что Вы под этим имеете ввиду? Через текстуру?
RetStatus
VideoRenderer::RTSurface::DrawInProjection(
VideoRenderer* aRenderer, RECT* aSrcRect, RECT* aDestRect)
{
assert(aRenderer != 0);
if (surface_ ==0 )
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DSurface9* backBuf = 0;
if (device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuf) != D3D_OK)
{
return RS_ERR;
/*NOTREACHED*/
}
HRESULT hr;
hr = device->StretchRect(surface_, aSrcRect, backBuf, aDestRect, D3DTEXF_LINEAR);
if(D3D_OK != hr) {
hr = device->StretchRect(surface_, aSrcRect, backBuf, aDestRect, D3DTEXF_NONE);
}
backBuf->Release();
return hr == D3D_OK? RS_OK: RS_ERR;
}
RetStatus
VideoRenderer::RTTexture::DrawInProjection(
VideoRenderer* aRenderer, RECT* srcRect, RECT* destRect)
{
assert(aRenderer != 0);
if ((texture_ == 0) || (vert_buffer_ == 0))
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
HRESULT hr;
{
SquareVertexBuffer squareVerts=
{{
{(float )destRect->left, (float )destRect->top, 0.0f, 1.0f,
(float )(((double )srcRect->left + 0.5f) / texture_width_),
(float )(((double )srcRect->top + 0.5f) / texture_height_)},
{(float )destRect->right, (float )destRect->top, 0.0f, 1.0f,
(float )(((double )srcRect->right + 0.5f) / texture_width_),
(float )(((double )srcRect->top + 0.5f) / texture_height_)},
{(float )destRect->left, (float )destRect->bottom, 0.0f, 1.0f,
(float )(((double )srcRect->left + 0.5f) / texture_width_),
(float )(((double )srcRect->bottom + 0.5f) / texture_height_)},
{(float )destRect->right, (float )destRect->bottom, 0.0f, 1.0f,
(float )(((double )srcRect->right + 0.5f) / texture_width_),
(float )(((double )srcRect->bottom + 0.5f) / texture_height_)}
}};
void * pBuf;
hr = vert_buffer_->Lock(0, sizeof (squareVerts), &pBuf, 0);
if (D3D_OK == hr) {
memcpy(pBuf, &squareVerts, sizeof (squareVerts));
vert_buffer_->Unlock();
} else {
return hr == D3D_OK? RS_OK: RS_ERR;
//NOTREACHED
}
}
hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, TRIANGLES_COUNT);
return hr == D3D_OK? RS_OK: RS_ERR;
}
ниже привожу, на всякий случай, файл целиком, там основа чужая и какая то горбатая, вот сижу разбираюсь пока шефы по голове стучат
думаю может проще все сделать проще но хочу понять НА ЧЕМ и КАК делать то надо. потому что при отображении видео на втором мониторе (если монитров два) уже приводит к тормозам. На крутом серваке запутсил загрузка вообще около 5% и фпс такойже...
не могу понять куда копать, думаю что неправильная идея в целом... но почему?
//
// -*- Mode: c++; tab-width: 4; -*-
// -*- ex: ts=4 -*-
//
//
// Copyright 2007 VIT Ltd. All rights reserved.
// VIT PROPRIETARY/CONFIDENTIAL.
//
// $Id$
//
#ifdef _DEBUG
# define D3D_DEBUG_INFO
#endif
#define MULTITHREADED_D3D
#ifdef MULTITHREADED_D3D
# define _D3DDEV_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED)
#else
# define _D3DDEV_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING)
#endif
#include <Vombat/VideoRenderer.h>
#include <assert.h>
#include "include/VResWin32Lib.h"
using namespace std;
namespace VR
{
/////////
VideoRenderer::VRResource::VRResource()
{
}
VideoRenderer::VRResource::~VRResource()
{
}
/////////
VideoRenderer::ProjectableResource::ProjArray::iterator
VideoRenderer::ProjectableResource::FindProjection(ProjectionID aProjID)
{
ProjArray::iterator curRes;
for (curRes = projections_.begin(); curRes != projections_.end(); ++curRes)
{
if (curRes->proj_id_ == aProjID)
{
return curRes;
/*NOTREACHED*/
}
}
return curRes;
}
RetStatus
VideoRenderer::ProjectableResource::controlResource(
VideoRenderer* aRenderer, ControlStruct* aControlStruct)
{
ProjArray::iterator curProj;
assert(aRenderer != 0);
assert(aControlStruct != 0);
switch (aControlStruct->code_)
{
case (VR_CC_SET_PROJECTION_RECTS):
{
cmdSetProjectionRects* setRects = (cmdSetProjectionRects*)aControlStruct;
curProj = FindProjection(setRects->projection_);
if (curProj != projections_.end())
{
projections_.erase(curProj);
}
ProjDesc projDesc;
projDesc.proj_id_ = setRects->projection_;
projDesc.is_dest_valid_ = false ;
if (setRects->dest_rect_ != 0)
{
projDesc.is_dest_valid_ = true ;
projDesc.dest_rect_ = *setRects->dest_rect_;
}
projDesc.is_src_valid_ = false ;
if (setRects->src_rect_ != 0)
{
projDesc.is_src_valid_ = true ;
projDesc.src_rect_ = *setRects->src_rect_;
}
projections_.push_back(projDesc);
return RS_OK;
/*NOTREACHED*/
}
case (VR_CC_DELETE_PROJECTION):
curProj = FindProjection(((cmdDeleteProjection*)aControlStruct)->projection_);
if (curProj == projections_.end())
{
return RS_ERR;
/*NOTREACHED*/
}
projections_.erase(curProj);
return RS_OK;
/*NOTREACHED*/
default :
return controlProjectedResource(aRenderer, aControlStruct);
/*NOTREACHED*/
}
return RS_OK;
}
RetStatus
VideoRenderer::ProjectableResource::ApplyToScene(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
if (projections_.empty())
{
return RS_OK;
/*NOTREACHED*/
}
RetStatus rs = BeforeDraw(aRenderer);
if (rs != RS_OK)
{
return rs;
/*NOTREACHED*/
}
ProjArray::iterator curProj;
for (curProj = projections_.begin(); curProj != projections_.end(); ++curProj)
{
RECT srcRect, destRect;
if (curProj->is_dest_valid_)
{
destRect = curProj->dest_rect_;
}
else
{
//aRenderer->getDeviceSize(&destRect);
//GetWindowRect
GetClientRect
(aRenderer->hwnd_, &destRect);
destRect.right -= destRect.left;
destRect.bottom -= destRect.top;
destRect.left = destRect.top = 0;
}
if (curProj->is_src_valid_)
{
srcRect = curProj->src_rect_;
}
else
{
cmdGetImageType imgType;
if (controlProjectedResource(aRenderer, &imgType) != RS_OK)
continue ;
/*NOTREACHED*/
srcRect.left = srcRect.top = 0;
srcRect.right = imgType.width_;
srcRect.bottom = imgType.height_;
}
{
cmdGetImageType imgType;
if (RS_OK == controlProjectedResource(aRenderer, &imgType))
{
if (D3DFMT_UYVY == imgType.format_ || D3DFMT_YUY2 == imgType.format_)
{
srcRect.left -= srcRect.left % 2;
srcRect.right -= srcRect.right % 2;
}
}
}
DrawInProjection(aRenderer, &srcRect, &destRect);
}
return AfterDraw(aRenderer);
}
/////////
#define UNDEFINED_SURF_PARAM ((ImgFormat)-1)
VideoRenderer::AbstractImage::AbstractImage()
: img_draw_proc_(0)
, format_(UNDEFINED_SURF_PARAM)
{
}
RetStatus
VideoRenderer::AbstractImage::CallCallback(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
ResID curID;
if (!aRenderer->getResourceID(this , curID))
{
return RS_ERR;
/*NOTREACHED*/
}
if (img_draw_proc_ != 0)
img_draw_proc_(aRenderer, curID, proc_param_);
return RS_OK;
}
RetStatus
VideoRenderer::AbstractImage::controlProjectedResource(
VideoRenderer* aRenderer, ControlStruct* controlStruct)
{
assert(aRenderer != 0);
switch (controlStruct->code_)
{
case (VR_CC_SET_IMAGE_TYPE):
{
cmdSetImageType* imgType = (cmdSetImageType*)controlStruct;
if ((format_ == imgType->format_) &&
(width_ == imgType->width_) &&
(height_ == imgType->height_) &&
(format_ != UNDEFINED_SURF_PARAM) &&
isRestored()
)
{
return RS_OK;
/*NOTREACHED*/
}
freeResources();
format_ = imgType->format_;
width_ = imgType->width_;
height_ = imgType->height_;
return restoreResource(aRenderer);
/*NOTREACHED*/
}
case (VR_CC_GET_IMAGE_TYPE):
{
if (format_ == (ImgFormat)UNDEFINED_SURF_PARAM)
return RS_ERR;
/*NOTREACHED*/
cmdGetImageType* imgType = (cmdGetImageType*)controlStruct;
imgType->format_ = format_;
imgType->width_ = width_;
imgType->height_ = height_;
return RS_OK;
/*NOTREACHED*/
}
case (VR_CC_LOCK_IMAGE):
{
cmdLockImage* cmdLock = (cmdLockImage*)controlStruct;
RetStatus rs;
cmdLock->p_bits_ = 0;
RECT allImgRect;
allImgRect.left = allImgRect.top = 0;
allImgRect.right = width_;
allImgRect.bottom = height_;
RECT* lockRect = &allImgRect;
if (cmdLock->lock_rect_ != 0)
{
lockRect = cmdLock->lock_rect_;
}
rs = LockImageProc(lockRect, &cmdLock->pitch_, &cmdLock->p_bits_);
if (rs != RS_OK)
{
return rs;
/*NOTREACHED*/
}
return RS_OK;
/*NOTREACHED*/
}
case (VR_CC_UNLOCK_IMAGE):
{
RetStatus rs;
rs = UnlockImageProc();
return rs;
/*NOTREACHED*/
}
case (VR_CC_SET_IMG_DRAW_PROC):
{
img_draw_proc_ = ((cmdSetImgDrawProc*)controlStruct)->draw_proc_;
proc_param_ = ((cmdSetImgDrawProc*)controlStruct)->proc_param_;
return RS_OK;
/*NOTREACHED*/
}
default :
return RS_NOTIMPLEMENTED;
/*NOTREACHED*/
}
return RS_OK;
}
//////////
bool
VideoRenderer::RTGDIImage::isRestored()
{
return (NULL != compatible_dc_) && (NULL != dib_section_);
}
VideoRenderer::RTGDIImage::RTGDIImage(bool hasAlpha)
{
RTGDIImage();
has_alpha_ = hasAlpha;
}
VideoRenderer::RTGDIImage::RTGDIImage()
:compatible_dc_(0), dib_section_(0),prev_bitmap_(0), img_data_(0)
{
unlock_called_ = false ;
}
RetStatus
VideoRenderer::RTGDIImage::BeforeDraw(VideoRenderer* aRenderer)
{
return RS_OK;
}
RetStatus
VideoRenderer::RTGDIImage::AfterDraw(VideoRenderer* aRenderer)
{
return RS_OK;
}
RetStatus
VideoRenderer::RTGDIImage::DrawInProjection(
VideoRenderer* aRenderer, RECT* aSrcRect, RECT* aDestRect)
{
assert(aRenderer != 0);
if (NULL == compatible_dc_ || NULL == dib_section_)
{
return RS_ERR;
/*NOTREACHED*/
}
HDC wndDC = ((HWStateGDI*)aRenderer->current_state_)->mem_dc_;
SetStretchBltMode(wndDC, HALFTONE);
if (has_alpha_)
{
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xFF;
bf.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(
wndDC,
aDestRect->left, aDestRect->top, aDestRect->right - aDestRect->left, aDestRect->bottom - aDestRect->top,
compatible_dc_,
aSrcRect->left, aSrcRect->top, aSrcRect->right - aSrcRect->left, aSrcRect->bottom - aSrcRect->top,
bf
);
}
else
{
StretchBlt(
wndDC,
aDestRect->left, aDestRect->top, aDestRect->right - aDestRect->left, aDestRect->bottom - aDestRect->top,
compatible_dc_,
aSrcRect->left, aSrcRect->top, aSrcRect->right - aSrcRect->left, aSrcRect->bottom - aSrcRect->top,
SRCCOPY
);
}
return RS_OK;
}
RetStatus
VideoRenderer::RTGDIImage::restoreResource(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
if (compatible_dc_ != 0 && dib_section_ != 0)
{
if (!unlock_called_) {
CallCallback(aRenderer);
}
return RS_OK;
/*NOTREACHED*/
}
freeResources();
if (D3DFMT_A8R8G8B8 != format_) {
return RS_ERR;
}
compatible_dc_ = CreateCompatibleDC(0);
if (compatible_dc_ == 0)
return RS_ERR;
BITMAPINFO bmi;
bmi.bmiHeader.biSize = sizeof (bmi.bmiHeader);
bmi.bmiHeader.biWidth = (LONG)width_;
bmi.bmiHeader.biHeight = -(LONG)height_;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32; //@todo:
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
dib_section_ = CreateDIBSection(compatible_dc_, &bmi, DIB_RGB_COLORS, &img_data_, NULL, 0);
prev_bitmap_ = SelectObject(compatible_dc_, (HGDIOBJ)dib_section_);
return CallCallback(aRenderer);
}
RetStatus
VideoRenderer::RTGDIImage::LockImageProc(RECT *aLockRect, int *aPitch, void **apBits)
{
if (img_data_ == 0)
{
return RS_ERR;
/*NOTREACHED*/
}
*aPitch = width_ * 4; //@todo:
*apBits = img_data_;
return RS_OK;
}
RetStatus
VideoRenderer::RTGDIImage::UnlockImageProc()
{
if (img_data_ == 0)
{
return RS_ERR;
/*NOTREACHED*/
}
unlock_called_ = true ;
return RS_OK;
}
VideoRenderer::RTGDIImage::~RTGDIImage()
{
freeResources();
}
void
VideoRenderer::RTGDIImage::freeResources()
{
unlock_called_ = false ;
if (compatible_dc_){
SelectObject(compatible_dc_, prev_bitmap_);
if (dib_section_) {
DeleteObject(dib_section_);
dib_section_ = 0;
}
DeleteObject(compatible_dc_);
compatible_dc_ = 0;
}
}
////////////
bool
VideoRenderer::RTSurface::isRestored()
{
return surface_ != 0;
}
VideoRenderer::RTSurface::RTSurface()
:surface_(0)
{
unlock_called_ = false ;
}
RetStatus
VideoRenderer::RTSurface::BeforeDraw(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
IDirect3DDevice9* device;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
return RS_OK;
}
RetStatus
VideoRenderer::RTSurface::AfterDraw(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
return RS_OK;
}
RetStatus
VideoRenderer::RTSurface::DrawInProjection(
VideoRenderer* aRenderer, RECT* aSrcRect, RECT* aDestRect)
{
assert(aRenderer != 0);
if (surface_ ==0 )
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DSurface9* backBuf = 0;
if (device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuf) != D3D_OK)
{
return RS_ERR;
/*NOTREACHED*/
}
HRESULT hr;
hr = device->StretchRect(surface_, aSrcRect, backBuf, aDestRect, D3DTEXF_LINEAR);
if (D3D_OK != hr) {
hr = device->StretchRect(surface_, aSrcRect, backBuf, aDestRect, D3DTEXF_NONE);
}
backBuf->Release();
return hr == D3D_OK? RS_OK: RS_ERR;
}
RetStatus
VideoRenderer::RTSurface::restoreResource(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
if (surface_ != 0)
{
if (!unlock_called_) {
CallCallback(aRenderer);
}
return RS_OK;
/*NOTREACHED*/
}
freeResources();
if (UNDEFINED_SURF_PARAM == format_)
{
return RS_ERR;
}
IDirect3DSurface9* newSurf;
HRESULT hr = device->CreateOffscreenPlainSurface(
width_,
height_,
(D3DFORMAT)format_,
D3DPOOL_DEFAULT,
&newSurf,
0
);
if (hr != D3D_OK)
return RS_ERR;
surface_ = newSurf;
return CallCallback(aRenderer);
}
RetStatus
VideoRenderer::RTSurface::LockImageProc(RECT *aLockRect, int *aPitch, void **apBits)
{
if (surface_ == 0)
{
return RS_ERR;
/*NOTREACHED*/
}
D3DLOCKED_RECT lockedRect;
if (surface_->LockRect(&lockedRect, aLockRect, D3DLOCK_DISCARD) != D3D_OK)
{
return RS_ERR;
/*NOTREACHED*/
}
*aPitch = lockedRect.Pitch;
*apBits = lockedRect.pBits;
return RS_OK;
}
RetStatus
VideoRenderer::RTSurface::UnlockImageProc()
{
if (surface_ == 0)
{
return RS_ERR;
/*NOTREACHED*/
}
unlock_called_ = true ;
surface_->UnlockRect();
return RS_OK;
}
VideoRenderer::RTSurface::~RTSurface()
{
freeResources();
}
void
VideoRenderer::RTSurface::freeResources()
{
unlock_called_ = false ;
RELEASE_COM_OBJ(surface_);
}
///////////////////
bool
VideoRenderer::RTTexture::isRestored()
{
return ((texture_ != 0) && (vert_buffer_ != 0));
}
VideoRenderer::RTTexture::RTTexture()
:texture_(0)
,vert_buffer_(0)
{
unlock_called_ = false ;
}
struct TexVertex_
{
float x,y,z, rh;
float tu,tv;
};
typedef TexVertex_ CurVertFmt;
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)
struct SquareVertexBuffer
{
CurVertFmt corners_[4];
};
#define VERTS_COUNT 4
#define TRIANGLES_COUNT 2
RetStatus
VideoRenderer::RTTexture::BeforeDraw(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
if ((texture_ == 0) || (vert_buffer_ == 0))
{
return RS_ERR;
/*NOTREACHED*/
}
device->SetStreamSource(0, vert_buffer_, 0, sizeof (CurVertFmt));
device->SetTexture(0, texture_);
return RS_OK;
}
RetStatus
VideoRenderer::RTTexture::AfterDraw(VideoRenderer* aRenderer)
{
assert(aRenderer != 0);
return RS_OK;
}
RetStatus
VideoRenderer::RTTexture::DrawInProjection(
VideoRenderer* aRenderer, RECT* srcRect, RECT* destRect)
{
assert(aRenderer != 0);
if ((texture_ == 0) || (vert_buffer_ == 0))
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
HRESULT hr;
{
SquareVertexBuffer squareVerts=
{{
{(float )destRect->left, (float )destRect->top, 0.0f, 1.0f,
(float )(((double )srcRect->left + 0.5f) / texture_width_),
(float )(((double )srcRect->top + 0.5f) / texture_height_)},
{(float )destRect->right, (float )destRect->top, 0.0f, 1.0f,
(float )(((double )srcRect->right + 0.5f) / texture_width_),
(float )(((double )srcRect->top + 0.5f) / texture_height_)},
{(float )destRect->left, (float )destRect->bottom, 0.0f, 1.0f,
(float )(((double )srcRect->left + 0.5f) / texture_width_),
(float )(((double )srcRect->bottom + 0.5f) / texture_height_)},
{(float )destRect->right, (float )destRect->bottom, 0.0f, 1.0f,
(float )(((double )srcRect->right + 0.5f) / texture_width_),
(float )(((double )srcRect->bottom + 0.5f) / texture_height_)}
}};
void * pBuf;
hr = vert_buffer_->Lock(0, sizeof (squareVerts), &pBuf, 0);
if (D3D_OK == hr) {
memcpy(pBuf, &squareVerts, sizeof (squareVerts));
vert_buffer_->Unlock();
} else {
return hr == D3D_OK? RS_OK: RS_ERR;
//NOTREACHED
}
}
hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, TRIANGLES_COUNT);
return hr == D3D_OK? RS_OK: RS_ERR;
}
RetStatus
VideoRenderer::RTTexture::restoreResource(VideoRenderer* aRenderer)
{
IDirect3DDevice9* device = 0;
if (RS_OK != ((HWStateDirctX*)(aRenderer->getCurrentState()))->getD3DDevice(&device))
{
return RS_ERR;
/*NOTREACHED*/
}
if (texture_ != 0)
{
if (!unlock_called_)
{
CallCallback(aRenderer);
}
return RS_OK;
/*NOTREACHED*/
}
freeResources();
IDirect3DTexture9* Texture = 0;
if (UNDEFINED_SURF_PARAM == format_)
{
return RS_ERR;
}
if (D3DXCreateTexture(device, width_, height_, 1, 0,
format_, D3DPOOL_MANAGED, &Texture) != D3D_OK)
{
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DSurface9* surf;
Texture->GetSurfaceLevel(0,&surf);
D3DSURFACE_DESC desc;
surf->GetDesc(&desc);
surf->Release();
texture_width_ = desc.Width;
texture_height_ = desc.Height;
if (desc.Format != format_)
{
RELEASE_COM_OBJ(Texture);
return RS_ERR;
/*NOTREACHED*/
}
IDirect3DVertexBuffer9* vertBuffer = 0;
if (device->CreateVertexBuffer(
sizeof (SquareVertexBuffer),
0,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,
&vertBuffer,
0
) != D3D_OK)
{
RELEASE_COM_OBJ(Texture);
return RS_ERR;
/*NOTREACHED*/
}
vert_buffer_ = vertBuffer;
texture_ = Texture;
return CallCallback(aRenderer);
}
RetStatus
VideoRenderer::RTTexture::LockImageProc(RECT *lockRect, int *pitch, void **pBits)
{
if (texture_ == 0)
{
return RS_ERR;
/*NOTREACHED*/
}
D3DLOCKED_RECT lockedRect;
if (texture_->LockRect(0,&lockedRect, lockRect, 0) != S_OK)
{
return RS_ERR;
/*NOTREACHED*/
}
*pitch = lockedRect.Pitch;
*pBits = lockedRect.pBits;
return RS_OK;
}
RetStatus
VideoRenderer::RTTexture::UnlockImageProc()
{
if (0 == texture_)
return RS_ERR;
unlock_called_ = true ;
texture_->UnlockRect(0);
return RS_OK;
}
VideoRenderer::RTTexture::~RTTexture()
{
freeResources();
}
void
VideoRenderer::RTTexture::freeResources()
{
unlock_called_ = false ;
RELEASE_COM_OBJ(texture_);
RELEASE_COM_OBJ(vert_buffer_);
}
///////////////////////
#define D3D_MSG (WM_USER + 13)
LRESULT CALLBACK D3DCreateProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
RendererState state = RST_NOTPRESENT;
if (uMsg != D3D_MSG)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof (d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.hDeviceWindow = hwnd;
IDirect3D9* d3d9 = (IDirect3D9*)wParam;
IDirect3DDevice9** device = (IDirect3DDevice9**)lParam;
assert(d3d9 != 0);
assert(device != 0);
RECT tstRect;
GetClientRect(hwnd,&tstRect);
*device = 0;
if (D3D_OK ==
d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
_D3DDEV_FLAGS,
&d3dpp,
device
)
){
state = RST_HAL;
}
else
{
state =
D3D_OK == d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF,
hwnd,
_D3DDEV_FLAGS,
&d3dpp,
device
) ? RST_REF : RST_NOTPRESENT;
}
IDirect3DDevice9* tst = *device;
return state;
}
VideoRenderer::HWStateDirctX::HWStateDirctX():
d3d_(0),
d3d_dev_(0)
{
#ifdef MULTITHREADED_D3D
# define COM_INIT COINIT_MULTITHREADED
#else
# define COM_INIT COINIT_APARTMENTTHREADED
#endif
coinited_ = SUCCEEDED(CoInitializeEx(0, COM_INIT));
if (coinited_)
{
d3d_ = Direct3DCreate9(D3D_SDK_VERSION);
}
}
VideoRenderer::HWStateDirctX::~HWStateDirctX()
{
fini();
RELEASE_COM_OBJ(d3d_);
if (coinited_){
CoUninitialize();
}
}
RetStatus VideoRenderer::HWStateDirctX::init(HWND hWnd)
{
if (d3d_ == 0 || !coinited_)
{
return RS_ERR;
/*NOTREACHED*/
}
if (!IsWindow(hWnd))
{
return RS_ERR;
/*NOTREACHED*/
}
RECT clientRect;
GetClientRect(hWnd, &clientRect);
fini();
d3d_dev_ = 0;
//#ifdef MULTITHREADED_D3D
RendererState state = (RendererState)D3DCreateProc(hWnd, D3D_MSG, (WPARAM)d3d_, (LPARAM)&d3d_dev_);
//#else //переключение в поток окна.
// LONG prevProc = SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&D3DCreateProc);
// RendererState state = (RendererState)SendMessage(hWnd, D3D_MSG, (WPARAM)d3d_, (LPARAM)&d3d_dev_);
// SetWindowLong(hWnd, GWL_WNDPROC, prevProc);
//#endif
if (NULL == d3d_dev_ || RST_HAL != state)
{
fini();
return RS_ERR;
/*NOTREACHED*/
}
return RS_OK;
}
void VideoRenderer::HWStateDirctX::fini()
{
RELEASE_COM_OBJ(d3d_dev_);
}
RendererState VideoRenderer::HWStateDirctX::getState(){
return RST_HAL;
}
RetStatus VideoRenderer::HWStateDirctX::getD3DDevice(IDirect3DDevice9** aDevice)
{
assert (0 != aDevice);
*aDevice = d3d_dev_;
if (NULL == d3d_dev_)
{
return RS_NODEVICE;
/*NOTREACHED*/
}
return RS_OK;
}
RetStatus VideoRenderer::HWStateDirctX::draw(VideoRenderer* aRenderer)
{
if (NULL == d3d_dev_)
{
return RS_ERR;
}
RetStatus result = RS_OK;
VideoRenderer::ResArray::iterator curRes;
d3d_dev_->Clear( 0, NULL, D3DCLEAR_TARGET, aRenderer->bg_color_, 1.0f, 0 );
d3d_dev_->BeginScene();
d3d_dev_->SetFVF(D3DFVF_CUSTOMVERTEX);
// d3d_dev_->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
d3d_dev_->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
d3d_dev_->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
d3d_dev_->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
// device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
for (curRes = aRenderer->res_array_.begin(); curRes != aRenderer->res_array_.end(); ++curRes)
{
if (NULL != curRes->resource_)
{
result = curRes->resource_->restoreResource(aRenderer);
if (result != RS_OK)
{
break ;
/*NOTREACHED*/
}
result = curRes->resource_->ApplyToScene(aRenderer);
if (result != RS_OK)
{
break ;
/*NOTREACHED*/
}
}
}
d3d_dev_->EndScene();
{
HRESULT hr = d3d_dev_->Present( NULL, NULL, NULL, NULL );
result = D3D_OK == hr && RS_OK == result ? RS_OK : RS_ERR; //D3DERR_DEVICELOST
}
return result;
}
VideoRenderer::VRResource* VideoRenderer::HWStateDirctX::createResource(ResourceType aType)
{
switch (aType)
{
case (RT_OPAQUE_SURF):
return new RTSurface;
/*NOTREACHED*/
case (RT_TRANSPARENT_SURF):
return new RTTexture;
/*NOTREACHED*/
default :
return NULL;
/*NOTREACHED*/
}
return NULL;
}
//////////////////
VideoRenderer::HWStateGDI::HWStateGDI()
{
}
VideoRenderer::HWStateGDI::~HWStateGDI()
{
}
RetStatus VideoRenderer::HWStateGDI::init(HWND hWnd)
{
if (!IsWindow(hWnd))
{
return RS_ERR;
/*NOTREACHED*/
}
RECT clientRect;
GetClientRect(hWnd, &clientRect);
fini();
HDC wndDC = GetDC(hWnd);
mem_dc_ = CreateCompatibleDC(wndDC);
HBITMAP bitmap_ = CreateCompatibleBitmap(wndDC, clientRect.right, clientRect.bottom);
prev_bitmap_ = SelectObject(mem_dc_, bitmap_);
ReleaseDC(hWnd, wndDC);
return RS_OK;
}
void VideoRenderer::HWStateGDI::fini()
{
if (NULL != prev_bitmap_) {
SelectObject(mem_dc_, prev_bitmap_);
}
DeleteObject(bitmap_);
DeleteDC(mem_dc_);
}
RendererState VideoRenderer::HWStateGDI::getState(){
return RST_REF;
}
RetStatus VideoRenderer::HWStateGDI::draw(VideoRenderer* aRenderer)
{
RetStatus result = RS_OK;
RECT rect;
GetClientRect(aRenderer->hwnd_, &rect);
{
HBRUSH hbr = VCreateSolidBrush(aRenderer->bg_color_, NULL);
FillRect(mem_dc_, &rect, hbr);
VUnLoadHandle(hbr);
}
for (
ResArray::iterator curRes = aRenderer->res_array_.begin();
curRes != aRenderer->res_array_.end();
++curRes
)
{
result = curRes->resource_->restoreResource(aRenderer);
if (result != RS_OK)
{
break ;
/*NOTREACHED*/
}
result = curRes->resource_->ApplyToScene(aRenderer);
if (result != RS_OK)
{
break ;
/*NOTREACHED*/
}
}
{
HDC wndDC = GetDC(aRenderer->hwnd_);
BitBlt(
wndDC,
rect.left, rect.top, rect.right, rect.bottom,
mem_dc_,
0, 0,
SRCCOPY
);
ReleaseDC(aRenderer->hwnd_, wndDC);
}
return result;
}
VideoRenderer::VRResource* VideoRenderer::HWStateGDI::createResource(ResourceType aType)
{
if (RT_OPAQUE_SURF == aType)
{
return new RTGDIImage(false );
/*NOTREACHED*/
}else if (RT_TRANSPARENT_SURF == aType)
{
return new RTGDIImage(true );
/*NOTREACHED*/
}
return NULL;
}
//////////////////
VideoRenderer::HWStateNULL::~HWStateNULL(){
}
RetStatus VideoRenderer::HWStateNULL::init(HWND hwnd){
return RS_OK;
}
void VideoRenderer::HWStateNULL::fini(){}
RetStatus VideoRenderer::HWStateNULL::draw(VideoRenderer* aRenderer)
{
return RS_OK;
}
VideoRenderer::VRResource* VideoRenderer::HWStateNULL::createResource(ResourceType aType)
{
return NULL;
}
RendererState VideoRenderer::HWStateNULL::getState(){
return RST_NOTPRESENT;
}
//////////////////
VideoRenderer::VideoRenderer()
:hwnd_(0)
, bg_color_(VR_RGB_COLOR(0,0,0))
{
current_state_ = new HWStateNULL;
}
VideoRenderer::~VideoRenderer()
{
current_state_->fini();
while (!res_array_.empty())
{
deleteResource(res_array_.begin()->res_id_);
}
delete current_state_;
}
void
VideoRenderer::freeObj()
{
ResArray::iterator curRes;
for (curRes = res_array_.begin(); curRes != res_array_.end(); ++curRes)
{
if (NULL != curRes->resource_){
delete curRes->resource_;
}
curRes->resource_ = NULL;
}
current_state_->fini();
delete current_state_;
current_state_ = new HWStateNULL;
// hwnd_ = 0;
}
//переинициализация устройств. должна быть синхронизирована с вызовами ф-ций работы с устройствами.
RetStatus
VideoRenderer::setWindow(HWND hWnd)
{
if (!IsWindow(hWnd))
{
return RS_ERR;
/*NOTREACHED*/
}
RECT clientRect;
GetClientRect(hWnd, &clientRect);
if ((hwnd_ == hWnd) && (clientRect.right == wnd_width_) && (clientRect.bottom == wnd_height_))
{
return RS_OK;
/*NOTREACHED*/
}
return absSetWindow(hWnd);
}
RetStatus
VideoRenderer::absSetWindow(HWND hWnd)
{
if (!IsWindow(hWnd))
{
return RS_ERR;
/*NOTREACHED*/
}
RECT clientRect;
GetClientRect(hWnd, &clientRect);
RetStatus status = RS_ERR;
CurrentHWState* newstate = new HWStateDirctX;
status = newstate->init(hWnd);
if (RS_OK != status)
{
newstate->fini();
delete newstate;
newstate = new HWStateGDI;
status = newstate->init(hWnd);
if (RS_OK != status)
{
newstate->fini();
delete newstate;
newstate = new HWStateNULL;
/*status =*/ newstate->init(hWnd);
}
}
{
if (RS_OK == status)
{
if (newstate->getState() != current_state_->getState())
{ //пересоздать
freeObj();
for (ResArray::iterator curRes = res_array_.begin(); curRes != res_array_.end(); curRes++)
{
curRes->resource_ = newstate->createResource(curRes->res_type_);
}
}else
{ //восстанвоить.
ResArray::iterator curRes;
for (curRes = res_array_.begin(); curRes != res_array_.end(); ++curRes)
{
if (NULL == curRes->resource_)
{
curRes->resource_ = newstate->createResource(curRes->res_type_);
}
if (NULL != curRes->resource_){
curRes->resource_->freeResources();
// curRes->resource_->restoreResource(this);
}
// curRes->resource_ = NULL;
}
}
}
current_state_->fini();
delete current_state_;
current_state_ = newstate;
if (RS_OK == status){
hwnd_ = hWnd;
wnd_width_ = clientRect.right;
wnd_height_ = clientRect.bottom;
} else {
hwnd_ = 0;
wnd_width_ = wnd_height_ = 0;
}
}
return status;
}
RetStatus
VideoRenderer::setBgColor(ColorID BGColor)
{
bg_color_ = BGColor;
return RS_OK;
}
RetStatus
VideoRenderer::draw()
{
RetStatus status = current_state_->draw(this );
if (RS_OK == status)
{
return RS_OK;
}
absSetWindow(hwnd_); //reinit renderer
return current_state_->draw(this );
//}
//else
//{
// for(curRes = res_array_.begin(); curRes != res_array_.end(); ++curRes)
// {
// RetStatus rs = curRes->resource_->restoreResource(this);
// if (rs != RS_OK)
// {
// continue;
// /*NOTREACHED*/
// }
// rs = curRes->resource_->ApplyToScene(this);
// }
//}
//return RS_OK;
}
//RetStatus
//VideoRenderer::getDeviceSize(RECT* aDeviceRect)
//{
// assert(0 != aDeviceRect);
// if (d3d_dev_ == 0)
// {
// return RS_NODEVICE;
// /*NOTREACHED*/
// }
//
// aDeviceRect->left = aDeviceRect->top = 0;
// aDeviceRect->right = wnd_width_;
// aDeviceRect->bottom = wnd_height_;
//
//#ifdef _DEBUG
// {
// RECT clientRect;
// GetClientRect(hwnd_, &clientRect);
// if(0 != memcmp(aDeviceRect, &clientRect, sizeof(RECT)))
// {
// DebugBreak();
// //если aDeviceRect постоянно некоректный, - где-то баг.
// return RS_ERR;
// }
// }
//#endif
//
// return RS_OK;
//}
RendererState VideoRenderer::getState()
{
return current_state_->getState();
}
VideoRenderer::ResArray::iterator
VideoRenderer::FindResource(ResID aResID)
{
ResArray::iterator curRes;
for (curRes = res_array_.begin(); curRes != res_array_.end(); ++curRes)
{
if (curRes->res_id_ == aResID)
{
return curRes;
/*NOTREACHED*/
}
}
return curRes;
}
RetStatus
VideoRenderer::createResource(ResID aCallerResID, ResourceType aType)
{
ResArray::iterator curRes;
curRes = FindResource(aCallerResID);
if (curRes != res_array_.end())
{
if (curRes->res_type_ == aType)
{
return RS_OK;
/*NOTREACHED*/
}
res_array_.erase(curRes);
}
VRResource* resource = current_state_->createResource(aType);
// if(NULL != resource) {
res_array_.push_back(
ResDesc(
aCallerResID,
aType,
resource
)
);
// }
return NULL != resource ? RS_OK :RS_ERR;
}
RetStatus
VideoRenderer::controlResource(ResID aCallerResID, ControlStruct* aControlStruct)
{
assert(0 != aControlStruct);
ResArray::iterator curRes;
curRes = FindResource(aCallerResID);
if (curRes == res_array_.end() || NULL == curRes->resource_)
{
return RS_ERR;
/*NOTREACHED*/
}
return curRes->resource_->controlResource(this , aControlStruct);
}
RetStatus
VideoRenderer::deleteResource(ResID aCallerResID)
{
ResArray::iterator curRes;
curRes = FindResource(aCallerResID);
if (curRes == res_array_.end())
{
return RS_ERR;
/*NOTREACHED*/
}
if (NULL != curRes->resource_)
{
delete curRes->resource_;
}
res_array_.erase(curRes);
return RS_OK;
}
RetStatus
VideoRenderer::bringToFrontResource(ResID aCallerResID)
{
ResArray::iterator curRes;
curRes = FindResource(aCallerResID);
if (curRes == res_array_.end())
{
return RS_ERR;
/*NOTREACHED*/
}
res_array_.push_back(*curRes);
res_array_.erase(FindResource(aCallerResID));
return RS_OK;
}
bool
VideoRenderer::getResourceID(VRResource* aResource, ResID& aResId)
{
ResArray::iterator curRes;
for (curRes = res_array_.begin(); curRes != res_array_.end(); ++curRes)
{
if (curRes->resource_ == aResource)
{
aResId = curRes->res_id_;
return true ;
/*NOTREACHED*/
}
}
return false ;
}
} // namespace VR
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[4]: DirectX тормоза при масштабировании картинки
От:
8bit
Дата: 17.02.09 10:42
Оценка:
Здравствуйте, Aleksey Skurihin, Вы писали:
При отрисовке с помощью текстуры есть падение fps?
У StretchRect есть ограничения
http://msdn.microsoft.com/en-us/library/bb174471(VS.85).aspx
смотрите таблицу Direct3D 9 Driver (stretching)
У вас получается (могу ошибаться)
Src format: Off-screen plain (ваша поверхность с видео данными)
Dst format: Off-screen plain (Back buffer)
Попробуйте создать свой render target, текущий запомнить, выставить свой,
сделать в него StretchRect видео, отрисовать все остальное, потом выставить назад родной
render target и в него сделать StretchRect своего render target в оригинальный, один к одному без фильтров (D3DTEXF_NONE).
По типу такого
http://www.gamedev.net/reference/articles/article2585.asp
Еще можно попробовать использовать две поверхности и чередовать их.
Т.е у вас будет surface_1 и surface_2.
Аналогично и при отрисовке текстурой, тоже можно их две иметь и чередовать.
Еще можно попробовать обновить драйвера
Вот это не надо делать на каждый фрейм, только если у вас меняются значения.
AS>AS> HRESULT hr;
AS> {
AS> SquareVertexBuffer squareVerts=
AS> {{
AS> {(float )destRect->left, (float )destRect->top, 0.0f, 1.0f,
AS> (float )(((double )srcRect->left + 0.5f) / texture_width_),
AS> (float )(((double )srcRect->top + 0.5f) / texture_height_)},
AS> {(float )destRect->right, (float )destRect->top, 0.0f, 1.0f,
AS> (float )(((double )srcRect->right + 0.5f) / texture_width_),
AS> (float )(((double )srcRect->top + 0.5f) / texture_height_)},
AS> {(float )destRect->left, (float )destRect->bottom, 0.0f, 1.0f,
AS> (float )(((double )srcRect->left + 0.5f) / texture_width_),
AS> (float )(((double )srcRect->bottom + 0.5f) / texture_height_)},
AS> {(float )destRect->right, (float )destRect->bottom, 0.0f, 1.0f,
AS> (float )(((double )srcRect->right + 0.5f) / texture_width_),
AS> (float )(((double )srcRect->bottom + 0.5f) / texture_height_)}
AS> }};
AS> void * pBuf;
AS> hr = vert_buffer_->Lock(0, sizeof (squareVerts), &pBuf, 0);
AS> if (D3D_OK == hr) {
AS> memcpy(pBuf, &squareVerts, sizeof (squareVerts));
AS> vert_buffer_->Unlock();
AS> } else {
AS> return hr == D3D_OK? RS_OK: RS_ERR;
AS> //NOTREACHED
AS> }
AS> }
AS>
Re[5]: DirectX тормоза при масштабировании картинки
Здравствуйте, 8bit, Вы писали:
8>Здравствуйте, Aleksey Skurihin, Вы писали:
пошел проверять и читать
спасибо. разберусь отпишусь.
а как VMR9 работает? у него на полный єкран загрузка проца 4% против моих 12%
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[5]: DirectX тормоза при масштабировании картинки
а еще проблема что при рисовании например ДВУХ кадров одновременно на разных хендлах, скорость падает в 4-5 раза
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[6]: DirectX тормоза при масштабировании картинки
От:
8bit
Дата: 17.02.09 12:43
Оценка:
Здравствуйте, Aleksey Skurihin, Вы писали:
Еще проверьте что у вас создается D3DDEVTYPE_HAL, а не D3DDEVTYPE_REF устройство.
Re[7]: DirectX тормоза при масштабировании картинки
Здравствуйте, 8bit, Вы писали:
8>Здравствуйте, Aleksey Skurihin, Вы писали:
8>Еще проверьте что у вас создается D3DDEVTYPE_HAL, а не D3DDEVTYPE_REF устройство.
проверили D3DDEVTYPE_HAL а вот с двумя вьюпортами (либо с увеличением площади) явно в итоге трабла, куда копать не знаю, то что Вы советовали ник чему не привело.
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[8]: DirectX тормоза при масштабировании картинки
От:
8bit
Дата: 17.02.09 17:08
Оценка:
Здравствуйте, Aleksey Skurihin, Вы писали:
AS>проверили D3DDEVTYPE_HAL а вот с двумя вьюпортами (либо с увеличением площади) явно в итоге трабла, куда копать не знаю, то что Вы советовали ник чему не привело.
Я у себя практически ваш код запустил, все в порядке. Делал stretch поверхности 640x480 на 990x730.
в оконном режиме 60фпс (частота обновления экрана, т.е все как и должно быть), загрузка ~10%
Какой формат у вас для surface_ ?
Что за видеокарточка?
Драйвера обновленные?
Re[9]: DirectX тормоза при масштабировании картинки
8>Я у себя практически ваш код запустил, все в порядке. Делал stretch поверхности 640x480 на 990x730.
8>в оконном режиме 60фпс (частота обновления экрана, т.е все как и должно быть), загрузка ~10%
можете прислать Ваш код?
а если будет ДВА вьюпорта? или один но разрешение 1600 на 1000.
8>Какой формат у вас для surface_ ?
ргб32
8>Что за видеокарточка?
гефорсе двухмониторный но без разницы.
8>Драйвера обновленные?
да
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[9]: DirectX тормоза при масштабировании картинки
а у текстуры с алертами — D3DFMT_A8R8G8B8
Радость от нахождения ошибки часто омрачаеться осознанием собственой глупости.
Re[10]: DirectX тормоза при масштабировании картинки
От:
8bit
Дата: 19.02.09 08:13
Оценка:
Здравствуйте, Aleksey Skurihin, Вы писали:
8>>Я у себя практически ваш код запустил, все в порядке. Делал stretch поверхности 640x480 на 990x730.
8>>в оконном режиме 60фпс (частота обновления экрана, т.е все как и должно быть), загрузка ~10%
AS>можете прислать Ваш код?
bool cDXRender::Open(const wchar_t *inWindowTitle, int inWidth, int inHeight, bool inFullScreen, tWndProc inWindowProcedure)
{
Close();
windowProcedure = inWindowProcedure;
fullScreen = inFullScreen;
width = inWidth;
height = inHeight;
midleWidth = width/2;
midleHeight = height/2;
instance = GetModuleHandle(NULL);
WNDCLASS wc;
int style1;
int style2;
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = (HINSTANCE)instance;
wc.hIcon = LoadIcon((HINSTANCE)instance, MAKEINTRESOURCE(IDI_APPLICATION));
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = 0;
wc.lpszClassName = L"dx9render wc" ;
if (!RegisterClass(&wc))
{
return (false );
}
int winPosX = 0;
int winPosY = 0;
if (fullScreen)
{
style2 = WS_EX_TOPMOST;
style1 = WS_POPUP | WS_VISIBLE;
}
else
{
winPosX = (GetSystemMetrics(SM_CXSCREEN) - inWidth)/2;
winPosY = (GetSystemMetrics(SM_CYSCREEN) - inHeight)/2;
style2 = 0;
style1 = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE;
}
wnd = CreateWindowEx(
style2,
L"dx9render wc" ,
(LPCTSTR)inWindowTitle,
style1,
winPosX, winPosY, inWidth, inHeight,
NULL,
NULL,
instance,
NULL);
if (!wnd)
{
return (false );
}
SetWindowLong(wnd, GWL_USERDATA, (long )this );
ShowWindow(wnd, SW_NORMAL);
if ((d3d = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
{
return (false );
}
#define MULTITHREADED_D3D
#ifdef MULTITHREADED_D3D
# define _D3DDEV_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED)
#else
# define _D3DDEV_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING)
#endif
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof (d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.hDeviceWindow = wnd;
if (D3D_OK !=
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
wnd,
_D3DDEV_FLAGS,
&d3dpp,
&device
)
)
{
return (false );
}
return true ;
}
int APIENTRY WinMain(HINSTANCE inInstance, HINSTANCE inPrevInstance, LPSTR inCmdLine, int inCmdShow)
{
HRESULT hr;
cDXRender r;
DWORD time = GetTickCount();
DWORD stime = GetTickCount();
DWORD tmil;
int frames = 0;
int fps = 0;
r.Open(L"asd" , 1600, 1000, false , 0);
IDirect3DDevice9 *d3d_dev_ = r.device;
IDirect3DSurface9* surface_;
hr = d3d_dev_->CreateOffscreenPlainSurface(
640,
480,
(D3DFORMAT)D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&surface_,
0
);
while (true )
{
MSG wmsg;
if (PeekMessage((LPMSG)&wmsg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage((LPMSG)&wmsg);
DispatchMessage((LPMSG)&wmsg);
}
D3DLOCKED_RECT lockedRect;
if (surface_->LockRect(&lockedRect, 0, D3DLOCK_DISCARD) != D3D_OK)
{
return -1;
}
for (int i = 0; i < 200; ++i)
{
memset((char *)lockedRect.pBits+lockedRect.Pitch*i, 127, lockedRect.Pitch);
}
surface_->UnlockRect();
d3d_dev_->Clear( 0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0 );
d3d_dev_->BeginScene();
frames++;
DWORD ctime = GetTickCount();
tmil = ctime - stime;
DWORD dtime = ctime-time;
time = ctime;
//d3d_dev_->SetFVF(D3DFVF_CUSTOMVERTEX);
// d3d_dev_->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
d3d_dev_->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
d3d_dev_->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
d3d_dev_->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
// device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
IDirect3DSurface9* backBuf = 0;
if (d3d_dev_->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuf) != D3D_OK)
{
return -1;
}
//IDirect3DSurface9* backBuf;
//d3d_dev_->GetRenderTarget(0,&backBuf);
RECT aSrcRect;
aSrcRect.left = 0;
aSrcRect.right = 320;
aSrcRect.top = 0;
aSrcRect.bottom = 200;
RECT aDestRect;
aDestRect.left = 0;
aDestRect.right = 1590;
aDestRect.top = 0;
aDestRect.bottom = 960;
hr = d3d_dev_->StretchRect(surface_, &aSrcRect, backBuf, &aDestRect, D3DTEXF_LINEAR);
if (D3D_OK != hr)
{
hr = d3d_dev_->StretchRect(surface_, &aSrcRect, backBuf, &aDestRect, D3DTEXF_NONE);
if (D3D_OK != hr)
{
return -1;
}
}
backBuf->Release();
if (tmil > 2000)
{
fps = (int )((float )frames/((float )tmil/1000.0f));
stime = GetTickCount();
frames = 0;
}
//r.DrawFps(fps);
d3d_dev_->EndScene();
{
HRESULT hr = d3d_dev_->Present( NULL, NULL, NULL, NULL );
}
}
}
AS>или один но разрешение 1600 на 1000.
Все в порядке. ~57 фпс
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить