Why drawing a line in OpenGL is not working? [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last month.
Improve this question
GLfloat vertices[NUM_VERTICES][3] = {
{ -0.5, -0.4, 0.0 },
{ 0.5, -0.4, 0.0 },
{ 0.5, 0.4, 0.0 },
{ 0.0, 0.8, 0.0 },
{ -0.5, 0.4, 0.0 }
};
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
for (int i = 0; i < NUM_VERTICES; i++) {
glColor3fv(colors[i]);
glVertex3fv(vertices[i]);
}
glEnd();
glutSwapBuffers();
glClear(GL_COLOR_BUFFER_BIT);
//glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glColor3ub(1.0, 1.0, 1.0);
glLineWidth(10);
glBegin(GL_LINES);
glVertex2f(0.0, -0.4);
glVertex2f(0.0, 0.8);
glEnd();
}
I drew a pentagon using OpenGL. I want to draw a line from one point to another inside the pentagon but it doesn't work. How to make it work?

glClear clears the entire framebuffer and must be called once before drawing all of the geometry. If you call it in between, all previous drawings will be cleared. glutSwapBuffers() swaps the buffers and updates the display and must be called after drawing all the objects in the scene:
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
for (int i = 0; i < NUM_VERTICES; i++) {
glColor3fv(colors[i]);
glVertex3fv(vertices[i]);
}
glEnd();
glColor3ub(1.0, 1.0, 1.0);
glLineWidth(10);
glBegin(GL_LINES);
glVertex2f(0.0, -0.4);
glVertex2f(0.0, 0.8);
glEnd();
glutSwapBuffers();
}

Related

Why does my second 3D object not have four faces in Open GL

As the title says I'm tyring to model a simple giraffe out of arraycubes in open GL wiht C++, now I got the concepts done, but ran into an issue, when I start on the neck for some reaosn I lose 5 out of the 6 faces of my cube, the example I'm following doesn't result in this. I linked a small video below to show the visual result and I'm wondering what might be causing this. If there's an easier way to go about this as well please do let me know.
Visual Result
Code Sample
#include <glut.h>
float angle[4];
GLfloat corners[8][3] = { {-0.5,0.5,-0.5},{0.5,0.5,-0.5},
{0.5,-0.5,-0.5},{-0.5,-0.5,-0.5},
{-0.5,0.5,0.5},{0.5,0.5,0.5},
{0.5,-0.5,0.5},{-0.5,-0.5,0.5} };
void drawFace(int a, int b, int c, int d) {
glBegin(GL_POLYGON);
glVertex3fv(corners[a]);
glVertex3fv(corners[b]);
glVertex3fv(corners[c]);
glVertex3fv(corners[d]);
glEnd();
}
void ArrayCube() {
glColor3f(1.0, 1.0, 1.0);
drawFace(0, 3, 2, 1);
glColor3f(1.0, 1.0, 1.0);
drawFace(3, 0, 4, 7);
glColor3f(1.0, 1.0, 1.0);
drawFace(2, 3, 7, 6);
glColor3f(1.0, 1.0, 1.0);
drawFace(1, 2, 6, 5);
glColor3f(1.0, 1.0, 1.0);
drawFace(4, 5, 6, 7);
glColor3f(1.0, 1.0, 1.0);
drawFace(5, 4, 0, 1);
}
void LowerNeck()
{
glPushMatrix();
glTranslatef(0.5, 0.25, -0.125);
glScalef(0.0, 0.5, 0.25);
ArrayCube();
glPopMatrix();
}
void MainBody()
{
glPushMatrix();
glScalef(1.25, 0.25, 0.5);
ArrayCube();
glPopMatrix();
}
void DrawGiraffe()
{
glRotatef(angle[0], 0.0, 1.0, 0.0);
MainBody();
LowerNeck();
}
void rotate() {
angle[0] += 1.0;
if (angle[0] > 360) angle[0] -= 360;
glutPostRedisplay();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.6, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
DrawGiraffe();
glutSwapBuffers();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 2.5);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Basic 3D");
glutDisplayFunc(display);
init();
glutIdleFunc(rotate);
glutMainLoop();
}
For the second object (the neck) you apply a scale transformation on x that scales the x component of all the following drawn vertices to 0.0:
glScalef(0.0, 0.5, 0.25);
That 0.0 should've probably been a 1.0.
That's the reason you only see one quad in the render video: That's the quad/face (actually two faces) which still have a dimension in Y and Z. The faces that have a dimension on x are squished to degenerate quads and not displayed at all.

