Fix texture preview in editor tools dialogue on Windows.

issue1247
Sven Eberhardt 2014-12-14 15:20:57 +01:00
parent bd1f59cb2d
commit 8df39d06e4
4 changed files with 63 additions and 30 deletions

View File

@ -305,7 +305,7 @@ class C4ToolsDlg::State: public C4ConsoleGUI::InternalState<class C4ToolsDlg>
{
public:
HWND hDialog;
CStdGLCtx* pGLCtx;
C4Window *pPreviewWindow;
friend INT_PTR CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
HBITMAP hbmBrush,hbmBrush2;
HBITMAP hbmLine,hbmLine2;
@ -330,7 +330,7 @@ public:
hbmStatic(0),
hbmExact(0)
{
pGLCtx = NULL;
pPreviewWindow = NULL;
}
void LoadBitmaps(HINSTANCE instance)
@ -366,10 +366,10 @@ public:
if (hbmFill) DeleteObject(hbmFill);
if (hbmIFT) DeleteObject(hbmIFT);
if (hbmNoIFT) DeleteObject(hbmNoIFT);
if (pGLCtx)
if (pPreviewWindow)
{
delete pGLCtx;
pGLCtx = NULL;
delete pPreviewWindow;
pPreviewWindow = NULL;
}
if (hDialog) DestroyWindow(hDialog); hDialog=NULL;
}
@ -931,6 +931,20 @@ void C4ConsoleGUI::ClearPropertyDlg(C4PropertyDlg *dlg)
}
*/
// Wrapper window around preview control: Used to create GL context and target surface
class C4ConsoleGUIPreviewWindow : public C4Window
{
public:
C4ConsoleGUIPreviewWindow(HWND hwndControl)
{
Init(C4Window::WindowKind::W_Control, &Application, NULL, NULL);
this->hWindow = this->hRenderWindow = hwndControl;
pSurface = new C4Surface(&Application, this);
}
virtual void Close() {}
};
bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg)
{
if (dlg->state->hDialog) return true;
@ -946,8 +960,10 @@ bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg)
// Load bitmaps if necessary
dlg->state->LoadBitmaps(Application.GetInstance());
// create target ctx for OpenGL rendering
if (pDraw && !dlg->state->pGLCtx)
dlg->state->pGLCtx = pDraw->CreateContext(GetDlgItem(dlg->state->hDialog,IDC_PREVIEW), &Application);
if (pDraw && !dlg->state->pPreviewWindow)
{
dlg->state->pPreviewWindow = new C4ConsoleGUIPreviewWindow(GetDlgItem(dlg->state->hDialog, IDC_PREVIEW));
}
// Show window
RestoreWindowPosition(dlg->state->hDialog, "Property", Config.GetSubkeyPath("Console"));
SetWindowPos(dlg->state->hDialog,Console.hWindow,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE);
@ -1025,9 +1041,11 @@ void C4ToolsDlg::UpdateTextures()
void C4ToolsDlg::NeedPreviewUpdate()
{
if (!state->hDialog) return;
if (!state->hDialog || !state->pPreviewWindow) return;
C4Surface * sfcPreview = state->pPreviewWindow->pSurface;
if (!sfcPreview) return;
C4Surface * sfcPreview;
int32_t iPrvWdt,iPrvHgt;
RECT rect;
@ -1036,10 +1054,12 @@ void C4ToolsDlg::NeedPreviewUpdate()
iPrvWdt=rect.right-rect.left;
iPrvHgt=rect.bottom-rect.top;
if (!(sfcPreview=new C4Surface(iPrvWdt,iPrvHgt))) return;
if (!sfcPreview->UpdateSize(iPrvWdt, iPrvHgt)) return;
sfcPreview->NoClip();
if (!pDraw->PrepareRendering(sfcPreview)) return;
// fill bg
pDraw->DrawBoxDw(sfcPreview,0,0,iPrvWdt-1,iPrvHgt-1,C4RGB(0x80,0x80,0x80));
pDraw->DrawBoxDw(sfcPreview,0,0,iPrvWdt-1,iPrvHgt-1,C4RGB(0xa0,0xa0,0xa0));
BYTE bCol = 0;
C4Pattern Pattern;
// Sky material: sky as pattern only
@ -1071,16 +1091,7 @@ void C4ToolsDlg::NeedPreviewUpdate()
Grade,
bCol, Pattern, *::Landscape.GetPal());
//Application.DDraw->AttachPrimaryPalette(sfcPreview);
// FIXME: This activates the wrong GL context. To avoid breaking the main window display,
// FIXME: it has been disabled for the moment
//if (pGLCtx->Select())
//{
// pGL->Blit(sfcPreview, 0,0,(float)iPrvWdt,(float)iPrvHgt, Application.pWindow->pSurface, rect.left,rect.top, iPrvWdt,iPrvHgt);
// Application.pWindow->pSurface->PageFlip();
//}
delete sfcPreview;
sfcPreview->PageFlip();
}
void C4ToolsDlg::InitGradeCtrl()

