opengl.sgml 16.2 KB
Newer Older
1 2 3
  <chapter id="opengl">
    <title>Wine and OpenGL</title>

John R. Sheets's avatar
John R. Sheets committed
4 5 6 7 8
    <para>
      Written by &name-lionel-ulmer; <email>&email-lionel-ulmer;</email>,
      last modification : 2000/06/13
    </para>
    <para>
9
      (Extracted from <filename>wine/documentation/opengl</filename>)
John R. Sheets's avatar
John R. Sheets committed
10
    </para>
11 12

    <sect1 id="opengl-required">
John R. Sheets's avatar
John R. Sheets committed
13
      <title>What is needed to have OpenGL support in Wine</title>
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

      <para>
        Basically, if you have a Linux OpenGL ABI compliant libGL
        (<ulink url="http://oss.sgi.com/projects/ogl-sample/ABI/">
          http://oss.sgi.com/projects/ogl-sample/ABI/</ulink>)
        installed on your computer, you should everything that is
        needed.
      </para>
      <para>
        To be more clear, I will detail one step after another what
        the <command>configure</command> script checks.
      </para>
      <para>
        If, after Wine compiles, OpenGL support is not compiled in,
        you can always check <filename>config.log</filename> to see
        which of the following points failed.
      </para>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
33
        <title>Header files</title>
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

        <para>
          The needed header files to build OpenGL support in Wine are :
        </para>

        <variablelist>
          <varlistentry>
            <term><filename>gl.h:</filename></term>
            <listitem>
              <para>the definition of all OpenGL core functions, types and enumerants</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term><filename>glx.h:</filename></term>
            <listitem>
              <para>how OpenGL integrates in the X Window environment</para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term><filename>glext.h:</filename></term>
            <listitem>
              <para>the list of all registered OpenGL extensions</para>
            </listitem>
          </varlistentry>
        </variablelist>

        <para>
          The latter file (<filename>glext.h</filename>) is, as of
          now, not necessary to build Wine. But as this file can be
          easily obtained from SGI 
          (<ulink url="http://oss.sgi.com/projects/ogl-sample/ABI/glext.h">
            http://oss.sgi.com/projects/ogl-sample/ABI/glext.h</ulink>),
          and that all OpenGL should provide one, I decided to keep it here.
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
71
        <title>OpenGL library thread-safety</title>
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

        <para>
          After that, the script checks if the OpenGL library relies
          or not on the pthread library to provide thread safety (most
          'modern' OpenGL libraries do).
        </para>
        <para>
          If the OpenGL library explicitely links in libpthread (you
          can check it with a <command>ldd libGL.so</command>), you
          need to force OpenGL support by starting
          <command>configure</command> with the
          <parameter>--enable-opengl</parameter> flag.
        </para>
        <para>
          The reason to this is that Wine contains some hacks done by
          Ove to cohabit with pthread that are known to work well in
          most of the cases (glibc 2.1.x). On the other hand, we never
          got Wine to work with glibc 2.0.6. Thus, I deemed preferable
          to play it safe : by default, I suppose that the hack won't
          work and that it's the user's responsability to enable it.
        </para>
        <para>
          Anyway, it should be pretty safe to build with
          <parameter>--enable-opengl</parameter>.
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
100
        <title>OpenGL library itself</title>
101 102 103 104 105 106 107 108 109 110

        <para>
          To check for the presence of 'libGL' on the system, the
          script checks if it defines the
          <function>glXCreateContext</function> function. There should
          be no problem here.
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
111
        <title>glXGetProcAddressARB function</title>
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

        <para>
          The core of Wine's OpenGL implementation (at least for all
          extensions) is the <function>glXGetProcAddressARB</function>
          function. Your OpenGL library needs to have this function
          defined for Wine to be able to support OpenGL.
        </para>
        <para>
          If your library does not provide it, you are out of luck.
        </para>
        <note>
          <para>
            this is not completely true as one could rewrite a
            <function>glXGetProcAddressARB</function> replacement
            using <function>dlopen</function> and friends, but well,
            telling people to upgrade is easier :-).
          </para>
        </note>
      </sect2>
    </sect1>

    <sect1 id="opengl-configure">
John R. Sheets's avatar
John R. Sheets committed
134
      <title>How to configure</title>
135 136 137 138 139 140 141 142 143 144 145 146

      <para>
        Configuration is quite easy : once OpenGL support has been
        built in Wine, this internal OpenGL driver will be used each
        time an application tries to load
        <filename>opengl32.dll</filename>.
      </para>
      <para>
        Due to restrictions (that do not exist in Windows) on OpenGL
        contexts, if you want to prevent the screen to flicker when
        using OpenGL applications (all games are using double-buffered
        contexts), you need to set the following option in your