How to make qt designer custom QOpenGLWidget widget background be transparent?

I have create a custom qt designer widget which inherit from QOpenGLWidget. Everything is fine except I cannot get the widget background transparent.
Is there a way to fix this issue?
void MyOpenGl::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0,0,0,0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
}
void MyOpenGl::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45, (float)w/h, 0.01, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0,0,5,0,0,0,0,1,0);
}
void MyOpenGl::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f( 0.5, -0.5, 0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f( 0.0, 0.5, 0);
glEnd();
}
Do not call glClear() in your MyOpenGL::paintGL() function with GL_COLOR_BUFFER_BIT, that will make to rewrite the entire color buffer to the color set by glClearColor(). You can even omit it completely.

glColor doesn't change the color of other triangles in opengl

So I am still a newbie with opengl and I used this tutorial as a reference
https://www.youtube.com/watch?v=8p76pJsUP44
I am now trying to draw a set of 4 triangles that made up a square (it's my project assignment) and this is my code
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
using namespace std;
void changeViewPort(int w, int h)
{
glViewport(0, 0, w, h);
}
void draw() {
glBegin(GL_TRIANGLES);
glColor3f(0.0, 0.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); // top triangle
glVertex3f(-1.0,1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glColor3f(50.0, 50.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); // right triangle
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glColor3f(75.0, 75.0, 255.0);
glVertex3f(0.0, 0.0, 0.0);//bottom triangle
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glColor3f(50.0, 50.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); //left triangle
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd();
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
glutSwapBuffers();
}
int main(int argc, char* argv[]) {
// Initialize GLUT
glutInit(&argc, argv);
// Set up some memory buffers for our display
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// Set the window size
glutInitWindowSize(350, 300);
// Create the window with the title "Hello,GL"
glutCreateWindow("Hello, GL");
// Bind the two functions (above) to respond when necessary
glutReshapeFunc(changeViewPort);
glutDisplayFunc(render);
//glutDisplayFunc(draw);
// Very important! This initializes the entry points in the OpenGL driver so we can
// call all the functions in the API.
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW error");
return 1;
}
glutMainLoop();
return 0;
}
notice that in my draw function, I am just trying to create 4 different triangles with different shades of blue.
However, whenever this code is executed, only the top triangle is blue while the rest stays white
Does anyone know why this wouldnt work ? I even tried to create a for loop version of the draw function but it also didnt work
void draw() {
double x = 1.0;
double y = 1.0;
double coords[8] = { -x,y,x,y,x,-y,-x,-y };
for (int i = 0; i < 7; i=i+2) { // i = [0,2,4,6]
switch (i) {
case 0:
glColor3f(0, 0, 255);
break;
case 2:
glColor3f(50, 50, 255);
break;
case 4:
glColor3f(75, 75, 255);
break;
case 6:
glColor3f(50, 50, 255);
break;
}
if (i == 6) { //4th and 1st coordinate
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(coords[i], coords[i + 1], 0.0);
glVertex3f(coords[0], coords[1], 0.0);
glEnd();
}
else {
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(coords[i], coords[i + 1], 0.0);
glVertex3f(coords[i + 2], coords[i + 3], 0.0);
glEnd();
}
}
}
glColor3f takes color components in the [0, 1] range as input and not [0, 255] as currently used.
Colors in OpenGL are stored in [0, 1] range. Unsigned ints map onto that range linearly automatically, but floats are just straight up stored.
See https://msdn.microsoft.com/en-us/library/windows/desktop/dd318399(v=vs.85).aspx

How to use spot light in opengl

I am trying to learn how to use a spot light in OpenGL. I wish to shine a spot (torch) light from a point marked (lighpos), and shown as grey dot, onto the side of a GLUT teapot centered at (possph) in 3D space. I have attached an example where I have tried to do this but I cannot get the light to focus on the teapot. I am expecting a almost touch light focus based on the parameters I have tried to use.
Could someone point out what I have missed / mistake I have made.
Thanks
Stuart
#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>
GLfloat lighpos[] = { -300., 200., 250., 1.0 }; // Location of light
GLfloat possph[] = { -50., 350., 150. }; // Position of teapot
GLfloat ligdir[] = { 250., 150., -100. }; // Direction from light to teapot
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
glLightfv(GL_LIGHT0, GL_POSITION, lighpos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, ligdir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 10.0);
GLfloat ambientLight0[] = { 0.25, 0.25, 0.25, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight0);
GLfloat diffuseLight0[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight0);
GLfloat specularLight0[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight0);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 128.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void drawAxis() {
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0); glVertex3f(-500., 0.0, 0.0); glVertex3f(500., 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, -500., 0.0); glVertex3f(0.0, 500., 0.0);
glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.0, -500.); glVertex3f(0.0, 0.0, 500.);
glEnd();
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
drawAxis();
glPushMatrix();
glPointSize(10);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POINTS);
glVertex3d(lighpos[0], lighpos[1], lighpos[2]);
glEnd();
glPopMatrix();
glColor3f(1., 0., 0.);
glPushMatrix();
glTranslated(possph[0], possph[1], possph[2]);
glutSolidTeapot(100.);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 4, 3000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1500.0, 1500.0, 1500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(0.0, 0.0);
glutInitWindowSize(800, 800);
glutCreateWindow("spotlight");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Fixed function pipeline illumination, which is what you are using in your code, performs lighting calculations only at the vertices. If your spotlight illuminates only a few or a single vertex you'll not get a pleasing spotlight effect. One possible solution would be to highly refine your models' meshes. The better, much more efficient and elegant solution is to drop using the fixed function pipeline and implement a illumination fragment shader, so that lighting is calculated for each pixel.

