Texture mapping a circle made using GL_POLYGON - opengl

I am trying to map a texture to a circle using GL_POLYGON using this code:
void drawCircleOutline(Circle c, int textureindex)
{
float angle, radian, x, y; // values needed by drawCircleOutline
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureLib[textureindex]);
glBegin(GL_POLYGON);
for (angle=0.0; angle<360.0; angle+=2.0)
{
radian = angle * (pi/180.0f);
x = (float)cos(radian) * c.r + c.pos.x;
y = (float)sin(radian) * c.r + c.pos.y;
glTexCoord2f(x, y);
glVertex2f(x, y);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
it looks like this when running.
And should look like this:

Try:
radian = angle * (pi/180.0f);
xcos = (float)cos(radian);
ysin = (float)sin(radian);
x = xcos * c.r + c.pos.x;
y = ysin * c.r + c.pos.y;
tx = xcos * 0.5 + 0.5;
ty = ysin * 0.5 + 0.5;
glTexCoord2f(tx, ty);
glVertex2f(x, y);

Related

OpenGL Resize Window -> objects are “moved / translated”

When the resize event of the window is called, the objects are moved out of the viewport / screen.
The link below is a video to show what happening is:
https://drive.google.com/file/d/1dBnOqBDUBNCQrwr7ChFlpS8vbBQ6wfKh/view?usp=sharing
I just found out that it just happens whin using QT Windowing. It did not happend with GLFW... wooow
I use the following code:
void Renderer::resize(int width, int height) {
RendererSettings* settings = RendererSettings::getInstance();
settings->setSize(width, height);
glViewport(0, 0, width, height);
if (camera != nullptr)
{
float aspectRatio = float(width) / float(height);
camera->updateProjectionPerspectiveAspect(aspectRatio);
}
}
I do not change the camera anymore.
The updateProjectionPerspectiveAspect is the same of glFrustum(FoV, aspect, near, far). but the data others parameters are kept the same.
void Camera::setProjectionPerspective(float fieldOfView, float aspectRatio, float near, float far) {
this->fieldOfView = fieldOfView;
this->aspectRatio = aspectRatio;
this->nearFrustum = near;
this->farFrustum = far;
float xmin, xmax, ymin, ymax; // Dimensions of near clipping plane
float xFmin, xFmax, yFmin, yFmax; // Dimensions of far clipping plane
// Do the Math for the near clipping plane
ymax = near * tanf(float(fieldOfView * PI_DIV_360));
ymin = -ymax;
xmin = ymin * aspectRatio;
xmax = -xmin;
// Construct the projection matrix
projectionMatrix = Mat4f::identity();
projectionMatrix[0] = (2.0f * near) / (xmax - xmin);
projectionMatrix[5] = (2.0f * near) / (ymax - ymin);
projectionMatrix[8] = (xmax + xmin) / (xmax - xmin);
projectionMatrix[9] = (ymax + ymin) / (ymax - ymin);
projectionMatrix[10] = -((far + near) / (far - near));
projectionMatrix[11] = -1.0f;
projectionMatrix[14] = -((2.0f * far * near) / (far - near));
projectionMatrix[15] = 0.0f; }
Camera parameter is not null and this event "resize" is called some times during the resizing. The parameters width and height are corrects.
I think your projection Matrix is wrong, mainly because you don't use the variable aspectRatio at all, but the way you do it it looks correct..? (So it's just me guessing :P)
Here is how i did my projection Matrix in C using an aspect ratio argument, maybe this helps
mat4 set_perspective_matrix(GLfloat fov, GLfloat aspect, GLfloat nearPlane, GLfloat farPlane)
{
mat4 p;
GLfloat f = 1.0/ tan(fov * 3.1415926/360.0);
GLfloat c1 = -(farPlane + nearPlane) / (farPlane - nearPlane);
GLfloat c2 = -(2.0 * farPlane * nearPlane) / (farPlane - nearPlane);
p._[0] = f/aspect;
p._[1] = 0.0;
p._[2] = 0.0;
p._[3] = 0.0;
p._[4] = 0.0;
p._[5] = f;
p._[6] = 0.0;
p._[7] = 0.0;
p._[8] = 0.0;
p._[9] = 0.0;
p._[10] = c1;
p._[11] = c2;
p._[12] = 0.0;
p._[13] = 0.0;
p._[14] =-1.0;
p._[15] = 0.0;
return p;
}
Here is a good article describing the setup of a projection matrix: The Perspective Matrix
The problem was on QT Windowing. It was solved using the following code to resize:
void QtOpenGLRenderer::resizeEvent(QResizeEvent* event) {
QSize size = event->size();
if (event->oldSize().isEmpty())
{
initialScreenSize = size;
return;
}
size = parentWidget->size();
float deltaX = size.width() - initialScreenSize.width();
float deltaY = size.height() - initialScreenSize.height();
renderer->resize(size.width() - deltaX, size.height() - deltaY); }

