GLFW3/GLU 3D world space using static pipeline - c

In previous projects, I enabled depth testing used gluPerspective called once on startup to set up a 3D space. Currently, I am rendering a square between -0.5 and 0.5 with 0.0 as its origin after the 3D world has initialised with code below will cause a square to cover the entire screen:
glBegin(GL_QUADS);
{
glVertex3f(-0.5, -0.5, 0);
glVertex3f(-0.5, 0.5, 0);
glVertex3f(0.5, 0.5, 0);
glVertex3f(0.5, -0.5, 0);
}
glEnd();
What I am looking is a way to set the perspective so that shapes are rendered in world space. For example, the snippet below should cause a square of 200x200 to be rendered:
glBegin(GL_QUADS);
{
glVertex3f(-100, -100, 0);
glVertex3f(-100, 100, 0);
glVertex3f(100, 100, 0);
glVertex3f(100, -100, 0);
}
glEnd();
The code below is what I am currently using to initialise a 3D world.
// WINDOW_WIDTH = 1600, WINDOW_HEIGHT = 900
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(47, WINDOW_WIDTH / WINDOW_HEIGHT, 0.01, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
Have I missed any steps in setting up a 3D space and if gluPerspective is used to do this any suggestions why it is not working?
I am able to achieve this in 2D using ortho, it is important that the world is 3D.
Everything is being written in C using OpenGL and GLU up to 1.3 with my GLFW set up identical to this. Due to technical restraints, I am unable to use the modern pipeline.

First of all, the result of WINDOW_WIDTH / WINDOW_HEIGHT is 1, because WINDOW_WIDTH and WINDOW_HEIGHT are integral values. You have to perform a floating point division ((float)WINDOW_WIDTH / WINDOW_HEIGHT) to compute the correct aspect ratio.
At Perspective Projection the projection matrix describes the mapping from 3D points in the world as they are seen from of a pinhole camera, to 2D points of the viewport.
The projected size of an object on the viewport depends on its distance to the camera. The different size at different distances (depths) causes the perspective effect. The perspective projection matrix defines a Viewing frustum
The ratio of projected size and the distance to the camera depends on the field of view angle:
maxDim / cameraZ = tan(FOV / 2) * 2
So there is exactly 1 distance where an object with a length of 200 covers 200 pixel. For instance, If you have a filed of view angle of 90° then an object with a z distance of half the window height (height /2) and a vertical size of 200 covers 200 pixel (vertical) because tan(90° / 2) * 2 = 2.
When you use gluPerspective, then you define the field of view angle along the y axis. The field of view along the x axis depends on the aspect ratio. If the aspect ratio is set correctly, then the projection of a square which is parallel to the xy plane of the view is still a square.
Note, if you would use orthographic projection, then the size of the object is independent on the distance.

Related

Use values instead of -1...1 for OpenGL drawing shapes?

If I wanted to draw a plane in OpenGL, I would do something like the below:
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glEnd();
This draws a white plane that covers 50% of the canvas (from -0.5 to 0.5 on two axes). I want to use numbers instead, however. I don't want to use -1 to 1, but instead something like 0 to n, where n is the dimension of my canvas. For the above example, something like 250 to 750 on two axes on a 1000 pixel canvas rather than -0.5 to 0.5.
That's what the transformation matrices are for. In your case you'd set a ortho projection matrix with the limits as you desire. In your example case
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1000, 0, 1000, -1, 1);
would set up a viewing volume so that the boundaries are at 0,0 for the lower left corner and 1000,1000 for the upper right.
Note that this (and the code you've given) use the old, deprecated fixed function pipeline. You should drop that in favour of a shader based approach.

Texture do not rotate with OpenGL (C)

I am trying to rotate a texture extracted from a video frame (provided by ffmpeg), I have tried the following code :
glTexSubImage2D(GL_TEXTURE_2D,
0,
0,
0,
textureWidth,
textureHeight,
GL_RGBA,
GL_UNSIGNED_BYTE,
//s_pixels);
pFrameConverted->data[0]);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5,0.5,0.0);
glRotatef(90,0.0,0.0,1.0);
glTranslatef(-0.5,-0.5,0.0);
glMatrixMode(GL_MODELVIEW);
//glDrawTexiOES(-dPaddingX, -dPaddingY, 0, drawWidth + 2 * dPaddingX, drawHeight + 2 * dPaddingY);
glDrawTexiOES(0, 0, 0, drawWidth, drawHeight);
The image is not rotated, do you see the problem ?
From the GL_OES_draw_texture extension specification:
Note also that s, t, r, and q are computed for each fragment as part of DrawTex rendering. This implies that the texture matrix is ignored and has no effect on the rendered result.
You are trying to transform the texture coordinates using the fixed-function texture matrix, but like point sprites, those coordinates are generated per-fragment rather than per-vertex. Thus, that means that nothing you do to the texture matrix is ever going to affect the output of glDrawTexiOES (...).
Consider using a textured quad instead, those will pass through the traditional vertex processing pipeline.

OpenGL - circle not being drawn smooth

I am drawing a circle using OpenGL, with the set of calls being:
float delta_theta = 0.001;
glBegin(GL_POLYGON); // OR GL_LINE_LOOP
glEnable( GL_LINE_SMOOTH );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (angle = 0; angle < 2*3.1415; angle += delta_theta)
glVertex3f( radius*cos(angle), radius*sin(angle), 0 );
glEnd();
The problem is that the circle is not smooth. I am moving (translating) the circle along axes; at some points it becomes smooth, but mostly, it's like a blot, please see the attached screenshot.
Any suggestions as to what I could do to smoothen the circle?
I would suggest you not try to implement this with lines or a filled polygon for one thing.
Use a single GL_POINT and enable GL_POINT_SMOOTH. That will rasterize the point as a filled circle instead of the normal square. It will be much more efficient, provided you use a point size your implementation supports for anti-aliased points (often up to ~ 63.5 on NV implementations, more on others).

Drawing with high precision alpha blending

I need to blend together about 1 million semi-transparent rectangles, while being able to manage transparency accuracy by increment of 1e-6.
Typically, if my 1 millions rectangle would be drawn on top of each other, I want to have a resulting alpha value for these pixels of exactly 1.0 (0.5 for 500 000 rectangles, and so on).
Using the cairo library, it would ideally look like:
const int NB_RECT = 1000000;
//[...]
cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
cairo_set_source_rgba(cr, 1.0, 0, 0, 1.0/NB_RECT);
for(int i = 0 ; i < NB_RECT ; i++) {
//[...]
cairo_rectangle(cr, x, y, w, h);
cairo_fill(cr);
}
// [...]
This does not work because below alpha~=0.01, the drawing commands seem to be simply discarded (probably due to the internal representation of colors inside cairo).
Could you suggest a drawing library that handle high precision transparency, or possible workaround?

How do I fill the screen with a rectangle in OpenGL ortho mode?

I have a single 640x480 texture that needs to fill the screen. So far, I can make it work with a square texture, but not a rectangular one.
glViewport(0, 0, display->w, display->h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double aspectRatio = (double)display->w / (double)display->h;
if (display->w <= display->h)
glOrtho(-1, 1, -1 / aspectRatio, 1 / aspectRatio, -1, 1);
else
glOrtho(-1 * aspectRatio, 1 * aspectRatio, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
What modifications do I need to make so that it will fit any texture to the screen, regardless of its aspect ratio?
This may have some relevance.
Tiling texture bmp file as texture onto a rectangle in OpenGL?
You may wish to consider ARB extension texture rectangle as an alternative approach to (assuming glTexImage2D?) http://glprogramming.com/red/chapter09.html

Resources