Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : /*
11 : * =======================================================================
12 : *
13 : * This is a quick hack to test some stuff. Work in progress. Don't touch
14 : * and don't bother inspecting too closely.
15 : *
16 : * =======================================================================
17 : */
18 :
19 : #include <iostream>
20 :
21 : #include <math.h>
22 :
23 : #include <GL/glew.h>
24 :
25 : #include <glm/gtx/bit.hpp>
26 :
27 : #include <com/sun/star/lang/XComponent.hpp>
28 : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
29 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 : #include <com/sun/star/ucb/UniversalContentBroker.hpp>
31 : #include <comphelper/processfactory.hxx>
32 : #include <cppuhelper/bootstrap.hxx>
33 : #include <osl/file.hxx>
34 : #include <vcl/builder.hxx>
35 : #include <vcl/button.hxx>
36 : #include <vcl/dialog.hxx>
37 : #include <vcl/fixed.hxx>
38 : #include <vcl/graph.hxx>
39 : #include <vcl/graphicfilter.hxx>
40 : #include <vcl/image.hxx>
41 : #include <vcl/openglwin.hxx>
42 : #include <vcl/opengl/OpenGLContext.hxx>
43 : #include <vcl/opengl/OpenGLHelper.hxx>
44 : #include <vcl/svapp.hxx>
45 : #include <vcl/vclmain.hxx>
46 : #include <vcl/wrkwin.hxx>
47 :
48 : using namespace com::sun::star;
49 :
50 : namespace {
51 : const int WIDTH = 1000, HEIGHT = 800;
52 :
53 0 : double getTimeNow()
54 : {
55 : TimeValue aValue;
56 0 : osl_getSystemTime(&aValue);
57 0 : return (double)aValue.Seconds +
58 0 : (double)aValue.Nanosec / (1000*1000*1000);
59 : }
60 :
61 : }
62 :
63 0 : class MyWorkWindow : public WorkWindow
64 : {
65 : private:
66 :
67 : protected:
68 : double mnStartTime;
69 : int mnPaintCount;
70 :
71 : public:
72 : Graphic maGraphic;
73 : Bitmap *mpBitmap;
74 : FixedBitmap *mpFixedBitmap;
75 :
76 : MyWorkWindow( vcl::Window* pParent, WinBits nWinStyle );
77 :
78 : void LoadGraphic( const OUString& sImageFile );
79 :
80 : virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
81 : virtual void Resize() SAL_OVERRIDE;
82 : };
83 :
84 0 : class MyOpenGLWorkWindow : public MyWorkWindow
85 : {
86 : public:
87 : bool mbHaveTexture;
88 : OpenGLWindow *mpOpenGLWindow;
89 : GLuint mnTextureName;
90 : float mnTextureAspect;
91 :
92 : void LoadTexture();
93 :
94 : MyOpenGLWorkWindow( vcl::Window* pParent, WinBits nWinStyle );
95 :
96 : virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
97 : };
98 :
99 0 : MyWorkWindow::MyWorkWindow( vcl::Window* pParent, WinBits nWinStyle )
100 : : WorkWindow(pParent, nWinStyle)
101 : , mpBitmap(NULL)
102 0 : , mpFixedBitmap(NULL)
103 : {
104 0 : mnPaintCount = 0;
105 0 : mnStartTime = getTimeNow();
106 0 : EnableInput();
107 0 : }
108 :
109 0 : void MyWorkWindow::LoadGraphic( const OUString& sImageFile )
110 : {
111 0 : SvFileStream aFileStream( sImageFile, STREAM_READ );
112 0 : GraphicFilter aGraphicFilter(false);
113 0 : if (aGraphicFilter.ImportGraphic(maGraphic, sImageFile, aFileStream) != 0)
114 : {
115 : SAL_WARN("vcl.icontest", "Could not import image '" << sImageFile << "'");
116 0 : return;
117 0 : }
118 : }
119 :
120 0 : void MyWorkWindow::Paint( const Rectangle& rRect )
121 : {
122 0 : std::cout << "==> Paint! " << mnPaintCount++ << " (vcl) " << GetSizePixel() << " " << getTimeNow() - mnStartTime << std::endl;
123 :
124 0 : Size aGraphicSize( maGraphic.GetSizePixel() );
125 0 : float aspect = ((float) aGraphicSize.Width()) / aGraphicSize.Height();
126 0 : Size aSize;
127 0 : if( aspect >= ((float) WIDTH) / HEIGHT )
128 0 : aSize = Size( WIDTH, HEIGHT/aspect );
129 : else
130 0 : aSize = Size( WIDTH * aspect, HEIGHT );
131 0 : aSize.setWidth( aSize.Width() * (1 + (0.1*sin(mnPaintCount/60.))) );
132 0 : aSize.setHeight( aSize.Height() * (1 + (0.1*sin(mnPaintCount/50.))) );
133 :
134 0 : Bitmap aEmpty;
135 0 : mpFixedBitmap->SetBitmap( aEmpty );
136 0 : GraphicConversionParameters aConv( aSize );
137 0 : mpBitmap = new Bitmap( maGraphic.GetBitmap( aConv ) );
138 0 : mpFixedBitmap->SetBitmap( *mpBitmap );
139 0 : mpFixedBitmap->SetSizePixel( aSize );
140 :
141 0 : WorkWindow::Paint( rRect );
142 :
143 0 : if (mnPaintCount == 100)
144 0 : Application::Quit();
145 :
146 0 : Invalidate( INVALIDATE_CHILDREN );
147 0 : }
148 :
149 0 : MyOpenGLWorkWindow::MyOpenGLWorkWindow( vcl::Window* pParent, WinBits nWinStyle )
150 : : MyWorkWindow(pParent, nWinStyle)
151 : , mnTextureName(0)
152 0 : , mnTextureAspect(0)
153 : {
154 0 : mbHaveTexture = false;
155 0 : mpOpenGLWindow = new OpenGLWindow( this );
156 0 : mpOpenGLWindow->SetSizePixel( Size( WIDTH, HEIGHT ) );
157 0 : mpOpenGLWindow->Show();
158 0 : mpOpenGLWindow->EnableInput();
159 0 : }
160 :
161 0 : void MyOpenGLWorkWindow::LoadTexture()
162 : {
163 0 : mbHaveTexture = true;
164 :
165 0 : glEnable(GL_TEXTURE_2D);
166 0 : CHECK_GL_ERROR();
167 :
168 0 : glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
169 0 : CHECK_GL_ERROR();
170 :
171 0 : glGenTextures( 1, &mnTextureName );
172 0 : CHECK_GL_ERROR();
173 :
174 0 : glBindTexture(GL_TEXTURE_2D, mnTextureName);
175 0 : CHECK_GL_ERROR();
176 :
177 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
178 0 : CHECK_GL_ERROR();
179 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
180 0 : CHECK_GL_ERROR();
181 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
182 0 : CHECK_GL_ERROR();
183 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
184 0 : CHECK_GL_ERROR();
185 :
186 0 : BitmapEx aBitmap( maGraphic.GetBitmapEx( ) );
187 0 : Size aBitmapSize( aBitmap.GetSizePixel() );
188 :
189 : GLint maxTexSize;
190 0 : glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
191 0 : CHECK_GL_ERROR();
192 :
193 : SAL_INFO("vcl.icontest", "GL_MAX_TEXTURE_SIZE: " << maxTexSize);
194 :
195 0 : if (aBitmapSize.Width() > maxTexSize || aBitmapSize.Height() > maxTexSize)
196 : {
197 0 : Size aNewSize(aBitmapSize);
198 0 : if (aNewSize.Width() > maxTexSize)
199 : {
200 0 : aNewSize.setHeight(aNewSize.Height() * (((float) maxTexSize) / aNewSize.Width()));
201 0 : aNewSize.setWidth(maxTexSize);
202 : }
203 0 : if (aNewSize.Height() > maxTexSize)
204 : {
205 0 : aNewSize.setWidth(aNewSize.Width() * (((float) maxTexSize) / aNewSize.Height()));
206 0 : aNewSize.setHeight(maxTexSize);
207 : }
208 : SAL_INFO("vcl.icontest", "Scaling to " << aNewSize);
209 0 : aBitmap.Scale(aNewSize, BMP_SCALE_SUPER);
210 0 : aBitmapSize = aNewSize;
211 : }
212 :
213 : SAL_INFO("vcl.icontest", "GLEW_ARB_texture_non_power_of_two: " << (GLEW_ARB_texture_non_power_of_two ? "YES" : "NO"));
214 :
215 0 : GLsizei texWidth(aBitmapSize.Width()), texHeight(aBitmapSize.Height());
216 :
217 0 : mnTextureAspect = ((float) aBitmapSize.Width()) / aBitmapSize.Height();
218 :
219 0 : if (!GLEW_ARB_texture_non_power_of_two)
220 : {
221 0 : texWidth = texHeight = std::max(aBitmapSize.Width(), aBitmapSize.Height());
222 0 : if (!glm::isPowerOfTwo(texWidth))
223 : {
224 0 : texWidth = glm::powerOfTwoAbove(texWidth);
225 0 : texHeight = texWidth;
226 : }
227 :
228 0 : aBitmap.Expand(texWidth - aBitmapSize.Width(), texHeight - aBitmapSize.Height());
229 :
230 0 : mnTextureAspect = 1;
231 : }
232 :
233 : SAL_INFO("vcl.icontest", "Texture size: " << texWidth << "x" << texHeight);
234 :
235 0 : GLubyte *buffer = new GLubyte[texWidth * texHeight * 4];
236 0 : OpenGLHelper::ConvertBitmapExToRGBATextureBuffer( aBitmap, buffer, true );
237 :
238 : glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
239 : texWidth, texHeight,
240 : 0, GL_RGBA, GL_UNSIGNED_BYTE,
241 0 : buffer);
242 0 : CHECK_GL_ERROR();
243 :
244 0 : delete[] buffer;
245 0 : }
246 :
247 0 : void MyOpenGLWorkWindow::Paint( const Rectangle& )
248 : {
249 0 : std::cout << "==> Paint! "<< mnPaintCount++ << " (OpenGL) " << GetSizePixel() << " " << getTimeNow() - mnStartTime << std::endl;
250 0 : OpenGLContext& aCtx = mpOpenGLWindow->getContext();
251 0 : aCtx.requestLegacyContext();
252 0 : CHECK_GL_ERROR();
253 :
254 0 : if (!mbHaveTexture)
255 0 : LoadTexture();
256 :
257 0 : aCtx.setWinSize( Size( WIDTH+1, HEIGHT+1 ) );
258 0 : CHECK_GL_ERROR();
259 :
260 0 : aCtx.makeCurrent();
261 0 : CHECK_GL_ERROR();
262 :
263 0 : glViewport( 0, 0, WIDTH, HEIGHT );
264 0 : CHECK_GL_ERROR();
265 :
266 0 : glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
267 0 : CHECK_GL_ERROR();
268 :
269 0 : glBindTexture(GL_TEXTURE_2D, mnTextureName);
270 0 : CHECK_GL_ERROR();
271 :
272 0 : glPushMatrix();
273 0 : CHECK_GL_ERROR();
274 :
275 0 : glTranslatef(-1, -1, 0);
276 0 : glScalef(2, 2, 2);
277 :
278 0 : if (mnTextureAspect >= ((float) WIDTH) / HEIGHT)
279 0 : glScalef(1, 1/mnTextureAspect, 1);
280 : else
281 0 : glScalef(1*mnTextureAspect, 1, 1);
282 0 : CHECK_GL_ERROR();
283 :
284 0 : glBegin(GL_QUADS);
285 0 : glTexCoord2f(0, 0);
286 0 : glVertex3f(0, 0, 0);
287 0 : glTexCoord2f(0, 1);
288 0 : glVertex3f(0, 1 + (0.1*sin(mnPaintCount/50.)), 0);
289 0 : glTexCoord2f(1, 1);
290 0 : glVertex3f(1 + (0.1*sin(mnPaintCount/60.)), 1 + (0.1*sin(mnPaintCount/50.)), 0);
291 0 : glTexCoord2f(1, 0);
292 0 : glVertex3f(1 + (0.1*sin(mnPaintCount/60.)), 0, 0);
293 0 : glEnd();
294 0 : CHECK_GL_ERROR();
295 :
296 0 : glPopMatrix();
297 0 : CHECK_GL_ERROR();
298 :
299 0 : aCtx.swapBuffers();
300 0 : CHECK_GL_ERROR();
301 :
302 0 : if (mnPaintCount == 100)
303 0 : Application::Quit();
304 :
305 0 : Invalidate( INVALIDATE_CHILDREN );
306 0 : }
307 :
308 0 : void MyWorkWindow::Resize()
309 : {
310 : SAL_INFO("vcl.icontest", "Resize " << GetSizePixel());
311 0 : }
312 :
313 0 : class IconTestApp : public Application
314 : {
315 : public:
316 : virtual void Init() SAL_OVERRIDE;
317 : virtual int Main() SAL_OVERRIDE;
318 :
319 0 : IconTestApp() : nRet(EXIT_SUCCESS) {};
320 :
321 : private:
322 : int nRet;
323 :
324 : void DoItWithVcl(const OUString& sImageFile);
325 : void DoItWithOpenGL(const OUString& sImageFile);
326 : };
327 :
328 0 : void IconTestApp::Init()
329 : {
330 0 : nRet = EXIT_SUCCESS;
331 :
332 : uno::Reference<uno::XComponentContext> xContext =
333 0 : cppu::defaultBootstrap_InitialComponentContext();
334 : uno::Reference<lang::XMultiComponentFactory> xFactory =
335 0 : xContext->getServiceManager();
336 : uno::Reference<lang::XMultiServiceFactory> xSFactory =
337 0 : uno::Reference<lang::XMultiServiceFactory> (xFactory, uno::UNO_QUERY_THROW);
338 0 : comphelper::setProcessServiceFactory(xSFactory);
339 :
340 : // Create UCB (for backwards compatibility, in case some code still uses
341 : // plain createInstance w/o args directly to obtain an instance):
342 : ::ucb::UniversalContentBroker::create(
343 0 : comphelper::getProcessComponentContext() );
344 0 : }
345 :
346 0 : int IconTestApp::Main()
347 : {
348 0 : if (GetCommandLineParamCount() != 2 ||
349 0 : (GetCommandLineParam(0) != "vcl" &&
350 0 : GetCommandLineParam(0) != "opengl"))
351 : {
352 0 : fprintf(stderr, "Usage: imagetest [vcl|opengl] image\n");
353 0 : return EXIT_FAILURE;
354 : }
355 0 : OUString sImageFile( GetCommandLineParam( 1 ) );
356 0 : if (GetCommandLineParam(0) == "vcl")
357 0 : DoItWithVcl( sImageFile );
358 : else
359 0 : DoItWithOpenGL( sImageFile );
360 :
361 0 : return nRet;
362 : }
363 :
364 0 : void IconTestApp::DoItWithVcl( const OUString& sImageFile)
365 : {
366 : try
367 : {
368 0 : MyWorkWindow *pWindow = new MyWorkWindow( NULL, WB_APP | WB_STDWORK | WB_SIZEABLE | WB_CLOSEABLE | WB_CLIPCHILDREN );
369 :
370 0 : pWindow->SetText(OUString("VCL Image Test"));
371 :
372 0 : pWindow->LoadGraphic( sImageFile );
373 0 : pWindow->mpFixedBitmap = new FixedBitmap( pWindow );
374 0 : pWindow->mpFixedBitmap->SetPosPixel( Point( 0, 0 ) );
375 0 : pWindow->mpFixedBitmap->Show();
376 :
377 0 : pWindow->Hide();
378 0 : pWindow->Show();
379 :
380 0 : Execute();
381 : }
382 0 : catch (const uno::Exception &e)
383 : {
384 0 : fprintf(stderr, "fatal error: %s\n", OUStringToOString(e.Message, osl_getThreadTextEncoding()).getStr());
385 0 : nRet = EXIT_FAILURE;
386 : }
387 0 : catch (const std::exception &e)
388 : {
389 0 : fprintf(stderr, "fatal error: %s\n", e.what());
390 0 : nRet = EXIT_FAILURE;
391 : }
392 0 : }
393 :
394 0 : void IconTestApp::DoItWithOpenGL(const OUString& sImageFile)
395 : {
396 : try
397 : {
398 0 : MyOpenGLWorkWindow *pWindow = new MyOpenGLWorkWindow( NULL, WB_APP | WB_STDWORK | WB_SIZEABLE | WB_CLOSEABLE | WB_CLIPCHILDREN );
399 :
400 0 : pWindow->SetText(OUString("OpenGL Image Test"));
401 :
402 0 : pWindow->LoadGraphic( sImageFile );
403 :
404 0 : Size aGraphicSize( pWindow->maGraphic.GetSizePixel() );
405 0 : float aspect = ((float) aGraphicSize.Width()) / aGraphicSize.Height();
406 : SAL_INFO("vcl.icontest", sImageFile << ": size: " << aGraphicSize << " aspect: " << aspect);
407 :
408 0 : pWindow->Hide();
409 0 : pWindow->Show();
410 :
411 0 : Execute();
412 : }
413 0 : catch (const uno::Exception &e)
414 : {
415 0 : fprintf(stderr, "fatal error: %s\n", OUStringToOString(e.Message, osl_getThreadTextEncoding()).getStr());
416 0 : nRet = EXIT_FAILURE;
417 : }
418 0 : catch (const std::exception &e)
419 : {
420 0 : fprintf(stderr, "fatal error: %s\n", e.what());
421 0 : nRet = EXIT_FAILURE;
422 : }
423 0 : }
424 :
425 0 : void vclmain::createApplication()
426 : {
427 0 : static IconTestApp aApp;
428 0 : }
429 :
430 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|