Opengl Circular Rotation

I'd like to create a circular rotation for the rays around the sun.
to make it look like this
How I draw curves on the canvas.
GLfloat ctrlpoints[4][3];
void drawCurves(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4) {
ctrlpoints[0][0]=x1;
ctrlpoints[0][1]=y1;
ctrlpoints[0][2]=50.0f;
ctrlpoints[1][0]=x2;
ctrlpoints[1][1]=y2;
ctrlpoints[1][2]=50.0f;
ctrlpoints[2][0]=x3;
ctrlpoints[2][1]=y3;
ctrlpoints[2][2]=50.0f;
ctrlpoints[3][0]=x4;
ctrlpoints[3][1]=y4;
ctrlpoints[3][2]=50.0f;
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
int i;
glLineWidth(3.0f);
//glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
}
How Rays are made.
void Ray (float x, float y, float s){
glColor3f(1, 1, 0);
drawCurves(x, y, x+4*s, y-7*s, x-6*s, y-27*s, x-3*s, y-30*s);
glColor3f(1, 1, 0);
drawCurves(x, y, x+7*s, y-7*s, x+1*s, y-27*s, x+4*s, y-30*s);
}
How I design the sun motive.
void Rays(float x, float y, float radius, int num_segments){
float i;
double twicePi = 2.0 * 3.142;
for (i = 0; i <= num_segments; i++) {
Ray((x+ (radius * cos((i * twicePi / num_segments))))
,(y + (radius * sin((i * twicePi / num_segments))))
,0.3);
}
}
Tried glRotation but it rotates the whole flag, I just want to rotate the rays.
You have to caluclate the direction of the ray and you have to set up the points of the curves in the direction of the ray. In computer graphics rotations are commonly calculated by matrices. But since this is a simple 2D graphic, and you have already written most of the code, the computation can be done without matrices.
You have to calculate the direction of the ray and the counterclockwise rotated orthonormal direction. This 2 directions ar the local x-axis and local y-axis of the geometry of single ray. The coordinates of the curves of a ray must be plotted along this axis.
void Rays(float x, float y, float radius, int num_segments)
{
const float twicePi = 2.0f * 3.141593f;
for (int i = 0; i <= num_segments; ++i)
{
float angle = (float)i * twicePi / num_segments;
float dir_x = sin( angle );
float dir_y = cos( angle );
Ray( dir_x, dir_y, radius, 0.3 );
}
}
float dot( float a[], float b[2] )
{
return a[0]*b[0] + a[1]*b[1];
}
void Ray ( float xx, float xy, float r, float l)
{
float yx = -xy, yy = xx; // (xx, xy) counterclockwise rotated = (-xy, xx)
float xc[]{ xx, yx };
float yc[]{ xy, yy };
float p0[]{ xx * r, xy * r };
float p1[]{ -7.0f * s, 4.0f * s };
float p2[]{ -27.0f * s, -6.0f * s };
float p3[]{ -30.0f * s, -3.0f * s };
float p4[]{ -7.0f * s, 7.0f * s };
float p5[]{ -27.0f * s, 1.0f * s };
float p6[]{ -30.0f * s, 4.0f * s };
glColor3f(1, 1, 0);
drawCurves(
p0[0], p0[1],
p0[0] + dot(xc, p1[0]), p0[1] + dot(yc, p1[1]),
p0[0] + dot(xc, p2[0]), p0[1] + dot(yc, p2[1]),
p0[0] + dot(xc, p3[0]), p0[1] + dot(yc, p3[1]) );
drawCurves(
p0[0], p0[1],
p0[0] + dot(xc, p4[0]), p0[1] + dot(yc, p4[1]),
p0[0] + dot(xc, p5[0]), p0[1] + dot(yc, p5[1]),
p0[0] + dot(xc, p6[0]), p0[1] + dot(yc, p6[1]) );
}

