i have coded what i have read in previous post about a well known subject but i continue to get a green window without any triangle inside.
Here is my paint function :
void mGLWidget::paintGL()
{
glClearColor( Qt::green );
QSize viewport_size = size();
glViewport(0, 0, viewport_size.width(), viewport_size.height());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 5, 7); // near and far match your triangle Z distance
glMatrixMode(GL_MODELVIEW);
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glColor4f( 1.0, 1.0, 1.0, 1.0 );
glTranslatef(-1.5f,0.0f,-15.0f);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd();
// Finished Drawing The Triangle
// swapBuffers();
}
I only get a green window without any triangle. My QT is qt4.8 and opengl 4.0.
What am I doing wrong ?-\
your near and far value for your glfrustrum is quite a small range, make it 1, 100 instead of 5, 7. might not be the actual solution but it will help if its not
Your near and far value is small and you are translating the triangle very far by -15f unit that means your triangle is not draw or act as a point. So you only see the window color.
Related
I need to create a 3d cube, and so far I've created all the vertices but when I run the program I can only see the cube (or what I hope is a cube, I can't tell) from one face, so it looks like a square. I want to know how to view my cube from above, so I can check whether or not it actually looks the way I want it to.
I created the 24 vertices using glVertex3f but like I said I can't tell if it is a cube or not because I cannot look at it from an angle other than the default.
I tried downloading GLM but I am very confused on how, if at all, to use that to change the viewing perspective.
glEnable(GL_DEPTH_TEST);
// Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
// Render here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
... // Repeating drawing the vertices for each vertex of the cube
glEnd();
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
No error messages but I cant tell if its a cube or not.
// Render here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// need the window width & height to compute aspect ratio
int width, height;
glfwGetWindowSize(window, &width, &height);
// set up the camera projection (if you haven't done this in init)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, float(width) / height, 0.1f, 100.0f);
// set camera position & orientation
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1, 1, -3, //< eye position
0, 0, 0, //< aim position
0, 1, 0); //< up direction
// now draw stuff
glBegin(GL_QUADS);
glEnd();
I was wondering if anyone could help me figure out how to add a light source to my 3D objects. I have four objects that are rotating and I want the light source to be at a fixed position, and I want to be able to see lighting on the object.
I tried doing this (********):
//*******Initializing the light position
GLfloat pos[] = {-2,4,5,1};
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
//*******adding the light to the display method
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, pos);
// rectangle
glPushMatrix();
glTranslatef(0.0f, 2.5f, -8.0f);
glRotatef(angleRectangle, 0.0f, 1.0f, 0.0f);
drawRectangle();
glPopMatrix();
//small cylinder
glPushMatrix();
glTranslatef(0.0f, 2.0f, -8.0f);
glRotatef(90, 1, 0, 0);
glRotatef(anglePyramid, 0.0f, 0.0f, 1.0f);
drawCylinder(0.2, 0.7);
glPopMatrix();
//big cylinder
glPushMatrix();
glTranslatef(0.0f, 1.5f, -8.0f);
glRotatef(90, 1, 0, 0);
glRotatef(anglePyramid, 0.0f, 0.0f, 1.0f);
drawCylinder(0.7, 2.7);
glPopMatrix();
//pyramid
glPushMatrix();
glTranslatef(0.0f, -2.2f, -8.0f);
glRotatef(180, 1, 0, 0);
glRotatef(anglePyramid, 0.0f, 1.0f, 0.0f);
drawPyramid();
glPopMatrix();
glutSwapBuffers();
anglePyramid += k * 0.2f; //- is CW, + is CCW
angleRectangle += -k * 0.2f;
}
//******* Then i added these to the main method
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
However when I do this and I run the entire program, my objects turn gray, and at certain points in the rotation they turn white. And this isnt what I want. I want to keep my colorful objects, but I want to be able to see the light source on them.
Any help would be greatly appreciated. Also let me know if you need to see more of my code to figure out the issue. Thanks
When lighting (GL_LIGHTING) is enabled, then the color is taken from the material parameters (glMaterial).
If you still want to use the current color, the you have to enable GL_COLOR_MATERIAL
and to set the color material paramters (glColorMaterial):
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
See also Basic OpenGL Lighting.
But note, that drawing by glBegin/glEnd sequences, the fixed function pipeline matrix stack and fixed function pipeline per vertex light model, is deprecated since decades.
Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.
I want to use OpenGL to draw on top of a webcam stream. I'm using an SDL_Surface named screen_surface_ containing webcam data, that I'm rendering to the screen using (1):
SDL_UpdateTexture(screen_texture_, NULL, screen_surface_->pixels, screen_surface_->pitch);
SDL_RenderClear(renderer_);
SDL_RenderCopy(renderer_, screen_texture_, NULL, NULL);
Then I try to draw some geometry on top:
glLoadIdentity();
glColor3f(1.0, 0.0, 1.0);
glBegin( GL_QUADS );
glVertex3f( 10.0f, 50.0f, 0.0f ); /* Top Left */
glVertex3f( 50.0f, 50.0f, 0.0f ); /* Top Right */
glVertex3f( 50.0f, 10.0f, 0.0f ); /* Bottom Right */
glVertex3f( 10.0f, 10.0f, 0.0f ); /* Bottom Left */
glEnd( );
glColor3f(1.0, 1.0, 1.0); //<- I need this to make sure the webcam stream isn't pink?
SDL_RenderPresent(renderer_);
I have initialized OpenGL using (excerpt):
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glViewport( 0, 0, res_width_, res_height_ );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(0.0f, res_width_, res_height_, 0.0f, -1.0f, 1.0f);
Subquestion: If I don't reset the glColor to white the whole webcam stream is colored pink. I find this odd, because I thought that SDl_RenderCopy had already rendered that texture before the first call to glColor. So how does SDL_RenderCopy actually work?
Main question: I get a neat 40x40 square in the top left of the screen on top of my webcam feed (good!). However, in stead of pink, it is a kind of flickering dark purple color; seemingly dependent on the camera feed in the background. Could you please tell me what I'm overlooking?
Edit:
As per #rodrigo's comment, these are some images with the color set to R, G, B and white, respectively:
Red Square
Green Square
Blue Square
White Square
Looking at these, it seems that the underlying texture has some effect on the color. Could it be that OpenGL is still applying (some part of) the texture to the quad?
Edit:
I suspect now that the geometry is drawn using the render texture as a texture, even though I've called glDisable(GL_TEXTURE_2D). Looking at the "White Square" screenshot (below), you can see that the white quad is the same color as the bottom-right pixel. I guess that the quad has no texture coordinates, so only the bottom-right texel is used. Knowing this, better question: how do I disable texturing?.
I have fixed the problem by simply adding
glcontext_ = SDL_GL_CreateContext(window_);
to the SDL_Init code. I think all my calls to openGL functions (like glDisable(GL_TEXTURE_2D) were applied to the wrong context. Explicitly creating a context from SDL sets the right context to be active, I'm guessing.
Something else to look out for: when using textured geometry after using SDL_RenderCopy; I had to make sure to reset
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
before calling glTexImage2d, because it uses
GL_UNPACK_ROW_LENGTH if it is greater than 0, the width argument to the pixel routine otherwise
(from the OpenGL docs)
Below is a piece of code I use to achieve a demo about how blending works:
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glBegin(GL_QUADS);
glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
glVertex3i(2, 0, 0);
glVertex3i(2, 6, 0);
glVertex3i(6, 6, 0);
glVertex3i(6, 0, 0);
glEnd();
glEnable(GL_BLEND);
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
glBegin(GL_QUADS);
glColor4f(0.0, 1.0, 0.0, 0.5f);
glVertex3i(3, 2, -1);
glVertex3i(3, 8, -1);
glVertex3i(8, 8, -1);
glVertex3i(8, 2, -1);
glEnd();
The problem is: It shows what I want on my laptop, which means that the intersection of the two quads is blended, and the area of the green quad left out on black background also blended with background whose alpha is 0.0. However, on another PC, only the red quad appears...
The OpenGL on the laptop is 2.0, and the one on the PC is over 4.0. I want to know whether the problem is the edition of OpenGL or not.
BTW: I know the order I should follow when I want to draw a translucent and an opaque object; I only use this demo to show how much trouble there will be if we do not follow it...
I got a problem with drawing on a QGLWidget. I have several quads on the widget which I can move around when pressing some keys. As long as I just draw quads, everything works fine but now I want to add some lines using:
glBegin(GL_LINE);
glColor3f(c[0], c[1], c[2]);
glVertex3f(v1.x, v1.y, v1.z);
glVertex3f(v2.x, v2.y, v2.z);
glEnd;
The drawing also works fine, but the clearing of the glwidget doesn't work anymore. Means that I see everything I ever drawed on it. Just to mention.
I tried the same with GLUT using the same initializations and it worked, but since I have switched to Qt it doesn't work anymore.
paintGL(), resizeGL() and initializeGL() are below.
void GLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, -10.0f, -20.0f, 0.0f, 20.0f, -10.0f);
glTranslatef(0.0f, -30.0f, -40.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glRotatef(s_deg, 0.0f, 0.0f, 1.0f);
glRotatef(s_deg2, cos(DEGRAD(s_deg)), sin(DEGRAD(s_deg)), 0.0f);
float colors[8][3] = {
0.5, 0.0, 0.0,
0.0, 0.5, 0.0,
0.0, 0.0, 0.5,
1.0, 0.5, 0.5,
0.5, 1.0, 0.5,
0.5, 0.5, 1.0,
0.9, 0.9, 0.9,
0.1, 0.1, 0.1,
}; //red, green, blue, red shiny, green shiny, blue shine, light grey, dark grey
for(int i=0;i<glBoxes.size();i++) {
glBoxes.at(i).setColor(colors[i]);
glBoxes.at(i).drawCuboid();
glBoxes.at(i).drawCuboidGrid();
}
}
void GLWidget::initializeGL() {
glDepthFunc(GL_LESS);
glClearColor(0.2, 0.2, 0.2, 0.2);
glClearDepth(1.0);
}
void GLWidget::resizeGL(int width, int height) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0.0f, 0.0f, (float)width, (float)height);
glLoadIdentity();
gluPerspective(45.0f, (float)width/(float)height, 0.5f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
any Ideas?
The tokens accepted by glBegin are
GL_POINTS
GL_LINES
GL_TRIANGLES
GL_TRIANGLE_FAN
GL_TRIANGLE_STRIP
GL_QUADS
GL_QUAD_STRIP
and
GL_POLYGON
The token used by you, GL_LINE (not the missing trailing S) is not valid for glBegin.
The statement glEnd; will evaluate the address of the function glEnd and silently discard the result. Could it be, that you have a Pascal or Delphi background? In C like languages you have to add a matched pair of parentheses to make it a function call. Functions that don't take a parameter are called with an empty pair of parentheses. E.g. in your case glEnd();.
Not related to your problem. All of the code in resizeGL should go to the head of paintGL (use the widget's width() and height() getters). Also what you have in initializeGL belongs to paintGL.
The proper use of initializeGL is to do one-time initialization, like loading textures, and shaders, preparing FBOs and such.
resizeGL is meant to re-/initialize stuff that depends on the window's size and which is quite time consuming to change, like renderbuffers and/or textures used as attachment in FBOs used for window sized post-processing or similar. Setting the projection matrix does not belong there, and neither does the viewport. Those go into paintGL.
glDepthFunc, glClearColor and glClearDepth directly influence the drawing process and as such belong with the drawing code.
Also you should not use the immediate mode (glBegin … glEnd) at all. It's been outdated ever since OpenGL-1.1 was released over 15 years ago. Use Vertex Arrays, with the possible addition of Buffer Objects.
glEnd; should be glEnd();. This may actually fix your problem.
GL_LINE isn't a valid token for glBegin. To draw lines, you need GL_LINES (that's subtle, and you're in good company - this is a common mistake).
GL_LINE is used to control how polygons are rendered, which is controlled by the glPolygonMode function.
It must be GL_LINES instead of GL_LINE. The symbols accepted by glBegin are plural (i.e. GL_QUADS, GL_LINE_STRIPS...).