I'm currently learning OpenGL and from what I understood, I have to call
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
before drawing lines. Then, to draw shapes I need to call
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
to draw shapes such as GL_TRIANGLES and GL_QUADS.
I wrote this code with the goal of drawing a single line at top and 3 shapes, but only the line was drawn.
Here is my code.
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glBegin(GL_LINES);
glColor3f(100,200,100);
glLineWidth(10.0f);
glVertex2f(-1.0f,0.8f);
glVertex2f(1.0f,0.8f);
glEnd();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS); //Begin quadrilateral coordinates
//Trapezoid
glVertex3f(-0.7f, -1.5f, -5.0f);
glVertex3f(0.7f, -1.5f, -5.0f);
glVertex3f(0.4f, -0.5f, -5.0f);
glVertex3f(-0.4f, -0.5f, -5.0f);
glEnd(); //End quadrilateral coordinates
glBegin(GL_TRIANGLES); //Begin triangle coordinates
//Pentagon
glVertex3f(0.5f, 0.5f, -5.0f);
glVertex3f(1.5f, 0.5f, -5.0f);
glVertex3f(0.5f, 1.0f, -5.0f);
glVertex3f(0.5f, 1.0f, -5.0f);
glVertex3f(1.5f, 0.5f, -5.0f);
glVertex3f(1.5f, 1.0f, -5.0f);
glVertex3f(0.5f, 1.0f, -5.0f);
glVertex3f(1.5f, 1.0f, -5.0f);
glVertex3f(1.0f, 1.5f, -5.0f);
//Triangle
glVertex3f(-0.5f, 0.5f, -5.0f);
glVertex3f(-1.0f, 1.5f, -5.0f);
glVertex3f(-1.5f, 0.5f, -5.0f);
glEnd(); //End triangle coordinates
glutSwapBuffers(); //Send the 3D scene to the screen
}
Could someone please explain to me how to switch between GL_PROJECTION and GL_MODELVIEW and how do they work?
The Z-value of your polygons is -5.0 which is outside the default [-1, 1] range for the device coordinates, so they get discarded.
Replace all glVertex3f(x, y, z) calls with glVertex2f(x,y).
Related
I read similar suggested questions and their solutions, but could not find an answer.
I'm trying to draw a scene with an isometric view in OpenGL.
Draw func:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
glPopMatrix();
In the end, I get this result. The camera does have an isometric projection, but for some reason polygons are clipped.
If I add glTranslatef(-0.8f, 0, -0.8f) before drawing the quad, the result is as follows:
The problem is that I don't apply any optimization to OpenGL render. But why do polygons have to be cut off?
The polygons are clipped by the near or far plane of the viewing volume.
When you do not set a projection matrix, then view space, clip space and normalized device space are the same. The normalized device space is a unique cube with the left, bottom, near of (-1, -1, -1) and right, top, far of (1, 1, 1). All the geometry which is not inside this cube is clipped.
Actually you draw a quad with a side length of 1. One vertex of the quad is at the origin of the view (0, 0, 0). The quad is rotated around the origin by glRotate. Since the length of the diagonal of the quad is sqrt(2.0), one vertex of the rotated quad is clipped by either the near plane or the far plane.
If you construct and rotate a quad whose center is (0, 0 ,0), it will not be clipped, because the length form the center to each vertex is sqrt(2.0)/2.0. That is less than 1 (distance to near and far plane form the center of the viewing volume)
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(-0.5f, 0.0f, -0.5f);
glVertex3f( 0.5f, 0.0f, -0.5f);
glVertex3f( 0.5f, 0.0f, 0.5f);
glVertex3f(-0.5f, 0.0f, 0.5f);
glEnd();
respectively
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
glTranslate(-0.5f, 0.0f, -0.5f);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
Alternatively you can set an Orthographic projection, which enlarges the viewing volume by glOrtho:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
I'm trying to make a scene where I am looking at the XY plane with Z coming towards and away from the camera view. I want to see objects that are further away at a different size than objects that are in front of my face so I imagine I am supposed to use gluPerspective for this. I should have some axes on my screen coming from the origin out, however, I don't see anything at all. I had it working with a bunch of translations but I want to make sure I understand how to manipulate this properly because that was all guess and check before.
void resizeWindow(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (GLfloat)newWidth / (GLfloat)newHeight, 0.1f, 100.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
glPushMatrix();
glColor4ub(0, 120, 20, 255);
glBegin(GL_LINE_STRIP);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(3.0f, 0.0f, 0.0f);
glVertex3f(2.85f, 0.10f, 0.0f);
glVertex3f(2.85f, -0.10f, 0.0f);
glVertex3f(3.0f, 0.0f, 0.0f);
glVertex3f(2.85f, 0.0f, 0.10f);
glVertex3f(2.85f, 0.0f, -0.10f);
glVertex3f(3.0f, 0.0f, 0.0f);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 3.0f, 0.0f);
glVertex3f(0.0f, 2.85f, 0.10f);
glVertex3f(0.0f, 2.85f, -0.10f);
glVertex3f(0.0f, 3.0f, 0.0f);
glVertex3f(0.10f, 2.85f, 0.0f);
glVertex3f(-0.10f, 2.85f, 0.0f);
glVertex3f(0.0f, 3.0f, 0.0f);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 3.0f);
glVertex3f(0.10f, 0.0f, 2.85f);
glVertex3f(-0.10f, 0.0f, 2.85f);
glVertex3f(0.0f, 0.0f, 3.0f);
glVertex3f(0.0f, 0.10f, 2.85f);
glVertex3f(0.0f, -0.10f, 2.85f);
glVertex3f(0.0f, 0.0f, 3.0f);
glEnd();
Didn't try to run the code, but from a quick glance :
Remove the glPushMatrix(). You're not popping it anywhere ... and not modifying them either
Your "eye" coordinates (0.0, 0.0, -1.0) seem to be a bit too close to the original give your axises are 3.0 unit in length. Try (0.0, 0.0, -20.0) or so.
I'm pretty sure this is due to my lack of understanding of how the GL_MODELVIEW matrix works. Here is a screen recording of what's happening: http://youtu.be/3F7FLkVI7kA
As you can see, the bottom-most triangle is the first triangle being drawn, and moves as I expect the other 2 triangles to move. The second triangle is moved and rotated relative to the first, and the third is moved and rotated relative to that combination.
What I want is for all three triangles to be stationary in 3D space, but spinning (like the first triangle).
Source:
// Main loop
do {
// Clear Screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Update camera
glfwGetCursorPos(window, &cursorX, &cursorY);
cam.update(0.001f, (int)cursorX, (int)cursorY);
// Reset Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// move camera
glRotatef(cam.rotation.x, 1.0f, 0.0f, 0.0f);
glRotatef(cam.rotation.y, 0.0f, 1.0f, 0.0f);
// translate modelview matrix to position of the camera - everything should now draw relative to camera position
glTranslatef(-cam.position.x, cam.position.y, -cam.position.z);
// Draw ground
drawGroundGrid(-25.0f);
drawSpinningTriangle(0.0f, 0.0f, -5.0f);
drawSpinningTriangle(3.14f, 3.0f, -6.0f);
drawSpinningTriangle(-6.0f, 12.0f, -5.0f);
// Swap buffers - back buffer is now front buffer to be rendered to next frame
glfwSwapBuffers(window);
glfwPollEvents();
calcFPS();
} while (!glfwGetKey(window, GLFW_KEY_ESCAPE) && !glfwWindowShouldClose(window));// Main Loop End
[...]
void drawSpinningTriangle(float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
{
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
}
glEnd();
}
First using the matrix stack is deprecated. It's much better to manage your own matrices
Second you should pushMatrix and popMatrix before the transformations and after drawing:
void drawSpinningTriangle(float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
{
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
}
glEnd();
glPopMatrix();
}
This will save and restore the top most matrix so any changes between the 2 calls are removed.
I am Trying to Render 3 textures,
-Background
-Black/White Foreground Mask
-Foreground
I have used this OpenGL - mask with multiple textures
because it acurately descirbes my problem. But i can not get it to work. I only get the Last rendererd Texture, in this case the Foreground. I have called glutInitDisplayMode(GLUT_ALPHA); to get Alpha rendering as sugested in the Answer.
Can anyone spot errors from my side?
My code is as follows:
double stretch = ((double)m_videoResY * (double)m_depthResX) / ((double)m_videoResX * (double)m_depthResY);
glEnable(GL_BLEND);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(+0.5, -0.5, +0.5, -0.5, 0.001f, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -0.5f);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBlendFunc(GL_ONE, GL_ZERO);
glBindTexture(GL_TEXTURE_2D, m_backgroundTexture);//Draw BGTexture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glEnd();
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO);
//mask with userID
glBindTexture(GL_TEXTURE_2D, m_userIDTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glTexCoord2f(1.0f, 1.0f * stretch);
glVertex3f(-0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 1.0f * stretch);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glEnd();
//blend with Video of User
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
glBindTexture(GL_TEXTURE_2D, m_videoTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glEnd();
I suppose your mistakes are:
When you drawing your background with glBlendFunc(GL_ONE, GL_ZERO);
As result you normaly draw it in framebuffer, but providing no needed blending operation, more effective on this pass is don't use blending at all. So, more effective is glDisable(GL_BLEND), but your pass work here like you expect.
At second pass you drawing with glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO); I don't know why you using so sofisticated function here and separatively blend colors and alpha values.
So, looking on third pass, I suppose you want to modify your background alpha value by your foreground black/white color mask. If It's true, you must use glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ZERO, GL_SRC_COLOR); - Yep, little mistake.
And at third pass when you drawing foreground you have glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA), what means you wanna draw those regions, where your black/white mask was white and blending with attenuation for more darker mask regions.
If you have any questions about glBlendFunc, I can help you.
HI I am starting to learn openGl for C++.but at stating point I stucked.
I have 2 question that is the coordinates for drawing some objects? I mean where is X, Y and Z?
Second one I am making tutorial from some sites. and I am trying to animate my triangle.In tutorial it works but on my computer not.I Also downloaded source codes but It doesnt move. And there is no compiler error.
Edit:I solved problem. With restarting computer.I think it is poblem about my computer.
Here sample codes. I thougt that problem is glutTimerFunc().
#include <iostream>
#include <stdlib.h>
#ifdef __APPLE__
#include<OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <gl/glut.h>
#endif
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 30.0f;
float _cameraAngle = 0.0f;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the camera
glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units
glPushMatrix(); //Save the transformations performed thus far
glTranslatef(0.0f, -1.0f, 0.0f); //Move to the center of the trapezoid
glRotatef(_angle, 0.0f, 0.0f, 1.0f); //Rotate about the z-axis
glBegin(GL_QUADS);
//Trapezoid
glVertex3f(-0.7f, -0.5f, 0.0f);
glVertex3f(0.7f, -0.5f, 0.0f);
glVertex3f(0.4f, 0.5f, 0.0f);
glVertex3f(-0.4f, 0.5f, 0.0f);
glEnd();
glPopMatrix(); //Undo the move to the center of the trapezoid
glPushMatrix(); //Save the current state of transformations
glTranslatef(1.0f, 1.0f, 0.0f); //Move to the center of the pentagon
glRotatef(_angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
glScalef(0.7f, 0.7f, 0.7f); //Scale by 0.7 in the x, y, and z directions
glBegin(GL_TRIANGLES);
//Pentagon
glVertex3f(-0.5f, -0.5f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glEnd();
glPopMatrix(); //Undo the move to the center of the pentagon
glPushMatrix(); //Save the current state of transformations
glTranslatef(-1.0f, 1.0f, 0.0f); //Move to the center of the triangle
glRotatef(_angle, 1.0f, 2.0f, 3.0f); //Rotate about the the vector (1, 2, 3)
glBegin(GL_TRIANGLES);
//Triangle
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glEnd();
glPopMatrix(); //Undo the move to the center of the triangle
glutSwapBuffers();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 260;
}
glutPostRedisplay(); //Tell GLUT that the display has changed
//Tell GLUT to call update again in 25 milliseconds
glutTimerFunc(25, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
//Create the window
glutCreateWindow("Transformations and Timers - videotutorialsrock.com");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(24, update, 0); //Add a timer
glutMainLoop();
return 0;
}
Regarding your first question, you can use gluProject() to apply your transform matrices (via GL_MODELVIEW_MATRIX and GL_PROJECTION_MATRIX) to arbitrary vertexes.