VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/ogltest/ogltest.cpp

Last change on this file was 98139, checked in by vboxsync, 16 months ago

Add/WinNT: Made an disabled opengl test build again and use VBoxR3Static instead of VBOXR3STATIC. bugref:10348

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* $Id: ogltest.cpp 98139 2023-01-19 13:50:46Z vboxsync $ */
2/** @file
3 * OpenGL testcase. Win32 application to run Gallium OpenGL tests.
4 */
5
6/*
7 * Copyright (C) 2019-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "oglrender.h"
29#include <iprt/string.h>
30
31PFNGLBINDBUFFERPROC glBindBuffer;
32PFNGLDELETEBUFFERSPROC glDeleteBuffers;
33PFNGLGENBUFFERSPROC glGenBuffers;
34PFNGLBUFFERDATAPROC glBufferData;
35PFNGLMAPBUFFERPROC glMapBuffer;
36PFNGLUNMAPBUFFERPROC glUnmapBuffer;
37PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
38PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
39PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
40PFNGLCREATESHADERPROC glCreateShader;
41PFNGLATTACHSHADERPROC glAttachShader;
42PFNGLCOMPILESHADERPROC glCompileShader;
43PFNGLCREATEPROGRAMPROC glCreateProgram;
44PFNGLDELETEPROGRAMPROC glDeleteProgram;
45PFNGLDELETESHADERPROC glDeleteShader;
46PFNGLDETACHSHADERPROC glDetachShader;
47PFNGLLINKPROGRAMPROC glLinkProgram;
48PFNGLSHADERSOURCEPROC glShaderSource;
49PFNGLUSEPROGRAMPROC glUseProgram;
50PFNGLGETPROGRAMIVPROC glGetProgramiv;
51PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
52PFNGLGETSHADERIVPROC glGetShaderiv;
53PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
54PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
55PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
56
57class OGLTest
58{
59public:
60 OGLTest();
61 ~OGLTest();
62
63 HRESULT Init(HINSTANCE hInstance, int argc, char **argv, int nCmdShow);
64 int Run();
65
66private:
67 HRESULT initWindow(HINSTANCE hInstance, int nCmdShow);
68 HRESULT initOGL();
69 void parseCmdLine(int argc, char **argv);
70 static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
71
72 void setCurrentGLCtx(HGLRC hGLRC);
73
74 int miRenderId;
75 int miRenderStep;
76
77 HWND mHwnd;
78 HGLRC mhGLRC;
79
80 OGLRender *mpRender;
81};
82
83OGLTest::OGLTest()
84 :
85 miRenderId(0),
86 miRenderStep(1),
87 mHwnd(0),
88 mhGLRC(0),
89 mpRender(0)
90{
91}
92
93OGLTest::~OGLTest()
94{
95 if (mpRender)
96 {
97 delete mpRender;
98 mpRender = 0;
99 }
100
101 setCurrentGLCtx(NULL);
102 wglDeleteContext(mhGLRC);
103}
104
105void OGLTest::setCurrentGLCtx(HGLRC hGLRC)
106{
107 if (hGLRC)
108 {
109 HDC const hDC = GetDC(mHwnd);
110 wglMakeCurrent(hDC, mhGLRC);
111 ReleaseDC(mHwnd, hDC);
112 }
113 else
114 {
115 wglMakeCurrent(NULL, NULL);
116 }
117}
118
119
120LRESULT CALLBACK OGLTest::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
121{
122 switch (msg)
123 {
124 case WM_CLOSE:
125 DestroyWindow(hwnd);
126 return 0;
127
128 case WM_DESTROY:
129 PostQuitMessage(0);
130 return 0;
131
132 default:
133 return DefWindowProcA(hwnd, msg, wParam, lParam);
134 }
135}
136
137HRESULT OGLTest::initWindow(HINSTANCE hInstance,
138 int nCmdShow)
139{
140 HRESULT hr = S_OK;
141
142 WNDCLASSA wc = { 0 };
143 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
144 wc.lpfnWndProc = wndProc;
145 wc.cbClsExtra = 0;
146 wc.cbWndExtra = 0;
147 wc.hInstance = hInstance;
148 wc.hIcon = LoadIcon(0, IDI_APPLICATION);
149 wc.hCursor = LoadCursor(0, IDC_ARROW);
150 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
151 wc.lpszMenuName = 0;
152 wc.lpszClassName = "OGLTestWndClassName";
153
154 if (RegisterClassA(&wc))
155 {
156 RECT r = {0, 0, 800, 600};
157 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
158
159 mHwnd = CreateWindowA("OGLTestWndClassName",
160 "OGL Test",
161 WS_OVERLAPPEDWINDOW,
162 100, 100, r.right, r.bottom,
163 0, 0, hInstance, 0);
164 if (mHwnd)
165 {
166 ShowWindow(mHwnd, nCmdShow);
167 UpdateWindow(mHwnd);
168 }
169 else
170 {
171 TestShowError(hr, "CreateWindow");
172 hr = E_FAIL;
173 }
174 }
175 else
176 {
177 TestShowError(hr, "RegisterClass");
178 hr = E_FAIL;
179 }
180
181 return hr;
182}
183
184HRESULT OGLTest::initOGL()
185{
186 HRESULT hr = S_OK;
187
188 HDC hDC = GetDC(mHwnd);
189
190 PIXELFORMATDESCRIPTOR pfd;
191 memset(&pfd, 0, sizeof(pfd));
192 pfd.nSize = sizeof(pfd);
193 pfd.nVersion = 1;
194 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
195 pfd.iPixelType = PFD_TYPE_RGBA;
196 pfd.cColorBits = 32;
197
198 int pf = ChoosePixelFormat(hDC, &pfd);
199 if (pf)
200 {
201 if (SetPixelFormat(hDC, pf, &pfd))
202 {
203 DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
204
205 mhGLRC = wglCreateContext(hDC);
206 setCurrentGLCtx(mhGLRC);
207
208/* Get a function address, return VERR_NOT_IMPLEMENTED on failure. */
209#define GLGETPROC_(ProcType, ProcName, NameSuffix) do { \
210 ProcName = (ProcType)wglGetProcAddress(#ProcName NameSuffix); \
211 if (!ProcName) { TestShowError(E_FAIL, #ProcName NameSuffix " missing"); } \
212} while(0)
213
214 GLGETPROC_(PFNGLBINDBUFFERPROC , glBindBuffer, "");
215 GLGETPROC_(PFNGLDELETEBUFFERSPROC , glDeleteBuffers, "");
216 GLGETPROC_(PFNGLGENBUFFERSPROC , glGenBuffers, "");
217 GLGETPROC_(PFNGLBUFFERDATAPROC , glBufferData, "");
218 GLGETPROC_(PFNGLMAPBUFFERPROC , glMapBuffer, "");
219 GLGETPROC_(PFNGLUNMAPBUFFERPROC , glUnmapBuffer, "");
220 GLGETPROC_(PFNGLENABLEVERTEXATTRIBARRAYPROC , glEnableVertexAttribArray, "");
221 GLGETPROC_(PFNGLDISABLEVERTEXATTRIBARRAYPROC , glDisableVertexAttribArray, "");
222 GLGETPROC_(PFNGLVERTEXATTRIBPOINTERPROC , glVertexAttribPointer, "");
223 GLGETPROC_(PFNGLCREATESHADERPROC , glCreateShader, "");
224 GLGETPROC_(PFNGLATTACHSHADERPROC , glAttachShader, "");
225 GLGETPROC_(PFNGLCOMPILESHADERPROC , glCompileShader, "");
226 GLGETPROC_(PFNGLCREATEPROGRAMPROC , glCreateProgram, "");
227 GLGETPROC_(PFNGLDELETEPROGRAMPROC , glDeleteProgram, "");
228 GLGETPROC_(PFNGLDELETESHADERPROC , glDeleteShader, "");
229 GLGETPROC_(PFNGLDETACHSHADERPROC , glDetachShader, "");
230 GLGETPROC_(PFNGLLINKPROGRAMPROC , glLinkProgram, "");
231 GLGETPROC_(PFNGLSHADERSOURCEPROC , glShaderSource, "");
232 GLGETPROC_(PFNGLUSEPROGRAMPROC , glUseProgram, "");
233 GLGETPROC_(PFNGLGETPROGRAMIVPROC , glGetProgramiv, "");
234 GLGETPROC_(PFNGLGETPROGRAMINFOLOGPROC , glGetProgramInfoLog, "");
235 GLGETPROC_(PFNGLGETSHADERIVPROC , glGetShaderiv, "");
236 GLGETPROC_(PFNGLGETSHADERINFOLOGPROC , glGetShaderInfoLog, "");
237 GLGETPROC_(PFNGLVERTEXATTRIBDIVISORPROC , glVertexAttribDivisor, "");
238 GLGETPROC_(PFNGLDRAWARRAYSINSTANCEDPROC , glDrawArraysInstanced, "");
239
240#undef GLGETPROC_
241
242 }
243 else
244 {
245 TestShowError(hr, "SetPixelFormat");
246 hr = E_FAIL;
247 }
248 }
249 else
250 {
251 TestShowError(hr, "ChoosePixelFormat");
252 hr = E_FAIL;
253 }
254
255 ReleaseDC(mHwnd, hDC);
256
257 return hr;
258}
259
260void OGLTest::parseCmdLine(int argc, char **argv)
261{
262 /* Very simple: test number followed by step flag.
263 * Default is test 0, step mode: 1
264 */
265
266 /* First number is the render id. */
267 if (argc >= 2)
268 miRenderId = RTStrToInt32(argv[1]);
269
270 /* Second number is the step mode. */
271 if (argc >= 3)
272 miRenderStep = RTStrToInt32(argv[2]);
273}
274
275HRESULT OGLTest::Init(HINSTANCE hInstance, int argc, char **argv, int nCmdShow)
276{
277 parseCmdLine(argc, argv);
278
279 HRESULT hr = initWindow(hInstance, nCmdShow);
280 if (SUCCEEDED(hr))
281 {
282 mpRender = CreateRender(miRenderId);
283 if (mpRender)
284 {
285 hr = initOGL();
286 if (SUCCEEDED(hr))
287 {
288 setCurrentGLCtx(mhGLRC);
289
290 hr = mpRender->InitRender();
291 if (FAILED(hr))
292 {
293 TestShowError(hr, "InitRender");
294 }
295
296 setCurrentGLCtx(NULL);
297 }
298 }
299 else
300 {
301 hr = E_FAIL;
302 }
303 }
304
305 return hr;
306}
307
308int OGLTest::Run()
309{
310 bool fFirst = true;
311 MSG msg;
312 do
313 {
314 BOOL fGotMessage;
315 if (miRenderStep)
316 {
317 fGotMessage = GetMessageA(&msg, 0, 0, 0);
318 }
319 else
320 {
321 fGotMessage = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
322 }
323
324 if (fGotMessage)
325 {
326 TranslateMessage(&msg);
327 DispatchMessageA(&msg);
328 }
329
330 float dt = 0.0f; /* Time in seconds since last render step. @todo Measure. */
331
332 BOOL fDoRender = FALSE;
333 if (miRenderStep)
334 {
335 if (msg.message == WM_CHAR)
336 {
337 if (msg.wParam == ' ')
338 {
339 fDoRender = TRUE;
340 dt = fFirst ? 0.0f : 0.1f; /* 0.1 second increment per step. */
341 }
342 }
343 }
344 else
345 {
346 fDoRender = TRUE;
347 }
348
349 if (fDoRender)
350 {
351 if (mpRender)
352 {
353 setCurrentGLCtx(mhGLRC);
354
355 mpRender->TimeAdvance(dt);
356 mpRender->DoRender();
357
358 setCurrentGLCtx(NULL);
359
360 fFirst = false;
361 }
362 }
363 } while (msg.message != WM_QUIT);
364
365 return msg.wParam;
366}
367
368int main(int argc, char **argv)
369{
370 int rcExit = RTEXITCODE_FAILURE;
371
372 OGLTest test;
373 HRESULT hr = test.Init(GetModuleHandleW(NULL), argc, argv, SW_SHOWDEFAULT);
374 if (SUCCEEDED(hr))
375 rcExit = test.Run();
376
377 return rcExit;
378}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use