1
\$\begingroup\$

I develop my game most of time under ArchLinux. I have decided to try it on the Ubuntu 16.04 recently. The situation I came across was really strange:

  1. No glGetError()s at all.
  2. No errors, warnings, anything bad in the gl debug output.
  3. All assertions that I made for all bad situations did not trigger.
  4. glClear successfully cleared the buffers I specified, but:
  5. glDraw* did not draw anything.

Luckily I have found a solution which was to set glViewport. However, I don't quite understand, why is it necessary for drawing in Ubuntu but not necessary in ArchLinux? The also difference is between graphics adaptors: on archlinux I use NVIDIA 1060, on Ubuntu I use integrated HD Graphics P530 (Skylake GT 2).

If it is important, I use SDL2 with opengl 4.4.

\$\endgroup\$
  • \$\begingroup\$ It's important for you to realize that the OS is not relevant here; OpenGL is implemented by your GPU vendor in their drivers, so the important factors are your GPUs and their drivers. Where the OS might be interesting is if your GPU vendor has different codebases for different OSs, but otherwise it's not useful information. \$\endgroup\$ – Maximus Minimus Nov 28 '17 at 9:37
  • \$\begingroup\$ @MaximusMinimus this could be the answer to the question. \$\endgroup\$ – Victor Polevoy Nov 28 '17 at 13:48
2
\$\begingroup\$

You've got two good answers already but they may be hard to understand for a beginner so I'll tell you why do we really need glViewport function.

In typical rendering it may seem to have no sense - you just create some window or render target and draw on it, right? I'd say that 95+% of apps works that way.

But let's say your're writing an app like 3DS MAX, where you have you window split into 4 distinct renderings. You remember your current split position and you manage Mouse events, so when you hover over the split bar you may change mouse cursor to resizing one, etc. When you drag your split bar you remember its new position and so on.

When you want to render your 3D views you cal glViewport with position and size of your first 3D-subwindow and run typical GL commands to draw here. OpenGL will automatically scale the rendering so it fits into the given viewport. You do the same for the rest of your viewports and at the end you get one window with few different renderings, each with its own parameters. This way you can have as many distinct renderings on single window/render target as you want.

Why it didn't work on one machine?

GPUs and their drivers have a lot of implementation details and differences so in general you need to get used to such issues. One simple example: In GLSL shader you can create a 2D zero vector like that: vec2(0.0,0.0), you may try also to write one value: vec2(0.0) and with this code some drivers will treat it as previous version while others will return error and render nothing. Bear in mind that drivers from two vendors will differ more that two versions of the same driver, so it's a good idea to test your code on nVidia, ATI and Intel GPUs. In this very case I suspect that in nVidia drivers, when you don't set the vieport by yourself they assume you want to use entire render target, while Intel drivers don't do that.

\$\endgroup\$
1
\$\begingroup\$

glViewport lets opengl know how to map the NDC coordinates to the framebuffer coordinates.

By default it is set to the full size of the screen buffer. So you only need to call it when the window gets resized or you actually want to change it.

\$\endgroup\$
  • \$\begingroup\$ Or when rendering to a framebuffer, assuming the size of the window is different. \$\endgroup\$ – HolyBlackCat Aug 23 '17 at 17:58
1
\$\begingroup\$

glViewport specifies the affine transformation of xx and yy from normalized device coordinates to window coordinates. Let (xnd,ynd)xndynd be normalized device coordinates. Then the window coordinates (xw,yw)xwyw are computed as follows:

  • 'xw=(xnd+1)(width2)+xxw=xnd+1⁢width2+x'
  • 'yw=(ynd+1)(height2)+yyw=ynd+1⁢height2+y'

Viewport width and height are silently clamped to a range that depends on the implementation. To query this range, call glGet with argument 'GL_MAX_VIEWPORT_DIMS'

The x and y parameters specify the lower left corner of the viewport in pixels, while width and height specify the width and height of the Viewport

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.