147
        <filename>~/.wine/config</filename> file
148 149 150 151 152 153 154 155 156 157 158 159
        in the [x11drv] section :
      </para>
      <programlisting>
DesktopDoubleBuffered = Y
      </programlisting>
      <para>
        and to run Wine with the <parameter>--desktop</parameter>
        option.
      </para>
    </sect1>

    <sect1 id="opengl-works">
John R. Sheets's avatar
John R. Sheets committed
160
      <title>How it all works</title>
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

      <para>
        The core OpenGL function calls are the same between Windows
        and Linux. So what is the difficulty to support it in Wine ?
        Well, there are two different problems :
      </para>

      <orderedlist>
        <listitem>
          <para>
            the interface to the windowing system is different for
            each OS. It's called 'GLX' for Linux (well, for X Window)
            and 'wgl' for Windows. Thus, one need first to emulate one
            (wgl) with the other (GLX).
          </para>
        </listitem>
        <listitem>
          <para>
            the calling convention between Windows (the 'Pascal'
            convention or 'stdcall') is different from the one used on
            Linux (the 'C' convention or 'cdecl'). This means that
            each call to an OpenGL function must be 'translated' and
            cannot be used directly by the Windows program.
          </para>
        </listitem>
      </orderedlist>

      <para>
        Add to this some braindead programs (using GL calls without
        setting-up a context or deleting three time the same context)
        and you have still some work to do :-)
      </para>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
195
        <title>The Windowing system integration</title>
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

        <para>
          This integration is done at two levels : 
        </para>

        <orderedlist>
          <listitem>
            <para>
              At GDI level for all pixel format selection routines (ie
              choosing if one wants a depth / alpha buffer, the size
              of these buffers, ...) and to do the 'page flipping' in
              double buffer mode. This is implemented in
              <filename>graphics/x11drv/opengl.c</filename> (all these
              functions are part of Wine's graphic driver function
              pointer table and thus could be reimplented if ever Wine
              works on another Windowing system than X).
            </para>
          </listitem>
          <listitem>
            <para>
              In the <filename>OpenGL32.DLL</filename> itself for all
              other functionalities (context creation / deletion,
              querying of extension functions, ...). This is done in
              <filename>dlls/opengl32/wgl.c</filename>.
            </para>
          </listitem>
        </orderedlist>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
