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
Related
I have a code:
#include <gl/glut.h>
#include <stdio.h>
#define WinW 1000
#define WinH 500
/* ----------------------------------------------------------------------- */
bool mousedown = false;
void myInit(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glPointSize(5.0);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, WinW, WinH, 0.0, -1.0, 1.0);
}
void myDisplay(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
glColor3f(1.0, 0.0, 0.0);
glVertex2i(50, 50);
glEnd();
//glFlush();
glutSwapBuffers();
}
void myMouse(int button, int state, int x, int y){
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
mousedown = true;
}
else
mousedown = false;
}
void myMovedMouse(int mouseX, int mouseY){
if (mousedown){
//printf("%d %d\n", mouseX, mouseY);
glBegin(GL_POINTS);
glColor3f(0.0, 1.0, 0.0);
glVertex2i(mouseX, mouseY);
glEnd();
//glFlush();
glutSwapBuffers();
}
}
/* ----------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(WinW, WinH);
glutInitWindowPosition(100, 150);
glutCreateWindow("Computer Graphic");
myInit();
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouse);
glutMotionFunc(myMovedMouse);
glutMainLoop();
}
I want to draw free shape by mouse dragging.
I have try with glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)and glFlush(), it work for me.
But when I use GLUT_DOUBLE and glutSwapBuffers() in myMovedMouse(), the screen is blinking (black-white-black-white...)
I am new in OpenGL, anyone have solution for this.
Thanks for help!
When using double buffering, you have to draw all your points on each redraw. So you have to maintain a list of all the points. The steps are then:
On startup, create an empty point list. If you want nice code, define a class/struct that contains two values for the x and y position, and use a C++ container like std::vector for your list of points.
When you get a new point from mouse input, add that point to the point list, and call glutPostRedisplay().
In the myDisplay() function, draw all the points in the list.
Having to maintain a list of points may seem to add complexity compared to using single buffering. But as soon as you go a little farther, you will probably need it anyway. For example, if the user resizes the window, you will have to be able to redraw all the points anyway. So drawing the points one by one in single buffering mode will not get you very far.
I have my program configured to close when I press the 'q' key. It was simple enough to orchestrate after reading the glutKeyboard prototype, so I thought I would also add the option to close with the right mouse button. However, no matter what I do, I can't get this to work. I'm curious if there is some subtle difference between mouseFunc and keyboardFunc that I'm missing? Here is my code:
#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
#include <GL/gl.h>
//#include <assert.h>
void init (void)
{
glClearColor (1.0, 1.0, 0.0, 0.0); /* Set background to yellow */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glVertex2d (0.0, 0.0);
glVertex2d (1.0, 0.0);
glVertex2d (0.5, 0.866);
glEnd();
glFlush (); //Display immediately
}
void keyEscape( unsigned char key, int x, int y )
{
switch ( key )
{
case 113: // 'Q' key for escape
int windowID = glutCreateWindow ("triangle");
glutDestroyWindow (windowID);
exit (0);
break;
}
glutPostRedisplay();
}
void mouseEscape( int button, int state, int x, int y )
{
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
int windowID = glutCreateWindow ("triangle");
glutDestroyWindow (windowID);
exit (0);
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition ((glutGet(GLUT_SCREEN_WIDTH)-250)/2, (glutGet(GLUT_SCREEN_HEIGHT)-250)/2);
glutCreateWindow ("triangle");
init ();
glutDisplayFunc(display);
glutKeyboardFunc(keyEscape);
glutMouseFunc(mouseEscape);
glutMainLoop();
return 0;
}
I parsed out a few more keyboard shortcuts (such as z for zooming) that all work similarly, hence my use of a switch statement as opposed to an if, but that is the only real difference I can see, and attempting to use a switch case has not worked for me either. I've also tried moving the redisplay command outside the if, to no avail. Any idea why mouse closing won't cooperate, but key closing will?
Turns out I was somehow building against an old .exe that wouldn't updated even with a 'Clean Project' operation. I changed projects and now all is fine... Thanks for the assistance all the same!
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).
I am developing a game in OpenGL/GLUT and I need to open a new window to show the score when the game is won.
In order to do this, i will call glutCreateWindow() and register the callbacks after calling mainEventLoop().
Is there a problem with this ? How should I do it properly ?
Is there a problem with this?
Yes.
Why don't you simply draw the results in the same window as the game?
Why are you using GLUT in the first place? It's not a very good framework for games. Better use GLFW or SDL.
How should I do it properly ?
By adding a small GUI system to your engine, that allows you to overlay the screen with stats (like a HUD) and a score screen.
You will need two display callback functions, display( ) and display2( ) for each window plus window = glutCreateWindow("Window 1"); and window2 = glutCreateWindow("Window 2");.
Code example :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glut.h>
int window2 = 0, window = 0, width = 400, height = 400;
void display(void)
{
glClearColor(0.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
printf("display1\n");
glFlush();
}
void display2(void)
{
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
printf("display2\n");
glFlush();
}
void reshape (int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
// Initialization stuff
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(width, height);
// Create window main
window = glutCreateWindow("Window 1");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutInitWindowPosition(100,100);
// Create second window
window2 = glutCreateWindow("Window 2");
glutDisplayFunc(display2);
glutReshapeFunc(reshape);
// Enter Glut Main Loop and wait for events
glutMainLoop();
return 0;
}
I'm trying to simulate a particle system using OpenGl but I can't get it to work, this is what I have so far:
#include <GL/glut.h>
int main (int argc, char **argv){
// data allocation, various non opengl stuff
............
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInitWindowPosition(100,100);
glutInitWindowSize(size, size);
glPointSize (4);
glutCreateWindow("test gl");
............
// initial state, not opengl
............
glViewport(0,0,size,size);
glutDisplayFunc(display);
glutIdleFunc(compute);
glutMainLoop();
}
void compute (void) {
// change state not opengl
glutPostRedisplay();
}
void display (void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
for(i = 0; i<nparticles; i++) {
// two types of particles
if (TYPE(particle[i]) == 1) glColor3f(1,0,0);
else glColor3f(0,0,1);
glVertex2f(X(particle[i]),Y(particle[i]));
}
glEnd();
glFlush();
glutSwapBuffers();
}
I get a black window after a couple of seconds (the window has just the title bar before that). Where do I go wrong?
LE: the x and y coordinates of each particle are within the interval (0,size)
Try to make these changes in your code:
move the Main function at the end of the file
glPoinSize call belongs to the Display function
then you should provide a function to handle resizing of the window glutReshapeFunc(reshape), something like this
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
glFlush is called from glutSwapBuffers function so you don't need it there
insert this code (after glutCreateWindow call) to set the initial position for the projection
glClearColor(0.2, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 10, 0.0, 10, -1.0, 1.0);