Cylinder drawn with triangles in OpenGL

It's drawing a cylinder with stacks and edges but the problem is that stacks are connected to one point instead of a new one.
Maybe a picture will show it better:
And here's how I'm rendering the side because disks are rendered separately:
for (int i = 1; i <= height; ++i) {
for (int j = 0; j < edges; ++j) {
glBegin(GL_TRIANGLES); {
// 0 bottom
glVertex3f(x + radius * cos(theta + interval), y , z + radius * sin(theta + interval));
// 1 bottom
glVertex3f(x + radius * cos(theta), y + y_value * i, z + radius * sin(theta));
// 2 top
glVertex3f(x + radius * cos(theta), y + y_value * i, z + radius * sin(theta));
// 2 top
glVertex3f(x + radius * cos(theta), y + y_value * i, z + radius * sin(theta));
// 3 top
glVertex3f(x + radius * cos(theta + interval), y + y_value * i, z + radius * sin(theta + interval));
// 0 bottom
glVertex3f(x + radius * cos(theta + interval), y , z + radius * sin(theta + interval));
} glEnd();
theta += interval;
}
theta = 0.0;
}
I've been trying to solve it for days and I run out of ideas. Do you know what I am doing wrong?
UPDATE:
I've changed it to be render with quads using ybungalobill advice. Now I'm struggling with UV mapping. And hopefully once this part is solved it'll be easy enough to convert into triangles.
That's what I have now:
And that's the code I'm using for UV mapping:
u = 0.0,
v = 0.0,
u_inter = 1.0 / edges,
v_inter = 1.0 / y_value; // (y_value = height / edges)
for (int i = 1; i <= height; ++i) {
for (int j = 0; j < edges; ++j) {
glBegin(GL_QUAD_STRIP); {
// 0 bottom
glTexCoord2f(u, v);
// 1 bottom
glTexCoord2f(u + u_inter, v);
// 2 top
glTexCoord2f(u + u_inter, v + v_inter);
// 3 top
glTexCoord2f(u, v + v_inter);
} glEnd();
theta += interval;
u += u_inter;
}
v += v_inter;
theta = 0.0;
}
float y0 = y + y_value * (i-1);
float y1 = y + y_value * i;
// 0 bottom
glVertex3f(x + radius * cos(theta + interval), y0, z + radius * sin(theta + interval));
// 1 bottom
glVertex3f(x + radius * cos(theta), y0, z + radius * sin(theta));
// 2 top
glVertex3f(x + radius * cos(theta), y1, z + radius * sin(theta));
// 2 top
glVertex3f(x + radius * cos(theta), y1, z + radius * sin(theta));
// 3 top
glVertex3f(x + radius * cos(theta + interval), y1, z + radius * sin(theta + interval));
// 0 bottom
glVertex3f(x + radius * cos(theta + interval), y0, z + radius * sin(theta + interval));

Rotation: Quaternion to matrix