View File

@ -995,17 +995,28 @@ void C4Draw::DrawQuadDw(C4Surface * sfcTarget, float *ipVtx, DWORD dwClr1, DWORD
void C4Draw::DrawPatternedCircle(C4Surface * sfcDest, int x, int y, int r, BYTE col, C4Pattern & Pattern, CStdPalette &rPal)
{
if (!sfcDest->Lock()) return;
bool fRenderTarget = sfcDest->IsRenderTarget();
if (!fRenderTarget) if (!sfcDest->Lock()) return;
for (int ycnt = -r; ycnt < r; ycnt++)
{
int lwdt = (int) sqrt(float(r * r - ycnt * ycnt));
int lwdt = (int)sqrt(float(r * r - ycnt * ycnt));
// Set line
for (int xcnt = x - lwdt; xcnt < x + lwdt; ++xcnt)
if (fRenderTarget)
{
sfcDest->SetPixDw(xcnt, y + ycnt, Pattern.PatternClr(xcnt, y + ycnt));
for (int xcnt = x - lwdt; xcnt < x + lwdt; ++xcnt)
{
DrawPix(sfcDest, xcnt, y + ycnt, Pattern.PatternClr(xcnt, y + ycnt));
}
}
else
{
for (int xcnt = x - lwdt; xcnt < x + lwdt; ++xcnt)
{
sfcDest->SetPixDw(xcnt, y + ycnt, Pattern.PatternClr(xcnt, y + ycnt));
}
}
}
sfcDest->Unlock();
if (!fRenderTarget) sfcDest->Unlock();
}
void C4Draw::Grayscale(C4Surface * sfcSfc, int32_t iOffset)

View File

@ -287,13 +287,15 @@ public:
W_GuiWindow,
W_Console,
W_Viewport,
W_Fullscreen
W_Fullscreen,
W_Control // wrapper to a render target control inside a window
};
public:
C4Window ();
virtual ~C4Window ();
bool Active;
C4Surface * pSurface;
WindowKind eKind;
virtual void Clear();
// Only when the wm requests a close
// For example, when the user clicks the little x in the corner or uses Alt-F4

View File

@ -533,6 +533,7 @@ C4Window::~C4Window ()
C4Window * C4Window::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp, const char * Title, const C4Rect * size)
{
Active = true;
eKind = windowKind;
if (windowKind == W_Viewport)
{
static bool fViewportClassRegistered = false;
@ -647,6 +648,11 @@ C4Window * C4Window::Init(C4Window::WindowKind windowKind, C4AbstractApp * pApp,
hRenderWindow = hWindow;
return hWindow ? this : 0;
}
else if (windowKind == W_Control)
{
// controlled externally
hWindow = hRenderWindow = NULL;
}
return this;
}
@ -674,9 +680,12 @@ bool C4Window::ReInit(C4AbstractApp* pApp)
void C4Window::Clear()
{
// Destroy window
if (hRenderWindow) DestroyWindow(hRenderWindow);
if (hWindow && hWindow != hRenderWindow) DestroyWindow(hWindow);
// Destroy window if we own it
if (eKind != W_Control)
{
if (hRenderWindow) DestroyWindow(hRenderWindow);
if (hWindow && hWindow != hRenderWindow) DestroyWindow(hWindow);
}
hRenderWindow = NULL;
hWindow = NULL;
}