can someone please explain me why is the camera in my code moving on every onIdle callback? I am not changing any parameters so it seems to me that it should display the same all the time. Still cannot figure it out by myself, thanks for help
#include <iostream>
#include <math.h>
#include "gl/glut.h"
#include <windows.h>
using namespace std;
void Display(void){
glMatrixMode(GL_PROJECTION);
glFrustum(-0.5, 0.5, -0.5, 0.5, 0.8, 2);
gluLookAt (0,0,1, 0,0,0, 0,1,1);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glutWireCube(0.2);
glFlush();
}
void onIdle(void){
Sleep(1000);
glutPostRedisplay();
}
int main(void){
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA);
glEnable(GL_DEPTH_TEST);
glutCreateWindow("camera");
glutDisplayFunc(Display);
glutIdleFunc(onIdle);
glutMainLoop();
return 0;
}
That is because you don't reset the matrices, after each render or at the beginning of each render.
Basically, you need to call glLoadIdentity(); that will reset the current selected matrix, but setting the matrix's values to the default values (Matrix Identity).
Related
I am using SDL2.00 with OpenGL to create a program. The program isn't supposed to do anything at the moment it's just a test bed. However I ran into a problem. When I create a window using SDL_CreateWindow, the window goes into a busy state and stops responding. The program flow isn't really affected by this however the window itself just won't work. All it does is show a white blank window and accept no input, can't resize can't move and can't quit. I will attach the code but I doubt it is code related since I already made a few programs using SDL and they seem to work just fine.
Using VS2013 SDL2.00 OpenGL
=========main========
#include "stdafx.h"
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 640.0 / 480.0, 1.0, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 2.0, -5.0);
glVertex3f(-2.0, -2.0, -5.0);
glVertex3f(2.0, -2.0, -5.0);
glEnd();
}
int main(int argc, char* argv[]){
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window;
window = SDL_CreateWindow("OpenGLTest", 300, 300, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
init();
while (true){
display();
SDL_GL_SwapWindow(window);
}
return 0;
}
=========stdafx======
#pragma once
#include <iostream>
#include <SDL.h>
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#define PI 3.14159265
using namespace std;
You forgot to process all the events, so the SDL window is just waiting and waiting and waiting, thereby "not responding" - Simply adding that should fix the problem!
while (true) {
SDL_PumpEvents();
display();
SDL_GL_SwapWindow(window);
}
You could also pull all the events manually with a loop calling SDL_PollEvent(SDL_Event *event)
SDL_Event event;
while (SDL_PollEvent(&event)) {
// Process the event...
}
Wiki
SDL_PumpEvents() - http://wiki.libsdl.org/SDL_PumpEvents
SDL_PollEvent() - http://wiki.libsdl.org/SDL_PollEvent
here is my code.
#include "stdafx.h"
#include <GL/glut.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <math.h>
#define pi 3.14;
float x=.05; //translation parameter
float angle=3;
void reshape(int w, int h)
{
if(h==0) h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,w,0,h,-1,1);
}
void display(void)
{
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(x,0.0f,0.0f);
glBegin(GL_POLYGON);
glVertex2f(10,10);
glVertex2f(30,20);
glVertex2f(30,30);
glVertex2f(10,30);
glEnd();
x=x+.0000005;
if(x>600)
x=0;
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc , argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(640,480);
glutCreateWindow("my window");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutMainLoop();
return(0);
}
the problem with this code is, the rectangle is translated to infinity. I want it translated to maximum window size and again return to starting of window.In this code I am checking x>600 (assumes 600 as maximum) ,if so x is changed to 0. But it wont working.
You need to call glPushMatrix before glTranslatef and glPopMatrix after glEnd.
glTranslatef doesn't set the transformation, it appends it to the existing transformation. What you need to do is push the existing matrix on the matrix stack, apply the transformation, then restore the original. That way the translations don't accumulate.
You are not resetting the ModelView matrix. The GL transformation functions multiply the current modelview matrix by the transformation matrix, so that the transformations accumulate. Every time your display function is called, you move the rectanlge by the amout of x - relative to where it was lats frame -. Thus, your logic of changing x is actually only modulating the speed with wich the object moves.
Put a glLoadIdentiy() at the start of display(). It will reset the matrix to identity, undoing all former transformations.
I am starting with openGL and c++, and I was wondering why I don't see anything on the window. Here is my code:
#include <GLUT/GLUT.h>
#include <stdlib.h>
void init() {
glClearColor(0, 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -10);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3i(-0.5, -0.5, 0);
glVertex3i(0, 0.5, 0);
glVertex3i(0.5, -0.5, 0);
glEnd();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA);
glutInitWindowPosition(200, 200);
glutInitWindowSize(400, 400);
glutCreateWindow("Window");
init();
glutDisplayFunc(display);
glutMainLoop();
}
I have a few questions:
If I run the program like this all I see is a white window... Didn't I set the color to blue?
When I do glutSwapBuffers() at the end of display function and run the program, I see the blue window without the triangle. So, I thought glutSwapBuffers() function only worked with double buffering.
And the most important, where the hell is my triangle? O.o Didn't I translate the camera with glTranslatf() function to -10 in the z-axes? If you are wondering why I used gluPerspective, I have to say that I am trying out new things, but neither works if I use gluOrtho2D().
I don't know if I am missing something or what. Maybe I need to search more information about this, but I think most of the code is correct.
1 & 2) Well you don't have to call glutSwapBuffers() when using single buffer. But you have to call glFlush(), so the draw commands are executed on the GPU.
3) I noticed that you are creating vertices with double coordinates, but you are calling integer version of glVertex** function (decimal part will be truncated) - it means that you will be drawing triangle with zero size.
Use glVertex3d() or glVertex3f() instead of glVertex3i().
Small note: intermediate mode is deprecated in the latest OpenGL.
I have written a simple OpenGL program in C++ that displays a line joining the center of the window to the current position of the mouse pointer.
My code is :
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<iostream>
using namespace std;
void passive(int,int);
void reshape(int,int);
void init(void);
void display(void);
void camera(void);
int x=3,y=3;
int main (int argc,char **argv) {
glutInit (&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(1364,689);
glutInitWindowPosition(0,0);
glutCreateWindow("Sample");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutPassiveMotionFunc(passive);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(x,y,0);
glEnd();
glutSwapBuffers();
}
void camera(void) {
glRotatef(0.0,1.0,0.0,0.0);
glRotatef(0.0,0.0,1.0,0.0);
glTranslated(0,0,-20);
}
void init(void) {
glEnable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_COLOR_MATERIAL);
}
void reshape(int w, int h) {
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
}
void passive(int x1,int y1) {
x=x1; y=y1;
}
The problem I am facing is that the x and y values set in the passive() function is not correctly mapped into the screen which uses perspective projection. So the line drawn is joining the center to some other coordinate outside the screen. Any modifications to the code to get it working properly?
An easy way would be to create an orthographic projection matrix and then render all of your "2D" elements (including this line, using the screen coordinates provided by glutPassiveMotionFunc).
Something like this:
void display() {
// clear
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( ... ) // create 3D perspective projection matrix
glMatrixMode(GL_MODELVIEW);
// Render 3D content here
// Render 2D content
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0); // create 2D orthographic projection matrix with coordinate system roughly equivalent to window position
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
glVertex2f( width / 2, height / 2 ); // now we can use "pixel coordinates"
glVertex2f( cursorX, cursorY );
glEnd();
...
}
Compare this to your modification of the perspective projection in your reshape method.
Obviously you'll also want to disable states that don't make sense for a "2D" rendering (like depth buffer checking, etc) but it should be pretty obvious. Take a look at this GDSE post for a discussion of how other people do this same task.
I'm trying to display a text-overlay (basically a help screen which shows my keyboard shortcuts) on top of a 3D Texture I'm rendering. The texture works great and I've got some east-to-use rotations and translations for the user.
My thought was to use
const unsigned char tmp[100] = "text to render";
glRasterPos2i(x, y);
glColor4b(255, 255, 255, 255);
glutBitmapString(GLUT_BITMAP_HELVETICA_18, tmp);
As recommended in How do I use glutBitmapString() in C++ to draw text to the screen? .
This works great except that the text now rotates with the object instead of remaining in a static location on the screen. I read some documentation and found that the glRasterPos functions are manipulated when you manipulate the model view matrix:
The object coordinates presented by glRasterPos are treated just like those of a glVertex command: They are transformed by the current modelview and projection matrices and passed to the clipping stage.
-Source
I then found via another post that you could push and pop the current matrix with glPushMatrix and glPopMatrix.
-Source
When I do this, the text disappears all together. At first I thought I might have had the coordinates wrong for the text, but I tried x=y=0 through x=y=25 in intervals of .01 and never saw the text. It's still possible I'm misunderstanding where this should be drawn, but I'm not sure what to try next.
My drawing function is calling something akin to:
glLoadIdentity();
glPushMatrix();
glTranslatef(0,0,-sdepth);
glRotatef(-stheta, 1.0, 0.0, 0.0);
glRotatef(sphi, 0.0, 0.0, 1.0);
glRotatef(rotateX,0,1,1);
glRotatef(rotateY,1,0,0);
glTranslatef(-0.5,-0.5,-0.5);
glPopMatrix();
glRasterPos2i(2, 2);
glColor4b(255, 255, 255, 255);
glutBitmapString(GLUT_BITMAP_HELVETICA_18, tmp);
Anyone have any recommendations for debug/troubleshooting steps to try to get this text to display in a single, static location on the screen?
Well, if glRasterPos is treated the same way as glVertex, then you need to set up proper projection (GL_PROJECTION) matrix (using gluOrtho2D) before calling glRasterPos.
Give this a shot:
#include <GL/glut.h>
#include <string>
using namespace std;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3ub(255,0,0);
glPushMatrix();
glScalef(5,5,5);
glBegin(GL_QUADS);
glVertex2f(-1,-1);
glVertex2f(1,-1);
glVertex2f(1,1);
glVertex2f(-1,1);
glEnd();
glPopMatrix();
glColor3ub(0,255,0); // A
glRasterPos2i(0,0); // B
string tmp( "wha-hey!" );
for( size_t i = 0; i < tmp.size(); ++i )
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, tmp[i]);
}
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double aspect_ratio = (double)w / (double)h;
glOrtho(-10*aspect_ratio, 10*aspect_ratio, -10, 10, -1, 1);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800,600);
glutCreateWindow("Text");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
Oddly enough swapping lines A and B causes the glColor3ub() call to not take effect. I think that's what you were running into with the code sequence you posted.
As an aside glColor4b() takes chars which max out at 127. You should switch to glColor4ub() if you want to persist in passing in 255.
Documented here ("The sequence of glRasterPos(), glColor(), glBitmap() doesn't result in the desired bitmap color"), but no explanation given :(
EDIT: Ah ha! The current raster position contains its own color state, which is only updated during a glRasterPos() call.