OpenGL Picking selects on wrong places

I'm trying to recognize a drawn object on a mousPressEvent in OpenGL in Qt with picking.
I did some research but wasn't able to find the problem.
Clearly it recognizes something (because the return value of glRenderMode(GL_RENDER) is often an integer > 0), but not necessarily when I click on an object.
I think gluPerspective is the problem right here, but i just don't know how to resolve it.
mousePressEvent:
void WorldView::mousePressEvent(QMouseEvent *e)
{
GLuint buff[256];
GLint hits;
GLint view[4];
//Buffer to store selection data
glSelectBuffer(256, buff);
//Viewport information
glGetIntegerv(GL_VIEWPORT, view);
//Switch to select mode
glRenderMode(GL_SELECT);
//Clear the name stack!
glInitNames();
//Restric viewing volume
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//Restrict draw area
gluPickMatrix(e->x(), e->y(), 1.0, 1.0, view);
gluPerspective(40.0f, (GLfloat)view[2]/(GLfloat)view[3], 1.0, 100.0);
//Draw the objects onto the screen
glMatrixMode(GL_MODELVIEW);
//Draw only the names in the stack
paintGL();
//Back into projection mode to push the matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
hits = glRenderMode(GL_RENDER);//number of recognized objects
printf("\n%d\n",hits);
//Back to modelview mode
glMatrixMode(GL_MODELVIEW);
}
Draw function:
void WorldView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
//Draw objects we want to pick
glPushName(0);
glBegin(GL_TRIANGLES);
glVertex3d(1,1,1);
glVertex3d(2,3,2);
glVertex3d(5,2,2);
glEnd();
glPopName();
glPushName(1);
glBegin(GL_TRIANGLES);
glVertex3d(7,-5,1);
glVertex3d(10,3,2);
glVertex3d(10,2,2);
glEnd();
glPopName();
glPushName(2);
glBegin(GL_TRIANGLES);
glVertex3d(1,-5,7);
glVertex3d(2,3,9);
glVertex3d(5,2,9);
glEnd();
glPopName();
}
EDIT1: Maybe completing the code could help?
Initializer:
void WorldView::initializeGL ()
{
this->dayOfYear = 0;
this->hourOfDay = 0;
// Initialize QGLWidget (parent)
QGLWidget::initializeGL();
glShadeModel(GL_SMOOTH);
// Black canvas
glClearColor(0.0f,0.0f,0.0f,0.0f);
// Place light
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable(GL_DEPTH_TEST);
GLfloat light0_position [] = {0.1f, 0.1f, 0.1f, 0.1f};
GLfloat light_diffuse []={ 1.0, 1.0, 1.0, 1.0 };
glLightfv ( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
}
resizer:
void WorldView::resizeGL ( int width, int height )
{
if ((width<=0) || (height<=0))
return;
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
//change the next line order to have a different perspective
GLdouble aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(40.0f, aspect_ratio, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Use bullet raycast and not gl_Select which is way too slow and unwieldy. This will also make you get away from calling paintGL manually and other glCalls...in qt mousepressevent. Dont do this!