226
        <title>The thunks</title>
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318

        <para>
          The thunks are the Wine code that does the calling
          convention translation and they are auto-generated by a Perl
          script. In Wine's CVS tree, these thunks are already
          generated for you. Now, if you want to do it yourself, there
          is how it all works....
        </para>
        <para>
          The script is located in <filename>dlls/opengl32</filename>
          and is called <command>make_opengl</command>. It requires
          Perl5 to work and takes two arguments :
        </para>

        <orderedlist>
          <listitem>
            <para>
              The first is the path to the OpenGL registry. Now, you
              will all ask 'but what is the OpenGL registry ?' :-)
              Well, it's part of the OpenGL sample implementation
              source tree from SGI (more informations at this URL :
              <ulink url="http://oss.sgi.com/projects/ogl-sample/">
                http://oss.sgi.com/projects/ogl-sample/</ulink>. 
            </para>
            <para>
              To summarize, these files contain human-readable but
              easily parsed information on ALL OpenGL core functions
              and ALL registered extensions (for example the
              prototype, the OpenGL version, ...).
            </para>
          </listitem>
          <listitem>
            <para>
              the second is the OpenGL version to 'simulate'. This
              fixes the list of functions that the Windows application
              can link directly to without having to query them from
              the OpenGL driver. Windows is based, for now, on OpenGL
              1.1, but the thunks that are in the CVS tree are
              generated for OpenGL 1.2.
            </para>
            <para>
              This option can have three values:
              <literal>1.0</literal>, <literal>1.1</literal> and
              <literal>1.2</literal>.
            </para>
          </listitem>
        </orderedlist>

        <para>
          This script generates three files :
        </para>

        <orderedlist>
          <listitem>
            <para>
              <filename>opengl32.spec</filename> gives Wine's linker
              the signature of all function in the
              <filename>OpenGL32.DLL</filename> library so that the
              application can link them. Only 'core' functions are
              listed here.
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>opengl_norm.c</filename> contains all the
              thunks for the 'core' functions. Your OpenGL library
              must provide ALL the function used in this file as these
              are not queried at run time.
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>opengl_ext.c</filename> contains all the
              functions that are not part of the 'core' functions.
              Contrary to the thunks in
              <filename>opengl_norm.c</filename>, these functions do
              not depend at all on what your libGL provides. 
            </para>
            <para>
              In fact, before using one of these thunks, the Windows
              program first needs to 'query' the function pointer. At
              this point, the corresponding thunk is useless. But as
              we first query the same function in libGL and store the
              returned function pointer in the thunk, the latter
              becomes functional.
            </para>
          </listitem>
        </orderedlist>
      </sect2>
    </sect1>

    <sect1 id="opengl-problems">
John R. Sheets's avatar
John R. Sheets committed
319
      <title>Known problems - shortcomings</title>
320 321

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
322
        <title>Missing GLU32.DLL</title>
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

        <para>
          GLU is a library that is layered upon OpenGL. There is a
          100% correspondence between the
          <filename>libGLU.so</filename> that is used on Linux and
          <filename>GLU32.DLL</filename>.
        </para>
        <para>
          As for the moment, I did not create a set of thunks to support this
          library natively in Wine (it would easy to do, but I am waiting for
          a better solution than adding another autogenerated thunk file), you
          can always download anywhere on the net (it's free) a
          <filename>GLU32.DLL</filename> file (by browsing, for example,
          <ulink url="http://ftpsearch.lycos.com/">
            http://ftpsearch.lycos.com/</ulink>).
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
342
        <title>OpenGL not detected at configure time</title>
343 344 345 346 347 348 349 350

        <para>
          See section (I) for a detailed explanation of the
          <filename>configure</filename> requirements.
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
351
        <title>When running an OpenGL application, the screen flickers</title>
352 353 354 355 356 357 358 359

        <para>
          See section (II) for how to create the context
          double-buffered and thus preventing this flicker effect.
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
360
        <title>Wine gives me the following error message : </title>
361 362 363

        <screen>
Extension defined in the OpenGL library but NOT in opengl_ext.c...
John R. Sheets's avatar
John R. Sheets committed
364
Please report (&email-lionel-ulmer;) !
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
        </screen>

        <para>
          This means that the extension requested by the application
          is found in the libGL used by Linux (ie the call to
          <function>glXGetProcAddressARB</function> returns a
          non-<constant>NULL</constant> pointer) but that this string
          was NOT found in Wine's extension registry.
        </para>
        <para>
          This can come from two causes :
        </para>

        <orderedlist>
          <listitem>
            <para>
              The <filename>opengl_ext.c</filename> file is too old
              and needs to be generated again.
            </para>
          </listitem>
          <listitem>
            <para>
              Use of obsolete extensions that are not supported
              anymore by SGI or of 'private' extensions that are not
              registered. An example of the former are
              <function>glMTexCoord2fSGIS</function> and
              <function>glSelectTextureSGIS</function> as used by
              Quake 2 (and apparently also by old versions of Half
              Life). If documentation can be found on these functions,
              they can be added to Wine's extension set.
            </para>
          </listitem>
        </orderedlist>

        <para>
          If you have this, run with <parameter>--debugmsg
            +opengl</parameter> and send me
John R. Sheets's avatar
John R. Sheets committed
402
          <email>&email-lionel-ulmer;</email> the TRACE.
403 404 405 406
        </para>
      </sect2>

      <sect2>
John R. Sheets's avatar
John R. Sheets committed
407
        <title><filename>libopengl32.so</filename> is built but it is still not working</title>
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456

        <para>
          This may be caused by some missing functions required by
          <filename>opengl_norm.c</filename> but that your Linux
          OpenGL library does not provide.
        </para>
        <para>
          To check for this, do the following steps :
        </para>

        <orderedlist>
          <listitem>
            <para>
              create a dummy <filename>.c</filename> file :
            </para>
            <programlisting>
int main(void) {
    return 0;
}
            </programlisting>
          </listitem>
          <listitem>
            <para>
              try to compile it by linking both libwine and
              libopengl32 (this command line supposes that you
              installed the Wine libraries in
              <filename>/usr/local/lib</filename>, YMMV) :
            </para>
            <programlisting>
gcc dummy.c -L/usr/local/lib -lwine -lopengl32
            </programlisting>
          </listitem>
          <listitem>
            <para>
              if it works, the problem is somewhere else (and you can
              send me an email). If not, you could re-generate the
              thunk files for OpenGL 1.1 for example (and send me your
              OpenGL version so that this problem can be detected at
              configure time).
            </para>
          </listitem>
        </orderedlist>
      </sect2>
    </sect1>
  </chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
John R. Sheets's avatar
John R. Sheets committed
457
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
458 459
End:
-->