I am trying to display a 360 panorama using an IMU for head tracking.
Yaw works correctly but the roll and pitch are reverse. I also notice that the pitch contains some roll (and maybe vice-versa).
I am receiving (W, X, Y, Z) coordinate from the IMU that I am storing in an array as X, Y, Z, W.
The next step is converting the quaternion to a rotation matrix. I have looked at many examples, and can't seem to find anything wrong with the following code:
static GLfloat rotation[16];
// Quaternion (x, y, z, w)
static void quaternionToRotation(float* quaternion)
{
// Normalize quaternion
float magnitude = sqrt(quaternion[0] * quaternion[0] +
quaternion[1] * quaternion[1] +
quaternion[2] * quaternion[2] +
quaternion[3] * quaternion[3]);
for (int i = 0; i < 4; ++i)
{
quaternion[i] /= magnitude;
}
double xx = quaternion[0] * quaternion[0], xy = quaternion[0] * quaternion[1],
xz = quaternion[0] * quaternion[2], xw = quaternion[0] * quaternion[3];
double yy = quaternion[1] * quaternion[1], yz = quaternion[1] * quaternion[2],
yw = quaternion[1] * quaternion[3];
double zz = quaternion[2] * quaternion[2], zw = quaternion[2] * quaternion[3];
// Column major order
rotation[0] = 1.0f - 2.0f * (yy + zz);
rotation[1] = 2.0f * (xy - zw);
rotation[2] = 2.0f * (xz + yw);
rotation[3] = 0;
rotation[4] = 2.0f * (xy + zw);
rotation[5] = 1.0f - 2.0f * (xx + zz);
rotation[6] = 2.0f * (yz - xw);
rotation[7] = 0;
rotation[8] = 2.0f * (xz - yw);
rotation[9] = 2.0f * (yz + xw);
rotation[10] = 1.0f - 2.0f * (xx + yy);
rotation[11] = 0;
rotation[12] = 0;
rotation[13] = 0;
rotation[14] = 0;
rotation[15] = 1;
}
The rotation matrix is then used in the draw call as such:
static void draw()
{
// Get IMU quaternion
float* quaternion = tracker.getTrackingData();
if (quaternion != NULL)
{
quaternionToRotation(quaternion);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
// TODO: Multiply initialRotation quaternion with IMU quaternion
glMultMatrixf(initialRotation); // Initial rotation to point forward
glMultMatrixf(rotation); // Rotation based on IMU
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
gluSphere(quad, 0.1, 50, 50);
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
glFlush();
glutSwapBuffers();
}
I tried to set all but one fields in the quaternion to 0, and I notice that they all work individually, except roll and pitch is swapped around. I tried swapping X and Y but this does not seem to help.
Any help would be really appreciated. Please let me know as well if you have any steps that can let me debug my issue. Thanks!

How to set up (create) sliced cylinder in OpenGL

How would you create a cylinder such as this?
http://www.eicac.co.uk/Images/SLICED-CYLINDER.png
I am guessing gluCylinder is not an option?
create it with one ribbon and two fans
Lets assume that point [0, 0, 0] is at the center of the shape's base and Z-axis is up. Using constants from the Image.
bottom cap
A simple disc.
glBegin(GL_TRIANGLE_FAN)
glVertex3d(0.0, 0.0, 0.0) // center
for angle from 0 to π (whatever step)
double x = 0.5 * D * cos(angle);
double y = 0.5 * D * sin(angle);
glVertex3d(x, y, 0.0);
glEnd();
side wall
We need to calculate the actual slope function.
It will be of the form y = a * x + b and have points (0.0, H) and (0.5*D, H2).
Thus we have to solve for a and b. We have b = H and a = (H2 - H) / 0.5 * D
double a = (H2 - H) / 0.5 * D;
double b = H;
glBegin(GL_TRIANGLE_STRIP)
for angle from 0 to π (whatever step)
double x = 0.5 * D * cos(angle);
double y = 0.5 * D * sin(angle);
double height = a * x + b;
glVertex3d(x, y, 0.0);
glVertex3d(x, y, height);
glEnd();
top cap
We combine the previous steps and seal the top.
double a = (H2 - H) / 0.5 * D;
double b = H;
glBegin(GL_TRIANGLE_FAN)
glVertex3d(0.0, 0.0, H) // center
for angle from 0 to π (whatever step)
double x = 0.5 * D * cos(angle);
double y = 0.5 * D * sin(angle);
double height = a * x + b;
glVertex3d(x, y, height);
glEnd();