Thanks for this great reply.
I am not fixed on using the Sleep() function in any way, it was just the only thing I could come up with yet to control the frame rate. I will have a look at Vsync now, and see if I can use it to make my application work.
One additional question, though: could I not load the bitmaps in advance to the GPU. I need to loop over a sequence of let’s say 32 frames that will not change. When frame #32 is displayed, I need to display frame #1 again, and so on… I thought by loading them to texture[1], texture[2], …, texture[32] before any displaying that this could save me time and thereby benefit the “one frame every 1/60th of a second”-goal. Or is this not how it works?
Simple code for now:
#include "stdafx.h"
#include "cv.h"
#include <conio.h>
#include <highgui.h>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string>
#include <io.h>
#include <iostream>
#include <gl\gl.h> // Header File For The OpenGL64 Library
#include <gl\glu.h> // Header File For The GLu64 Library
#include <glut.h>
#include "SOIL.h"
#include <math.h>
using namespace cv;
using namespace std;
GLuint texture[1]; // Storage For One Texture ( NEW )
int k = 0;
int l = 0;
int n = 0;
const unsigned int TARGET_FPS = 60;
const double TIME_PER_FRAME = 1000.0 / TARGET_FPS;
int g_start_time;
int g_current_frame_number;
void myInit(void);
void display(void);
void myIdle();
void myIdle() // ! Will not use the sleep() function anymore in next version
{
glutPostRedisplay(); // display function is recalled on idle
double end_frame_time, end_rendering_time, waste_time;
// event handling is done elsewhere
// draw current frame
glutPostRedisplay();
// wait until it is time to draw the current frame
end_frame_time = g_start_time + (g_current_frame_number + 1) * TIME_PER_FRAME;
end_rendering_time = glutGet(GLUT_ELAPSED_TIME);
waste_time = end_frame_time - end_rendering_time;
if (waste_time > 0.0)
Sleep(waste_time ); // sleep parameter should be in seconds
// update frame number
g_current_frame_number = g_current_frame_number + 1;
}
int DetectNrImages(){
char path[100];
GetCurrentDirectory(100, path);
printf("path : %s", path);
int rows = 0;
int cols = 0;
DIR* directory = opendir(path);
dirent *entry = readdir(directory);
printf("
Detecting .png files...
");
if (directory != NULL){
Mat test = imread("img0.bmp");
cvtColor(test, test, CV_RGB2GRAY);
int rows = test.rows;
int cols = test.cols;
int npix = rows * cols;
printf("
Image size = %i x %i",cols,rows);
while(entry = readdir (directory)){
std::string fname = entry->d_name;
if (fname.find(".bmp") != string::npos) {
printf("
Filename: %s", fname);
n++;
}
}
}
else{
perror ("Couldn't open the directory");}
return n;
}
int LoadGLTextures(int n)// Load images And Convert To Textures
{
for(int j = 0; j<n;j++){
char integer_string[32];
char *fname1 = "img";
sprintf(integer_string, "%d", j);
char *fname3 = ".bmp";
char result[100]; // array to hold the result.
strcpy(result,fname1); // copy string one into the result.
strcat(result,integer_string); // append string two to the result.
strcat(result,fname3); // append string three to the result.
/* load an image file directly as a new OpenGL texture */
texture[j] = SOIL_load_OGL_texture
(
result,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_TEXTURE_REPEATS
);
//printf("
'''''%i",2*texture[j]);
if(texture[j] == 0){
printf("
probleem met texture nummer %i", j);
return false;}
else
printf("
%s loaded",result);
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[j]);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
//glTexImage2D(GL_TEXTURE_2D, 0, 3, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[j]);
}
return true; // Return Success
}
int InitGL(int n) // All Setup For OpenGL Goes Here
{
g_start_time = glutGet(GLUT_ELAPSED_TIME);
g_current_frame_number = 0;
if (!LoadGLTextures(n)) // Jump To Texture Loading Routine ( NEW )
{ printf("
o oh");
return FALSE; // If Texture Didn't Load Return FALSE
}
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
//glShadeModel(GL_SMOOTH); // Enable Smooth Shading
//glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
//glClearDepth(1.0f); // Depth Buffer Setup
//glEnable(GL_DEPTH_TEST); // Enables Depth Testing
//glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE; // Initialization Went OK
}
void display()
{
k++;
k = k%(n);
printf("
%i",k);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
//glLoadIdentity(); // Reset The View
//glTranslatef(0.0f,0.0f,-5.0f);
glBindTexture(GL_TEXTURE_2D, texture[k]);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glFlush();
glPopMatrix();
glutSwapBuffers();
}
void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("Texture Map Demo");
glutIdleFunc(myIdle);
int n = DetectNrImages();
glutDisplayFunc(display);
printf("
%i images found", n);
InitGL(n);
glutMainLoop();
}