OpenGL мигает?

Я пытаюсь нарисовать текст в OpenGL, в то время как программа рисует куб или любой родной Opengl, поэтому, когда я пытаюсь поместить текст на экран, он очень быстро мигает, и я не знаю почему, я пытался изменить режим сна. ценность и ничего …

Код ниже; вот GIF, показывающий проблему.

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

#include <windows.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include "default.h"
using namespace std;

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI WorkLoop(LPVOID PARAMS);
void keyScan (MSG msg, Camera cam);

HDC hDC;
HGLRC hRC;
HWND hwnd;

RECT WBounds;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
MSG msg;
BOOL bQuit = FALSE;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;
Screen ();

if (!RegisterClassEx(&wcex))
return 0;hwnd = CreateWindowEx(0,
"GLSample",
"OpenGL Testing",
WS_OVERLAPPEDWINDOW,
Scr.sx/2-630,
Scr.sy/2-450,
1260,
900,
NULL,
NULL,
hInstance,
NULL);

GetClientRect(hwnd, &WBounds);

ShowWindow(hwnd, nCmdShow);
EnableOpenGL(hwnd, &hDC, &hRC);  ///ENABLE OPENGL

Camera cam = Camera (0, 0, -1);

CreateThread(0, 0x1000, &WorkLoop, 0, 0, 0);

while (!bQuit)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) bQuit = TRUE;
else
{
keyScan (msg, cam);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
renderSimulation (cam);
SwapBuffers (hDC);
}
Sleep(1);
}

DisableOpenGL(hwnd, hDC, hRC);
DestroyWindow(hwnd);
return msg.wParam;
}

DWORD WINAPI WorkLoop(LPVOID PARAMS)
{
while (true)
{
InvalidateRect(hwnd, &WBounds, true);
Sleep(33);
}
ExitThread(0);
}float x = 0.0f, y = 0.0f, z = 0.0f;
float rx = 0.0f, ry = 0.0f, rz = 0.0f;
char* textas = "test";

void keyScan (MSG p, Camera cam)
{
if (p.message == WM_KEYDOWN)
{
if (p.wParam == ARROW_RIGHT)      {x += 0.1; cam.SetCameraPosition (x, y, z);}
else if (p.wParam == ARROW_LEFT)  {x -= 0.1; cam.SetCameraPosition (x, y, z);}
else if (p.wParam == ARROW_UP)    {y += 0.1; cam.SetCameraPosition (x, y, z);}
else if (p.wParam == ARROW_DOWN)  {y -= 0.1; cam.SetCameraPosition (x, y, z);}
else if (p.wParam == NUM_8)       {z += 0.1; cam.SetCameraPosition (x, y, z);}
else if (p.wParam == NUM_2)       {z -= 0.1; cam.SetCameraPosition (x, y, z);}
else if (p.wParam == L)           SetFullScreen (p.hwnd, hDC, hRC);
else if (p.wParam == K)           textas = "cambiado";
}
}

HFONT Font = CreateFont(40, 0, 0, 0,FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, FF_MODERN, TEXT("Arial"));
HPEN BoxPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
HPEN OutlinePen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
HPEN CHPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
HBRUSH CHBrush = CreateSolidBrush(RGB(0, 255, 0));

void drawtext(HDC hdc, int x, int y, const char * text)
{
SetBkMode (hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0, 255, 0));
SetBkColor(hdc, RGB(255, 255, 255));
TextOutA(hdc, x, y, text, strlen(text));
}

/*void Draw(HDC hdc, int x, int y, float dist)
{
int width = 20000 / dist;
int height = 45000 / dist;
SelectObject(hdc, OutlinePen);
SelectObject(hdc, WHITE_BRUSH);
Rectangle(hdc, x - (width / 2), y - height, x + (width / 2), y);
SelectObject(hdc, BoxPen);
Rectangle(hdc, x - (width / 2), y - height, x + (width / 2), y);
SetTextAlign(hdc, TA_CENTER | TA_NOUPDATECP);
std::stringstream ss2;
ss2 << "Dist: " << dist << " m";
drawtext(hdc, x, y + 90, ss2.str().c_str());
}*/

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
int win_width = WBounds.right - WBounds.left;
int win_height = WBounds.bottom + WBounds.left;
PAINTSTRUCT ps;
HDC Memhdc;
HDC hdc;
HBITMAP Membitmap;
hdc = BeginPaint(hwnd, &ps);
Memhdc = CreateCompatibleDC (hdc);
Membitmap = CreateCompatibleBitmap (hdc, win_width, win_height);
SelectObject (Memhdc, Membitmap);
//FillRect (Memhdc, &WBounds, WHITE_BRUSH);
SelectObject (Memhdc, Font);
SetTextAlign (Memhdc, TA_LEFT | TA_NOUPDATECP);
drawtext(Memhdc, 100, 100, textas);

//Draw (Memhdc, 20, 50, 90.0);

/*SelectObject(Memhdc, CHPen);
SelectObject(Memhdc, CHBrush);*/

BitBlt (hdc, 0, 0, win_width, win_height, Memhdc, 0, 0, SRCCOPY);
DeleteObject(Membitmap);
DeleteDC(Memhdc);
DeleteDC(hdc);
EndPaint(hwnd, &ps);
ValidateRect(hwnd, &WBounds);
}
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
}
}
case WM_ERASEBKGND:
return 1;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}

1

Решение

Две проблемы с вашей программой:

  1. Установка фоновой кисти для окна OpenGL заставит ОС визуально очистить окно с помощью кисти перед отправкой WM_PAINT (при которой вы переопределяете с помощью OpenGL). Используя InvalidateRect, вы запускаете это стирание с фоном до WM_PAINT

  2. Пиксельные форматы OpenGL с двойной буферизацией и рисование с использованием GDI плохо сочетаются. Если вы хотите нарисовать текст, вам придется сделать это по-другому. Например, рисование на DIBSECTION DC и затем рисование этого растрового изображения в соответствии с использованием текстурированного квадрата. Или используя растеризатор шрифтов, который обращается к OpenGL (FTGL, Glyphy или тому подобное).

5

Другие решения


По вопросам рекламы [email protected]